ActivityManagerService.java revision 0d2ebc29689cc7cb8a5447c38ac01fe433ed693b
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 com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // Maximum number recent bitmaps to keep in memory.
297    static final int MAX_RECENT_BITMAPS = 3;
298
299    // Amount of time after a call to stopAppSwitches() during which we will
300    // prevent further untrusted switches from happening.
301    static final long APP_SWITCH_DELAY_TIME = 5*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real.
305    static final int PROC_START_TIMEOUT = 10*1000;
306
307    // How long we wait for a launched process to attach to the activity manager
308    // before we decide it's never going to come up for real, when the process was
309    // started with a wrapper for instrumentation (such as Valgrind) because it
310    // could take much longer than usual.
311    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
312
313    // How long to wait after going idle before forcing apps to GC.
314    static final int GC_TIMEOUT = 5*1000;
315
316    // The minimum amount of time between successive GC requests for a process.
317    static final int GC_MIN_INTERVAL = 60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process.
320    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process
323    // when the request is due to the memory state being lowered.
324    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
325
326    // The rate at which we check for apps using excessive power -- 15 mins.
327    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on wake locks to start killing things.
331    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // The minimum sample duration we will allow before deciding we have
334    // enough data on CPU usage to start killing things.
335    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336
337    // How long we allow a receiver to run before giving up on it.
338    static final int BROADCAST_FG_TIMEOUT = 10*1000;
339    static final int BROADCAST_BG_TIMEOUT = 60*1000;
340
341    // How long we wait until we timeout on key dispatching.
342    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
343
344    // How long we wait until we timeout on key dispatching during instrumentation.
345    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
346
347    // Amount of time we wait for observers to handle a user switch before
348    // giving up on them and unfreezing the screen.
349    static final int USER_SWITCH_TIMEOUT = 2*1000;
350
351    // Maximum number of users we allow to be running at a time.
352    static final int MAX_RUNNING_USERS = 3;
353
354    // How long to wait in getAssistContextExtras for the activity and foreground services
355    // to respond with the result.
356    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
357
358    // Maximum number of persisted Uri grants a package is allowed
359    static final int MAX_PERSISTED_URI_GRANTS = 128;
360
361    static final int MY_PID = Process.myPid();
362
363    static final String[] EMPTY_STRING_ARRAY = new String[0];
364
365    // How many bytes to write into the dropbox log before truncating
366    static final int DROPBOX_MAX_SIZE = 256 * 1024;
367
368    // Access modes for handleIncomingUser.
369    static final int ALLOW_NON_FULL = 0;
370    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
371    static final int ALLOW_FULL_ONLY = 2;
372
373    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
374
375    // Delay in notifying task stack change listeners (in millis)
376    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
377
378    /** All system services */
379    SystemServiceManager mSystemServiceManager;
380
381    private Installer mInstaller;
382
383    /** Run all ActivityStacks through this */
384    ActivityStackSupervisor mStackSupervisor;
385
386    /** Task stack change listeners. */
387    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
388            new RemoteCallbackList<ITaskStackListener>();
389
390    public IntentFirewall mIntentFirewall;
391
392    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
393    // default actuion automatically.  Important for devices without direct input
394    // devices.
395    private boolean mShowDialogs = true;
396
397    BroadcastQueue mFgBroadcastQueue;
398    BroadcastQueue mBgBroadcastQueue;
399    // Convenient for easy iteration over the queues. Foreground is first
400    // so that dispatch of foreground broadcasts gets precedence.
401    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
402
403    BroadcastQueue broadcastQueueForIntent(Intent intent) {
404        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
405        if (DEBUG_BACKGROUND_BROADCAST) {
406            Slog.i(TAG, "Broadcast intent " + intent + " on "
407                    + (isFg ? "foreground" : "background")
408                    + " queue");
409        }
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
414        for (BroadcastQueue queue : mBroadcastQueues) {
415            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
416            if (r != null) {
417                return r;
418            }
419        }
420        return null;
421    }
422
423    /**
424     * Activity we have told the window manager to have key focus.
425     */
426    ActivityRecord mFocusedActivity = null;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    ArrayList<TaskRecord> mRecentTasks;
432    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
433
434    /**
435     * For addAppTask: cached of the last activity component that was added.
436     */
437    ComponentName mLastAddedTaskComponent;
438
439    /**
440     * For addAppTask: cached of the last activity uid that was added.
441     */
442    int mLastAddedTaskUid;
443
444    /**
445     * For addAppTask: cached of the last ActivityInfo that was added.
446     */
447    ActivityInfo mLastAddedTaskActivity;
448
449    public class PendingAssistExtras extends Binder implements Runnable {
450        public final ActivityRecord activity;
451        public final Bundle extras;
452        public final Intent intent;
453        public final String hint;
454        public final int userHandle;
455        public boolean haveResult = false;
456        public Bundle result = null;
457        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
458                String _hint, int _userHandle) {
459            activity = _activity;
460            extras = _extras;
461            intent = _intent;
462            hint = _hint;
463            userHandle = _userHandle;
464        }
465        @Override
466        public void run() {
467            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
468            synchronized (this) {
469                haveResult = true;
470                notifyAll();
471            }
472        }
473    }
474
475    final ArrayList<PendingAssistExtras> mPendingAssistExtras
476            = new ArrayList<PendingAssistExtras>();
477
478    /**
479     * Process management.
480     */
481    final ProcessList mProcessList = new ProcessList();
482
483    /**
484     * All of the applications we currently have running organized by name.
485     * The keys are strings of the application package name (as
486     * returned by the package manager), and the keys are ApplicationRecord
487     * objects.
488     */
489    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
490
491    /**
492     * Tracking long-term execution of processes to look for abuse and other
493     * bad app behavior.
494     */
495    final ProcessStatsService mProcessStats;
496
497    /**
498     * The currently running isolated processes.
499     */
500    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
501
502    /**
503     * Counter for assigning isolated process uids, to avoid frequently reusing the
504     * same ones.
505     */
506    int mNextIsolatedProcessUid = 0;
507
508    /**
509     * The currently running heavy-weight process, if any.
510     */
511    ProcessRecord mHeavyWeightProcess = null;
512
513    /**
514     * The last time that various processes have crashed.
515     */
516    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
517
518    /**
519     * Information about a process that is currently marked as bad.
520     */
521    static final class BadProcessInfo {
522        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
523            this.time = time;
524            this.shortMsg = shortMsg;
525            this.longMsg = longMsg;
526            this.stack = stack;
527        }
528
529        final long time;
530        final String shortMsg;
531        final String longMsg;
532        final String stack;
533    }
534
535    /**
536     * Set of applications that we consider to be bad, and will reject
537     * incoming broadcasts from (which the user has no control over).
538     * Processes are added to this set when they have crashed twice within
539     * a minimum amount of time; they are removed from it when they are
540     * later restarted (hopefully due to some user action).  The value is the
541     * time it was added to the list.
542     */
543    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
544
545    /**
546     * All of the processes we currently have running organized by pid.
547     * The keys are the pid running the application.
548     *
549     * <p>NOTE: This object is protected by its own lock, NOT the global
550     * activity manager lock!
551     */
552    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
553
554    /**
555     * All of the processes that have been forced to be foreground.  The key
556     * is the pid of the caller who requested it (we hold a death
557     * link on it).
558     */
559    abstract class ForegroundToken implements IBinder.DeathRecipient {
560        int pid;
561        IBinder token;
562    }
563    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
564
565    /**
566     * List of records for processes that someone had tried to start before the
567     * system was ready.  We don't start them at that point, but ensure they
568     * are started by the time booting is complete.
569     */
570    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of persistent applications that are in the process
574     * of being started.
575     */
576    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes that are being forcibly torn down.
580     */
581    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * List of running applications, sorted by recent usage.
585     * The first entry in the list is the least recently used.
586     */
587    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Where in mLruProcesses that the processes hosting activities start.
591     */
592    int mLruProcessActivityStart = 0;
593
594    /**
595     * Where in mLruProcesses that the processes hosting services start.
596     * This is after (lower index) than mLruProcessesActivityStart.
597     */
598    int mLruProcessServiceStart = 0;
599
600    /**
601     * List of processes that should gc as soon as things are idle.
602     */
603    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
604
605    /**
606     * Processes we want to collect PSS data from.
607     */
608    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
609
610    /**
611     * Last time we requested PSS data of all processes.
612     */
613    long mLastFullPssTime = SystemClock.uptimeMillis();
614
615    /**
616     * If set, the next time we collect PSS data we should do a full collection
617     * with data from native processes and the kernel.
618     */
619    boolean mFullPssPending = false;
620
621    /**
622     * This is the process holding what we currently consider to be
623     * the "home" activity.
624     */
625    ProcessRecord mHomeProcess;
626
627    /**
628     * This is the process holding the activity the user last visited that
629     * is in a different process from the one they are currently in.
630     */
631    ProcessRecord mPreviousProcess;
632
633    /**
634     * The time at which the previous process was last visible.
635     */
636    long mPreviousProcessVisibleTime;
637
638    /**
639     * Which uses have been started, so are allowed to run code.
640     */
641    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
642
643    /**
644     * LRU list of history of current users.  Most recently current is at the end.
645     */
646    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
647
648    /**
649     * Constant array of the users that are currently started.
650     */
651    int[] mStartedUserArray = new int[] { 0 };
652
653    /**
654     * Registered observers of the user switching mechanics.
655     */
656    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
657            = new RemoteCallbackList<IUserSwitchObserver>();
658
659    /**
660     * Currently active user switch.
661     */
662    Object mCurUserSwitchCallback;
663
664    /**
665     * Packages that the user has asked to have run in screen size
666     * compatibility mode instead of filling the screen.
667     */
668    final CompatModePackages mCompatModePackages;
669
670    /**
671     * Set of IntentSenderRecord objects that are currently active.
672     */
673    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
674            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
675
676    /**
677     * Fingerprints (hashCode()) of stack traces that we've
678     * already logged DropBox entries for.  Guarded by itself.  If
679     * something (rogue user app) forces this over
680     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
681     */
682    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
683    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
684
685    /**
686     * Strict Mode background batched logging state.
687     *
688     * The string buffer is guarded by itself, and its lock is also
689     * used to determine if another batched write is already
690     * in-flight.
691     */
692    private final StringBuilder mStrictModeBuffer = new StringBuilder();
693
694    /**
695     * Keeps track of all IIntentReceivers that have been registered for
696     * broadcasts.  Hash keys are the receiver IBinder, hash value is
697     * a ReceiverList.
698     */
699    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
700            new HashMap<IBinder, ReceiverList>();
701
702    /**
703     * Resolver for broadcast intents to registered receivers.
704     * Holds BroadcastFilter (subclass of IntentFilter).
705     */
706    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
707            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
708        @Override
709        protected boolean allowFilterResult(
710                BroadcastFilter filter, List<BroadcastFilter> dest) {
711            IBinder target = filter.receiverList.receiver.asBinder();
712            for (int i=dest.size()-1; i>=0; i--) {
713                if (dest.get(i).receiverList.receiver.asBinder() == target) {
714                    return false;
715                }
716            }
717            return true;
718        }
719
720        @Override
721        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
722            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
723                    || userId == filter.owningUserId) {
724                return super.newResult(filter, match, userId);
725            }
726            return null;
727        }
728
729        @Override
730        protected BroadcastFilter[] newArray(int size) {
731            return new BroadcastFilter[size];
732        }
733
734        @Override
735        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
736            return packageName.equals(filter.packageName);
737        }
738    };
739
740    /**
741     * State of all active sticky broadcasts per user.  Keys are the action of the
742     * sticky Intent, values are an ArrayList of all broadcasted intents with
743     * that action (which should usually be one).  The SparseArray is keyed
744     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
745     * for stickies that are sent to all users.
746     */
747    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
748            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
749
750    final ActiveServices mServices;
751
752    /**
753     * Backup/restore process management
754     */
755    String mBackupAppName = null;
756    BackupRecord mBackupTarget = null;
757
758    final ProviderMap mProviderMap;
759
760    /**
761     * List of content providers who have clients waiting for them.  The
762     * application is currently being launched and the provider will be
763     * removed from this list once it is published.
764     */
765    final ArrayList<ContentProviderRecord> mLaunchingProviders
766            = new ArrayList<ContentProviderRecord>();
767
768    /**
769     * File storing persisted {@link #mGrantedUriPermissions}.
770     */
771    private final AtomicFile mGrantFile;
772
773    /** XML constants used in {@link #mGrantFile} */
774    private static final String TAG_URI_GRANTS = "uri-grants";
775    private static final String TAG_URI_GRANT = "uri-grant";
776    private static final String ATTR_USER_HANDLE = "userHandle";
777    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
778    private static final String ATTR_TARGET_USER_ID = "targetUserId";
779    private static final String ATTR_SOURCE_PKG = "sourcePkg";
780    private static final String ATTR_TARGET_PKG = "targetPkg";
781    private static final String ATTR_URI = "uri";
782    private static final String ATTR_MODE_FLAGS = "modeFlags";
783    private static final String ATTR_CREATED_TIME = "createdTime";
784    private static final String ATTR_PREFIX = "prefix";
785
786    /**
787     * Global set of specific {@link Uri} permissions that have been granted.
788     * This optimized lookup structure maps from {@link UriPermission#targetUid}
789     * to {@link UriPermission#uri} to {@link UriPermission}.
790     */
791    @GuardedBy("this")
792    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
793            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
794
795    public static class GrantUri {
796        public final int sourceUserId;
797        public final Uri uri;
798        public boolean prefix;
799
800        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
801            this.sourceUserId = sourceUserId;
802            this.uri = uri;
803            this.prefix = prefix;
804        }
805
806        @Override
807        public int hashCode() {
808            int hashCode = 1;
809            hashCode = 31 * hashCode + sourceUserId;
810            hashCode = 31 * hashCode + uri.hashCode();
811            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
812            return hashCode;
813        }
814
815        @Override
816        public boolean equals(Object o) {
817            if (o instanceof GrantUri) {
818                GrantUri other = (GrantUri) o;
819                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
820                        && prefix == other.prefix;
821            }
822            return false;
823        }
824
825        @Override
826        public String toString() {
827            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
828            if (prefix) result += " [prefix]";
829            return result;
830        }
831
832        public String toSafeString() {
833            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
834            if (prefix) result += " [prefix]";
835            return result;
836        }
837
838        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
839            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
840                    ContentProvider.getUriWithoutUserId(uri), false);
841        }
842    }
843
844    CoreSettingsObserver mCoreSettingsObserver;
845
846    /**
847     * Thread-local storage used to carry caller permissions over through
848     * indirect content-provider access.
849     */
850    private class Identity {
851        public final IBinder token;
852        public final int pid;
853        public final int uid;
854
855        Identity(IBinder _token, int _pid, int _uid) {
856            token = _token;
857            pid = _pid;
858            uid = _uid;
859        }
860    }
861
862    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
863
864    /**
865     * All information we have collected about the runtime performance of
866     * any user id that can impact battery performance.
867     */
868    final BatteryStatsService mBatteryStatsService;
869
870    /**
871     * Information about component usage
872     */
873    UsageStatsManagerInternal mUsageStatsService;
874
875    /**
876     * Information about and control over application operations
877     */
878    final AppOpsService mAppOpsService;
879
880    /**
881     * Save recent tasks information across reboots.
882     */
883    final TaskPersister mTaskPersister;
884
885    /**
886     * Current configuration information.  HistoryRecord objects are given
887     * a reference to this object to indicate which configuration they are
888     * currently running in, so this object must be kept immutable.
889     */
890    Configuration mConfiguration = new Configuration();
891
892    /**
893     * Current sequencing integer of the configuration, for skipping old
894     * configurations.
895     */
896    int mConfigurationSeq = 0;
897
898    /**
899     * Hardware-reported OpenGLES version.
900     */
901    final int GL_ES_VERSION;
902
903    /**
904     * List of initialization arguments to pass to all processes when binding applications to them.
905     * For example, references to the commonly used services.
906     */
907    HashMap<String, IBinder> mAppBindArgs;
908
909    /**
910     * Temporary to avoid allocations.  Protected by main lock.
911     */
912    final StringBuilder mStringBuilder = new StringBuilder(256);
913
914    /**
915     * Used to control how we initialize the service.
916     */
917    ComponentName mTopComponent;
918    String mTopAction = Intent.ACTION_MAIN;
919    String mTopData;
920    boolean mProcessesReady = false;
921    boolean mSystemReady = false;
922    boolean mBooting = false;
923    boolean mCallFinishBooting = false;
924    boolean mBootAnimationComplete = false;
925    boolean mWaitingUpdate = false;
926    boolean mDidUpdate = false;
927    boolean mOnBattery = false;
928    boolean mLaunchWarningShown = false;
929
930    Context mContext;
931
932    int mFactoryTest;
933
934    boolean mCheckedForSetup;
935
936    /**
937     * The time at which we will allow normal application switches again,
938     * after a call to {@link #stopAppSwitches()}.
939     */
940    long mAppSwitchesAllowedTime;
941
942    /**
943     * This is set to true after the first switch after mAppSwitchesAllowedTime
944     * is set; any switches after that will clear the time.
945     */
946    boolean mDidAppSwitch;
947
948    /**
949     * Last time (in realtime) at which we checked for power usage.
950     */
951    long mLastPowerCheckRealtime;
952
953    /**
954     * Last time (in uptime) at which we checked for power usage.
955     */
956    long mLastPowerCheckUptime;
957
958    /**
959     * Set while we are wanting to sleep, to prevent any
960     * activities from being started/resumed.
961     */
962    private boolean mSleeping = false;
963
964    /**
965     * Set while we are running a voice interaction.  This overrides
966     * sleeping while it is active.
967     */
968    private boolean mRunningVoice = false;
969
970    /**
971     * State of external calls telling us if the device is awake or asleep.
972     */
973    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
974
975    static final int LOCK_SCREEN_HIDDEN = 0;
976    static final int LOCK_SCREEN_LEAVING = 1;
977    static final int LOCK_SCREEN_SHOWN = 2;
978    /**
979     * State of external call telling us if the lock screen is shown.
980     */
981    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
982
983    /**
984     * Set if we are shutting down the system, similar to sleeping.
985     */
986    boolean mShuttingDown = false;
987
988    /**
989     * Current sequence id for oom_adj computation traversal.
990     */
991    int mAdjSeq = 0;
992
993    /**
994     * Current sequence id for process LRU updating.
995     */
996    int mLruSeq = 0;
997
998    /**
999     * Keep track of the non-cached/empty process we last found, to help
1000     * determine how to distribute cached/empty processes next time.
1001     */
1002    int mNumNonCachedProcs = 0;
1003
1004    /**
1005     * Keep track of the number of cached hidden procs, to balance oom adj
1006     * distribution between those and empty procs.
1007     */
1008    int mNumCachedHiddenProcs = 0;
1009
1010    /**
1011     * Keep track of the number of service processes we last found, to
1012     * determine on the next iteration which should be B services.
1013     */
1014    int mNumServiceProcs = 0;
1015    int mNewNumAServiceProcs = 0;
1016    int mNewNumServiceProcs = 0;
1017
1018    /**
1019     * Allow the current computed overall memory level of the system to go down?
1020     * This is set to false when we are killing processes for reasons other than
1021     * memory management, so that the now smaller process list will not be taken as
1022     * an indication that memory is tighter.
1023     */
1024    boolean mAllowLowerMemLevel = false;
1025
1026    /**
1027     * The last computed memory level, for holding when we are in a state that
1028     * processes are going away for other reasons.
1029     */
1030    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1031
1032    /**
1033     * The last total number of process we have, to determine if changes actually look
1034     * like a shrinking number of process due to lower RAM.
1035     */
1036    int mLastNumProcesses;
1037
1038    /**
1039     * The uptime of the last time we performed idle maintenance.
1040     */
1041    long mLastIdleTime = SystemClock.uptimeMillis();
1042
1043    /**
1044     * Total time spent with RAM that has been added in the past since the last idle time.
1045     */
1046    long mLowRamTimeSinceLastIdle = 0;
1047
1048    /**
1049     * If RAM is currently low, when that horrible situation started.
1050     */
1051    long mLowRamStartTime = 0;
1052
1053    /**
1054     * For reporting to battery stats the current top application.
1055     */
1056    private String mCurResumedPackage = null;
1057    private int mCurResumedUid = -1;
1058
1059    /**
1060     * For reporting to battery stats the apps currently running foreground
1061     * service.  The ProcessMap is package/uid tuples; each of these contain
1062     * an array of the currently foreground processes.
1063     */
1064    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1065            = new ProcessMap<ArrayList<ProcessRecord>>();
1066
1067    /**
1068     * This is set if we had to do a delayed dexopt of an app before launching
1069     * it, to increase the ANR timeouts in that case.
1070     */
1071    boolean mDidDexOpt;
1072
1073    /**
1074     * Set if the systemServer made a call to enterSafeMode.
1075     */
1076    boolean mSafeMode;
1077
1078    /**
1079     * If true, we are running under a test environment so will sample PSS from processes
1080     * much more rapidly to try to collect better data when the tests are rapidly
1081     * running through apps.
1082     */
1083    boolean mTestPssMode = false;
1084
1085    String mDebugApp = null;
1086    boolean mWaitForDebugger = false;
1087    boolean mDebugTransient = false;
1088    String mOrigDebugApp = null;
1089    boolean mOrigWaitForDebugger = false;
1090    boolean mAlwaysFinishActivities = false;
1091    IActivityController mController = null;
1092    String mProfileApp = null;
1093    ProcessRecord mProfileProc = null;
1094    String mProfileFile;
1095    ParcelFileDescriptor mProfileFd;
1096    int mSamplingInterval = 0;
1097    boolean mAutoStopProfiler = false;
1098    int mProfileType = 0;
1099    String mOpenGlTraceApp = null;
1100
1101    final long[] mTmpLong = new long[1];
1102
1103    static class ProcessChangeItem {
1104        static final int CHANGE_ACTIVITIES = 1<<0;
1105        static final int CHANGE_PROCESS_STATE = 1<<1;
1106        int changes;
1107        int uid;
1108        int pid;
1109        int processState;
1110        boolean foregroundActivities;
1111    }
1112
1113    final RemoteCallbackList<IProcessObserver> mProcessObservers
1114            = new RemoteCallbackList<IProcessObserver>();
1115    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1116
1117    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1118            = new ArrayList<ProcessChangeItem>();
1119    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1120            = new ArrayList<ProcessChangeItem>();
1121
1122    /**
1123     * Runtime CPU use collection thread.  This object's lock is used to
1124     * perform synchronization with the thread (notifying it to run).
1125     */
1126    final Thread mProcessCpuThread;
1127
1128    /**
1129     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1130     * Must acquire this object's lock when accessing it.
1131     * NOTE: this lock will be held while doing long operations (trawling
1132     * through all processes in /proc), so it should never be acquired by
1133     * any critical paths such as when holding the main activity manager lock.
1134     */
1135    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1136            MONITOR_THREAD_CPU_USAGE);
1137    final AtomicLong mLastCpuTime = new AtomicLong(0);
1138    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1139
1140    long mLastWriteTime = 0;
1141
1142    /**
1143     * Used to retain an update lock when the foreground activity is in
1144     * immersive mode.
1145     */
1146    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1147
1148    /**
1149     * Set to true after the system has finished booting.
1150     */
1151    boolean mBooted = false;
1152
1153    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1154    int mProcessLimitOverride = -1;
1155
1156    WindowManagerService mWindowManager;
1157
1158    final ActivityThread mSystemThread;
1159
1160    // Holds the current foreground user's id
1161    int mCurrentUserId = 0;
1162    // Holds the target user's id during a user switch
1163    int mTargetUserId = UserHandle.USER_NULL;
1164    // If there are multiple profiles for the current user, their ids are here
1165    // Currently only the primary user can have managed profiles
1166    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1167
1168    /**
1169     * Mapping from each known user ID to the profile group ID it is associated with.
1170     */
1171    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1172
1173    private UserManagerService mUserManager;
1174
1175    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1176        final ProcessRecord mApp;
1177        final int mPid;
1178        final IApplicationThread mAppThread;
1179
1180        AppDeathRecipient(ProcessRecord app, int pid,
1181                IApplicationThread thread) {
1182            if (localLOGV) Slog.v(
1183                TAG, "New death recipient " + this
1184                + " for thread " + thread.asBinder());
1185            mApp = app;
1186            mPid = pid;
1187            mAppThread = thread;
1188        }
1189
1190        @Override
1191        public void binderDied() {
1192            if (localLOGV) Slog.v(
1193                TAG, "Death received in " + this
1194                + " for thread " + mAppThread.asBinder());
1195            synchronized(ActivityManagerService.this) {
1196                appDiedLocked(mApp, mPid, mAppThread);
1197            }
1198        }
1199    }
1200
1201    static final int SHOW_ERROR_MSG = 1;
1202    static final int SHOW_NOT_RESPONDING_MSG = 2;
1203    static final int SHOW_FACTORY_ERROR_MSG = 3;
1204    static final int UPDATE_CONFIGURATION_MSG = 4;
1205    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1206    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1207    static final int SERVICE_TIMEOUT_MSG = 12;
1208    static final int UPDATE_TIME_ZONE = 13;
1209    static final int SHOW_UID_ERROR_MSG = 14;
1210    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1211    static final int PROC_START_TIMEOUT_MSG = 20;
1212    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1213    static final int KILL_APPLICATION_MSG = 22;
1214    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1215    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1216    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1217    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1218    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1219    static final int CLEAR_DNS_CACHE_MSG = 28;
1220    static final int UPDATE_HTTP_PROXY_MSG = 29;
1221    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1222    static final int DISPATCH_PROCESSES_CHANGED = 31;
1223    static final int DISPATCH_PROCESS_DIED = 32;
1224    static final int REPORT_MEM_USAGE_MSG = 33;
1225    static final int REPORT_USER_SWITCH_MSG = 34;
1226    static final int CONTINUE_USER_SWITCH_MSG = 35;
1227    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1228    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1229    static final int PERSIST_URI_GRANTS_MSG = 38;
1230    static final int REQUEST_ALL_PSS_MSG = 39;
1231    static final int START_PROFILES_MSG = 40;
1232    static final int UPDATE_TIME = 41;
1233    static final int SYSTEM_USER_START_MSG = 42;
1234    static final int SYSTEM_USER_CURRENT_MSG = 43;
1235    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1236    static final int FINISH_BOOTING_MSG = 45;
1237    static final int START_USER_SWITCH_MSG = 46;
1238    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1239    static final int DISMISS_DIALOG_MSG = 48;
1240    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1241
1242    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1243    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1244    static final int FIRST_COMPAT_MODE_MSG = 300;
1245    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1246
1247    CompatModeDialog mCompatModeDialog;
1248    long mLastMemUsageReportTime = 0;
1249
1250    /**
1251     * Flag whether the current user is a "monkey", i.e. whether
1252     * the UI is driven by a UI automation tool.
1253     */
1254    private boolean mUserIsMonkey;
1255
1256    /** Flag whether the device has a Recents UI */
1257    boolean mHasRecents;
1258
1259    /** The dimensions of the thumbnails in the Recents UI. */
1260    int mThumbnailWidth;
1261    int mThumbnailHeight;
1262
1263    final ServiceThread mHandlerThread;
1264    final MainHandler mHandler;
1265
1266    final class MainHandler extends Handler {
1267        public MainHandler(Looper looper) {
1268            super(looper, null, true);
1269        }
1270
1271        @Override
1272        public void handleMessage(Message msg) {
1273            switch (msg.what) {
1274            case SHOW_ERROR_MSG: {
1275                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1276                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1277                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1278                synchronized (ActivityManagerService.this) {
1279                    ProcessRecord proc = (ProcessRecord)data.get("app");
1280                    AppErrorResult res = (AppErrorResult) data.get("result");
1281                    if (proc != null && proc.crashDialog != null) {
1282                        Slog.e(TAG, "App already has crash dialog: " + proc);
1283                        if (res != null) {
1284                            res.set(0);
1285                        }
1286                        return;
1287                    }
1288                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1289                            >= Process.FIRST_APPLICATION_UID
1290                            && proc.pid != MY_PID);
1291                    for (int userId : mCurrentProfileIds) {
1292                        isBackground &= (proc.userId != userId);
1293                    }
1294                    if (isBackground && !showBackground) {
1295                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1296                        if (res != null) {
1297                            res.set(0);
1298                        }
1299                        return;
1300                    }
1301                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1302                        Dialog d = new AppErrorDialog(mContext,
1303                                ActivityManagerService.this, res, proc);
1304                        d.show();
1305                        proc.crashDialog = d;
1306                    } else {
1307                        // The device is asleep, so just pretend that the user
1308                        // saw a crash dialog and hit "force quit".
1309                        if (res != null) {
1310                            res.set(0);
1311                        }
1312                    }
1313                }
1314
1315                ensureBootCompleted();
1316            } break;
1317            case SHOW_NOT_RESPONDING_MSG: {
1318                synchronized (ActivityManagerService.this) {
1319                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                    ProcessRecord proc = (ProcessRecord)data.get("app");
1321                    if (proc != null && proc.anrDialog != null) {
1322                        Slog.e(TAG, "App already has anr dialog: " + proc);
1323                        return;
1324                    }
1325
1326                    Intent intent = new Intent("android.intent.action.ANR");
1327                    if (!mProcessesReady) {
1328                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1329                                | Intent.FLAG_RECEIVER_FOREGROUND);
1330                    }
1331                    broadcastIntentLocked(null, null, intent,
1332                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1333                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1334
1335                    if (mShowDialogs) {
1336                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1337                                mContext, proc, (ActivityRecord)data.get("activity"),
1338                                msg.arg1 != 0);
1339                        d.show();
1340                        proc.anrDialog = d;
1341                    } else {
1342                        // Just kill the app if there is no dialog to be shown.
1343                        killAppAtUsersRequest(proc, null);
1344                    }
1345                }
1346
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1350                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1351                synchronized (ActivityManagerService.this) {
1352                    ProcessRecord proc = (ProcessRecord) data.get("app");
1353                    if (proc == null) {
1354                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1355                        break;
1356                    }
1357                    if (proc.crashDialog != null) {
1358                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1359                        return;
1360                    }
1361                    AppErrorResult res = (AppErrorResult) data.get("result");
1362                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1363                        Dialog d = new StrictModeViolationDialog(mContext,
1364                                ActivityManagerService.this, res, proc);
1365                        d.show();
1366                        proc.crashDialog = d;
1367                    } else {
1368                        // The device is asleep, so just pretend that the user
1369                        // saw a crash dialog and hit "force quit".
1370                        res.set(0);
1371                    }
1372                }
1373                ensureBootCompleted();
1374            } break;
1375            case SHOW_FACTORY_ERROR_MSG: {
1376                Dialog d = new FactoryErrorDialog(
1377                    mContext, msg.getData().getCharSequence("msg"));
1378                d.show();
1379                ensureBootCompleted();
1380            } break;
1381            case UPDATE_CONFIGURATION_MSG: {
1382                final ContentResolver resolver = mContext.getContentResolver();
1383                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1384            } break;
1385            case GC_BACKGROUND_PROCESSES_MSG: {
1386                synchronized (ActivityManagerService.this) {
1387                    performAppGcsIfAppropriateLocked();
1388                }
1389            } break;
1390            case WAIT_FOR_DEBUGGER_MSG: {
1391                synchronized (ActivityManagerService.this) {
1392                    ProcessRecord app = (ProcessRecord)msg.obj;
1393                    if (msg.arg1 != 0) {
1394                        if (!app.waitedForDebugger) {
1395                            Dialog d = new AppWaitingForDebuggerDialog(
1396                                    ActivityManagerService.this,
1397                                    mContext, app);
1398                            app.waitDialog = d;
1399                            app.waitedForDebugger = true;
1400                            d.show();
1401                        }
1402                    } else {
1403                        if (app.waitDialog != null) {
1404                            app.waitDialog.dismiss();
1405                            app.waitDialog = null;
1406                        }
1407                    }
1408                }
1409            } break;
1410            case SERVICE_TIMEOUT_MSG: {
1411                if (mDidDexOpt) {
1412                    mDidDexOpt = false;
1413                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1414                    nmsg.obj = msg.obj;
1415                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1416                    return;
1417                }
1418                mServices.serviceTimeout((ProcessRecord)msg.obj);
1419            } break;
1420            case UPDATE_TIME_ZONE: {
1421                synchronized (ActivityManagerService.this) {
1422                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1423                        ProcessRecord r = mLruProcesses.get(i);
1424                        if (r.thread != null) {
1425                            try {
1426                                r.thread.updateTimeZone();
1427                            } catch (RemoteException ex) {
1428                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1429                            }
1430                        }
1431                    }
1432                }
1433            } break;
1434            case CLEAR_DNS_CACHE_MSG: {
1435                synchronized (ActivityManagerService.this) {
1436                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1437                        ProcessRecord r = mLruProcesses.get(i);
1438                        if (r.thread != null) {
1439                            try {
1440                                r.thread.clearDnsCache();
1441                            } catch (RemoteException ex) {
1442                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1443                            }
1444                        }
1445                    }
1446                }
1447            } break;
1448            case UPDATE_HTTP_PROXY_MSG: {
1449                ProxyInfo proxy = (ProxyInfo)msg.obj;
1450                String host = "";
1451                String port = "";
1452                String exclList = "";
1453                Uri pacFileUrl = Uri.EMPTY;
1454                if (proxy != null) {
1455                    host = proxy.getHost();
1456                    port = Integer.toString(proxy.getPort());
1457                    exclList = proxy.getExclusionListAsString();
1458                    pacFileUrl = proxy.getPacFileUrl();
1459                }
1460                synchronized (ActivityManagerService.this) {
1461                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1462                        ProcessRecord r = mLruProcesses.get(i);
1463                        if (r.thread != null) {
1464                            try {
1465                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1466                            } catch (RemoteException ex) {
1467                                Slog.w(TAG, "Failed to update http proxy for: " +
1468                                        r.info.processName);
1469                            }
1470                        }
1471                    }
1472                }
1473            } break;
1474            case SHOW_UID_ERROR_MSG: {
1475                if (mShowDialogs) {
1476                    AlertDialog d = new BaseErrorDialog(mContext);
1477                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1478                    d.setCancelable(false);
1479                    d.setTitle(mContext.getText(R.string.android_system_label));
1480                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1481                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1482                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1483                    d.show();
1484                }
1485            } break;
1486            case SHOW_FINGERPRINT_ERROR_MSG: {
1487                if (mShowDialogs) {
1488                    AlertDialog d = new BaseErrorDialog(mContext);
1489                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1490                    d.setCancelable(false);
1491                    d.setTitle(mContext.getText(R.string.android_system_label));
1492                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1493                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1494                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1495                    d.show();
1496                }
1497            } break;
1498            case PROC_START_TIMEOUT_MSG: {
1499                if (mDidDexOpt) {
1500                    mDidDexOpt = false;
1501                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1502                    nmsg.obj = msg.obj;
1503                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1504                    return;
1505                }
1506                ProcessRecord app = (ProcessRecord)msg.obj;
1507                synchronized (ActivityManagerService.this) {
1508                    processStartTimedOutLocked(app);
1509                }
1510            } break;
1511            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1512                synchronized (ActivityManagerService.this) {
1513                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1514                }
1515            } break;
1516            case KILL_APPLICATION_MSG: {
1517                synchronized (ActivityManagerService.this) {
1518                    int appid = msg.arg1;
1519                    boolean restart = (msg.arg2 == 1);
1520                    Bundle bundle = (Bundle)msg.obj;
1521                    String pkg = bundle.getString("pkg");
1522                    String reason = bundle.getString("reason");
1523                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1524                            false, UserHandle.USER_ALL, reason);
1525                }
1526            } break;
1527            case FINALIZE_PENDING_INTENT_MSG: {
1528                ((PendingIntentRecord)msg.obj).completeFinalize();
1529            } break;
1530            case POST_HEAVY_NOTIFICATION_MSG: {
1531                INotificationManager inm = NotificationManager.getService();
1532                if (inm == null) {
1533                    return;
1534                }
1535
1536                ActivityRecord root = (ActivityRecord)msg.obj;
1537                ProcessRecord process = root.app;
1538                if (process == null) {
1539                    return;
1540                }
1541
1542                try {
1543                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1544                    String text = mContext.getString(R.string.heavy_weight_notification,
1545                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1546                    Notification notification = new Notification();
1547                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1548                    notification.when = 0;
1549                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1550                    notification.tickerText = text;
1551                    notification.defaults = 0; // please be quiet
1552                    notification.sound = null;
1553                    notification.vibrate = null;
1554                    notification.color = mContext.getResources().getColor(
1555                            com.android.internal.R.color.system_notification_accent_color);
1556                    notification.setLatestEventInfo(context, text,
1557                            mContext.getText(R.string.heavy_weight_notification_detail),
1558                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1559                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1560                                    new UserHandle(root.userId)));
1561
1562                    try {
1563                        int[] outId = new int[1];
1564                        inm.enqueueNotificationWithTag("android", "android", null,
1565                                R.string.heavy_weight_notification,
1566                                notification, outId, root.userId);
1567                    } catch (RuntimeException e) {
1568                        Slog.w(ActivityManagerService.TAG,
1569                                "Error showing notification for heavy-weight app", e);
1570                    } catch (RemoteException e) {
1571                    }
1572                } catch (NameNotFoundException e) {
1573                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1574                }
1575            } break;
1576            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1577                INotificationManager inm = NotificationManager.getService();
1578                if (inm == null) {
1579                    return;
1580                }
1581                try {
1582                    inm.cancelNotificationWithTag("android", null,
1583                            R.string.heavy_weight_notification,  msg.arg1);
1584                } catch (RuntimeException e) {
1585                    Slog.w(ActivityManagerService.TAG,
1586                            "Error canceling notification for service", e);
1587                } catch (RemoteException e) {
1588                }
1589            } break;
1590            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1591                synchronized (ActivityManagerService.this) {
1592                    checkExcessivePowerUsageLocked(true);
1593                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1594                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1595                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1596                }
1597            } break;
1598            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1599                synchronized (ActivityManagerService.this) {
1600                    ActivityRecord ar = (ActivityRecord)msg.obj;
1601                    if (mCompatModeDialog != null) {
1602                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1603                                ar.info.applicationInfo.packageName)) {
1604                            return;
1605                        }
1606                        mCompatModeDialog.dismiss();
1607                        mCompatModeDialog = null;
1608                    }
1609                    if (ar != null && false) {
1610                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1611                                ar.packageName)) {
1612                            int mode = mCompatModePackages.computeCompatModeLocked(
1613                                    ar.info.applicationInfo);
1614                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1615                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1616                                mCompatModeDialog = new CompatModeDialog(
1617                                        ActivityManagerService.this, mContext,
1618                                        ar.info.applicationInfo);
1619                                mCompatModeDialog.show();
1620                            }
1621                        }
1622                    }
1623                }
1624                break;
1625            }
1626            case DISPATCH_PROCESSES_CHANGED: {
1627                dispatchProcessesChanged();
1628                break;
1629            }
1630            case DISPATCH_PROCESS_DIED: {
1631                final int pid = msg.arg1;
1632                final int uid = msg.arg2;
1633                dispatchProcessDied(pid, uid);
1634                break;
1635            }
1636            case REPORT_MEM_USAGE_MSG: {
1637                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1638                Thread thread = new Thread() {
1639                    @Override public void run() {
1640                        reportMemUsage(memInfos);
1641                    }
1642                };
1643                thread.start();
1644                break;
1645            }
1646            case START_USER_SWITCH_MSG: {
1647                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1648                break;
1649            }
1650            case REPORT_USER_SWITCH_MSG: {
1651                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1652                break;
1653            }
1654            case CONTINUE_USER_SWITCH_MSG: {
1655                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1656                break;
1657            }
1658            case USER_SWITCH_TIMEOUT_MSG: {
1659                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1660                break;
1661            }
1662            case IMMERSIVE_MODE_LOCK_MSG: {
1663                final boolean nextState = (msg.arg1 != 0);
1664                if (mUpdateLock.isHeld() != nextState) {
1665                    if (DEBUG_IMMERSIVE) {
1666                        final ActivityRecord r = (ActivityRecord) msg.obj;
1667                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1668                    }
1669                    if (nextState) {
1670                        mUpdateLock.acquire();
1671                    } else {
1672                        mUpdateLock.release();
1673                    }
1674                }
1675                break;
1676            }
1677            case PERSIST_URI_GRANTS_MSG: {
1678                writeGrantedUriPermissions();
1679                break;
1680            }
1681            case REQUEST_ALL_PSS_MSG: {
1682                synchronized (ActivityManagerService.this) {
1683                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1684                }
1685                break;
1686            }
1687            case START_PROFILES_MSG: {
1688                synchronized (ActivityManagerService.this) {
1689                    startProfilesLocked();
1690                }
1691                break;
1692            }
1693            case UPDATE_TIME: {
1694                synchronized (ActivityManagerService.this) {
1695                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1696                        ProcessRecord r = mLruProcesses.get(i);
1697                        if (r.thread != null) {
1698                            try {
1699                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1700                            } catch (RemoteException ex) {
1701                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1702                            }
1703                        }
1704                    }
1705                }
1706                break;
1707            }
1708            case SYSTEM_USER_START_MSG: {
1709                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1710                        Integer.toString(msg.arg1), msg.arg1);
1711                mSystemServiceManager.startUser(msg.arg1);
1712                break;
1713            }
1714            case SYSTEM_USER_CURRENT_MSG: {
1715                mBatteryStatsService.noteEvent(
1716                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1717                        Integer.toString(msg.arg2), msg.arg2);
1718                mBatteryStatsService.noteEvent(
1719                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1720                        Integer.toString(msg.arg1), msg.arg1);
1721                mSystemServiceManager.switchUser(msg.arg1);
1722                break;
1723            }
1724            case ENTER_ANIMATION_COMPLETE_MSG: {
1725                synchronized (ActivityManagerService.this) {
1726                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1727                    if (r != null && r.app != null && r.app.thread != null) {
1728                        try {
1729                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1730                        } catch (RemoteException e) {
1731                        }
1732                    }
1733                }
1734                break;
1735            }
1736            case FINISH_BOOTING_MSG: {
1737                if (msg.arg1 != 0) {
1738                    finishBooting();
1739                }
1740                if (msg.arg2 != 0) {
1741                    enableScreenAfterBoot();
1742                }
1743                break;
1744            }
1745            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1746                try {
1747                    Locale l = (Locale) msg.obj;
1748                    IBinder service = ServiceManager.getService("mount");
1749                    IMountService mountService = IMountService.Stub.asInterface(service);
1750                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1751                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1752                } catch (RemoteException e) {
1753                    Log.e(TAG, "Error storing locale for decryption UI", e);
1754                }
1755                break;
1756            }
1757            case DISMISS_DIALOG_MSG: {
1758                final Dialog d = (Dialog) msg.obj;
1759                d.dismiss();
1760                break;
1761            }
1762            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1763                synchronized (ActivityManagerService.this) {
1764                    int i = mTaskStackListeners.beginBroadcast();
1765                    while (i > 0) {
1766                        i--;
1767                        try {
1768                            // Make a one-way callback to the listener
1769                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1770                        } catch (RemoteException e){
1771                            // Handled by the RemoteCallbackList
1772                        }
1773                    }
1774                    mTaskStackListeners.finishBroadcast();
1775                }
1776                break;
1777            }
1778            }
1779        }
1780    };
1781
1782    static final int COLLECT_PSS_BG_MSG = 1;
1783
1784    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1785        @Override
1786        public void handleMessage(Message msg) {
1787            switch (msg.what) {
1788            case COLLECT_PSS_BG_MSG: {
1789                long start = SystemClock.uptimeMillis();
1790                MemInfoReader memInfo = null;
1791                synchronized (ActivityManagerService.this) {
1792                    if (mFullPssPending) {
1793                        mFullPssPending = false;
1794                        memInfo = new MemInfoReader();
1795                    }
1796                }
1797                if (memInfo != null) {
1798                    updateCpuStatsNow();
1799                    long nativeTotalPss = 0;
1800                    synchronized (mProcessCpuTracker) {
1801                        final int N = mProcessCpuTracker.countStats();
1802                        for (int j=0; j<N; j++) {
1803                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1804                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1805                                // This is definitely an application process; skip it.
1806                                continue;
1807                            }
1808                            synchronized (mPidsSelfLocked) {
1809                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1810                                    // This is one of our own processes; skip it.
1811                                    continue;
1812                                }
1813                            }
1814                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1815                        }
1816                    }
1817                    memInfo.readMemInfo();
1818                    synchronized (ActivityManagerService.this) {
1819                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1820                                + (SystemClock.uptimeMillis()-start) + "ms");
1821                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1822                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1823                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1824                    }
1825                }
1826
1827                int num = 0;
1828                long[] tmp = new long[1];
1829                do {
1830                    ProcessRecord proc;
1831                    int procState;
1832                    int pid;
1833                    long lastPssTime;
1834                    synchronized (ActivityManagerService.this) {
1835                        if (mPendingPssProcesses.size() <= 0) {
1836                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1837                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1838                            mPendingPssProcesses.clear();
1839                            return;
1840                        }
1841                        proc = mPendingPssProcesses.remove(0);
1842                        procState = proc.pssProcState;
1843                        lastPssTime = proc.lastPssTime;
1844                        if (proc.thread != null && procState == proc.setProcState) {
1845                            pid = proc.pid;
1846                        } else {
1847                            proc = null;
1848                            pid = 0;
1849                        }
1850                    }
1851                    if (proc != null) {
1852                        long pss = Debug.getPss(pid, tmp, null);
1853                        synchronized (ActivityManagerService.this) {
1854                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1855                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1856                                num++;
1857                                recordPssSample(proc, procState, pss, tmp[0],
1858                                        SystemClock.uptimeMillis());
1859                            }
1860                        }
1861                    }
1862                } while (true);
1863            }
1864            }
1865        }
1866    };
1867
1868    public void setSystemProcess() {
1869        try {
1870            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1871            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1872            ServiceManager.addService("meminfo", new MemBinder(this));
1873            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1874            ServiceManager.addService("dbinfo", new DbBinder(this));
1875            if (MONITOR_CPU_USAGE) {
1876                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1877            }
1878            ServiceManager.addService("permission", new PermissionController(this));
1879
1880            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1881                    "android", STOCK_PM_FLAGS);
1882            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1883
1884            synchronized (this) {
1885                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1886                app.persistent = true;
1887                app.pid = MY_PID;
1888                app.maxAdj = ProcessList.SYSTEM_ADJ;
1889                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1890                mProcessNames.put(app.processName, app.uid, app);
1891                synchronized (mPidsSelfLocked) {
1892                    mPidsSelfLocked.put(app.pid, app);
1893                }
1894                updateLruProcessLocked(app, false, null);
1895                updateOomAdjLocked();
1896            }
1897        } catch (PackageManager.NameNotFoundException e) {
1898            throw new RuntimeException(
1899                    "Unable to find android system package", e);
1900        }
1901    }
1902
1903    public void setWindowManager(WindowManagerService wm) {
1904        mWindowManager = wm;
1905        mStackSupervisor.setWindowManager(wm);
1906    }
1907
1908    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1909        mUsageStatsService = usageStatsManager;
1910    }
1911
1912    public void startObservingNativeCrashes() {
1913        final NativeCrashListener ncl = new NativeCrashListener(this);
1914        ncl.start();
1915    }
1916
1917    public IAppOpsService getAppOpsService() {
1918        return mAppOpsService;
1919    }
1920
1921    static class MemBinder extends Binder {
1922        ActivityManagerService mActivityManagerService;
1923        MemBinder(ActivityManagerService activityManagerService) {
1924            mActivityManagerService = activityManagerService;
1925        }
1926
1927        @Override
1928        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1929            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1930                    != PackageManager.PERMISSION_GRANTED) {
1931                pw.println("Permission Denial: can't dump meminfo from from pid="
1932                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1933                        + " without permission " + android.Manifest.permission.DUMP);
1934                return;
1935            }
1936
1937            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1938        }
1939    }
1940
1941    static class GraphicsBinder extends Binder {
1942        ActivityManagerService mActivityManagerService;
1943        GraphicsBinder(ActivityManagerService activityManagerService) {
1944            mActivityManagerService = activityManagerService;
1945        }
1946
1947        @Override
1948        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1949            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1950                    != PackageManager.PERMISSION_GRANTED) {
1951                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1952                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1953                        + " without permission " + android.Manifest.permission.DUMP);
1954                return;
1955            }
1956
1957            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1958        }
1959    }
1960
1961    static class DbBinder extends Binder {
1962        ActivityManagerService mActivityManagerService;
1963        DbBinder(ActivityManagerService activityManagerService) {
1964            mActivityManagerService = activityManagerService;
1965        }
1966
1967        @Override
1968        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1969            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1970                    != PackageManager.PERMISSION_GRANTED) {
1971                pw.println("Permission Denial: can't dump dbinfo from from pid="
1972                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1973                        + " without permission " + android.Manifest.permission.DUMP);
1974                return;
1975            }
1976
1977            mActivityManagerService.dumpDbInfo(fd, pw, args);
1978        }
1979    }
1980
1981    static class CpuBinder extends Binder {
1982        ActivityManagerService mActivityManagerService;
1983        CpuBinder(ActivityManagerService activityManagerService) {
1984            mActivityManagerService = activityManagerService;
1985        }
1986
1987        @Override
1988        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1989            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1990                    != PackageManager.PERMISSION_GRANTED) {
1991                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1992                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1993                        + " without permission " + android.Manifest.permission.DUMP);
1994                return;
1995            }
1996
1997            synchronized (mActivityManagerService.mProcessCpuTracker) {
1998                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1999                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2000                        SystemClock.uptimeMillis()));
2001            }
2002        }
2003    }
2004
2005    public static final class Lifecycle extends SystemService {
2006        private final ActivityManagerService mService;
2007
2008        public Lifecycle(Context context) {
2009            super(context);
2010            mService = new ActivityManagerService(context);
2011        }
2012
2013        @Override
2014        public void onStart() {
2015            mService.start();
2016        }
2017
2018        public ActivityManagerService getService() {
2019            return mService;
2020        }
2021    }
2022
2023    // Note: This method is invoked on the main thread but may need to attach various
2024    // handlers to other threads.  So take care to be explicit about the looper.
2025    public ActivityManagerService(Context systemContext) {
2026        mContext = systemContext;
2027        mFactoryTest = FactoryTest.getMode();
2028        mSystemThread = ActivityThread.currentActivityThread();
2029
2030        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2031
2032        mHandlerThread = new ServiceThread(TAG,
2033                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2034        mHandlerThread.start();
2035        mHandler = new MainHandler(mHandlerThread.getLooper());
2036
2037        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2038                "foreground", BROADCAST_FG_TIMEOUT, false);
2039        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2040                "background", BROADCAST_BG_TIMEOUT, true);
2041        mBroadcastQueues[0] = mFgBroadcastQueue;
2042        mBroadcastQueues[1] = mBgBroadcastQueue;
2043
2044        mServices = new ActiveServices(this);
2045        mProviderMap = new ProviderMap(this);
2046
2047        // TODO: Move creation of battery stats service outside of activity manager service.
2048        File dataDir = Environment.getDataDirectory();
2049        File systemDir = new File(dataDir, "system");
2050        systemDir.mkdirs();
2051        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2052        mBatteryStatsService.getActiveStatistics().readLocked();
2053        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2054        mOnBattery = DEBUG_POWER ? true
2055                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2056        mBatteryStatsService.getActiveStatistics().setCallback(this);
2057
2058        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2059
2060        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2061
2062        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2063
2064        // User 0 is the first and only user that runs at boot.
2065        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2066        mUserLru.add(Integer.valueOf(0));
2067        updateStartedUserArrayLocked();
2068
2069        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2070            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2071
2072        mConfiguration.setToDefaults();
2073        mConfiguration.setLocale(Locale.getDefault());
2074
2075        mConfigurationSeq = mConfiguration.seq = 1;
2076        mProcessCpuTracker.init();
2077
2078        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2079        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2080        mStackSupervisor = new ActivityStackSupervisor(this);
2081        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2082
2083        mProcessCpuThread = new Thread("CpuTracker") {
2084            @Override
2085            public void run() {
2086                while (true) {
2087                    try {
2088                        try {
2089                            synchronized(this) {
2090                                final long now = SystemClock.uptimeMillis();
2091                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2092                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2093                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2094                                //        + ", write delay=" + nextWriteDelay);
2095                                if (nextWriteDelay < nextCpuDelay) {
2096                                    nextCpuDelay = nextWriteDelay;
2097                                }
2098                                if (nextCpuDelay > 0) {
2099                                    mProcessCpuMutexFree.set(true);
2100                                    this.wait(nextCpuDelay);
2101                                }
2102                            }
2103                        } catch (InterruptedException e) {
2104                        }
2105                        updateCpuStatsNow();
2106                    } catch (Exception e) {
2107                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2108                    }
2109                }
2110            }
2111        };
2112
2113        Watchdog.getInstance().addMonitor(this);
2114        Watchdog.getInstance().addThread(mHandler);
2115    }
2116
2117    public void setSystemServiceManager(SystemServiceManager mgr) {
2118        mSystemServiceManager = mgr;
2119    }
2120
2121    public void setInstaller(Installer installer) {
2122        mInstaller = installer;
2123    }
2124
2125    private void start() {
2126        Process.removeAllProcessGroups();
2127        mProcessCpuThread.start();
2128
2129        mBatteryStatsService.publish(mContext);
2130        mAppOpsService.publish(mContext);
2131        Slog.d("AppOps", "AppOpsService published");
2132        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2133    }
2134
2135    public void initPowerManagement() {
2136        mStackSupervisor.initPowerManagement();
2137        mBatteryStatsService.initPowerManagement();
2138    }
2139
2140    @Override
2141    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2142            throws RemoteException {
2143        if (code == SYSPROPS_TRANSACTION) {
2144            // We need to tell all apps about the system property change.
2145            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2146            synchronized(this) {
2147                final int NP = mProcessNames.getMap().size();
2148                for (int ip=0; ip<NP; ip++) {
2149                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2150                    final int NA = apps.size();
2151                    for (int ia=0; ia<NA; ia++) {
2152                        ProcessRecord app = apps.valueAt(ia);
2153                        if (app.thread != null) {
2154                            procs.add(app.thread.asBinder());
2155                        }
2156                    }
2157                }
2158            }
2159
2160            int N = procs.size();
2161            for (int i=0; i<N; i++) {
2162                Parcel data2 = Parcel.obtain();
2163                try {
2164                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2165                } catch (RemoteException e) {
2166                }
2167                data2.recycle();
2168            }
2169        }
2170        try {
2171            return super.onTransact(code, data, reply, flags);
2172        } catch (RuntimeException e) {
2173            // The activity manager only throws security exceptions, so let's
2174            // log all others.
2175            if (!(e instanceof SecurityException)) {
2176                Slog.wtf(TAG, "Activity Manager Crash", e);
2177            }
2178            throw e;
2179        }
2180    }
2181
2182    void updateCpuStats() {
2183        final long now = SystemClock.uptimeMillis();
2184        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2185            return;
2186        }
2187        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2188            synchronized (mProcessCpuThread) {
2189                mProcessCpuThread.notify();
2190            }
2191        }
2192    }
2193
2194    void updateCpuStatsNow() {
2195        synchronized (mProcessCpuTracker) {
2196            mProcessCpuMutexFree.set(false);
2197            final long now = SystemClock.uptimeMillis();
2198            boolean haveNewCpuStats = false;
2199
2200            if (MONITOR_CPU_USAGE &&
2201                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2202                mLastCpuTime.set(now);
2203                haveNewCpuStats = true;
2204                mProcessCpuTracker.update();
2205                //Slog.i(TAG, mProcessCpu.printCurrentState());
2206                //Slog.i(TAG, "Total CPU usage: "
2207                //        + mProcessCpu.getTotalCpuPercent() + "%");
2208
2209                // Slog the cpu usage if the property is set.
2210                if ("true".equals(SystemProperties.get("events.cpu"))) {
2211                    int user = mProcessCpuTracker.getLastUserTime();
2212                    int system = mProcessCpuTracker.getLastSystemTime();
2213                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2214                    int irq = mProcessCpuTracker.getLastIrqTime();
2215                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2216                    int idle = mProcessCpuTracker.getLastIdleTime();
2217
2218                    int total = user + system + iowait + irq + softIrq + idle;
2219                    if (total == 0) total = 1;
2220
2221                    EventLog.writeEvent(EventLogTags.CPU,
2222                            ((user+system+iowait+irq+softIrq) * 100) / total,
2223                            (user * 100) / total,
2224                            (system * 100) / total,
2225                            (iowait * 100) / total,
2226                            (irq * 100) / total,
2227                            (softIrq * 100) / total);
2228                }
2229            }
2230
2231            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2232            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2233            synchronized(bstats) {
2234                synchronized(mPidsSelfLocked) {
2235                    if (haveNewCpuStats) {
2236                        if (mOnBattery) {
2237                            int perc = bstats.startAddingCpuLocked();
2238                            int totalUTime = 0;
2239                            int totalSTime = 0;
2240                            final int N = mProcessCpuTracker.countStats();
2241                            for (int i=0; i<N; i++) {
2242                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2243                                if (!st.working) {
2244                                    continue;
2245                                }
2246                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2247                                int otherUTime = (st.rel_utime*perc)/100;
2248                                int otherSTime = (st.rel_stime*perc)/100;
2249                                totalUTime += otherUTime;
2250                                totalSTime += otherSTime;
2251                                if (pr != null) {
2252                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2253                                    if (ps == null || !ps.isActive()) {
2254                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2255                                                pr.info.uid, pr.processName);
2256                                    }
2257                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2258                                            st.rel_stime-otherSTime);
2259                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2260                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2261                                } else {
2262                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2263                                    if (ps == null || !ps.isActive()) {
2264                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2265                                                bstats.mapUid(st.uid), st.name);
2266                                    }
2267                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2268                                            st.rel_stime-otherSTime);
2269                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2270                                }
2271                            }
2272                            bstats.finishAddingCpuLocked(perc, totalUTime,
2273                                    totalSTime, cpuSpeedTimes);
2274                        }
2275                    }
2276                }
2277
2278                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2279                    mLastWriteTime = now;
2280                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2281                }
2282            }
2283        }
2284    }
2285
2286    @Override
2287    public void batteryNeedsCpuUpdate() {
2288        updateCpuStatsNow();
2289    }
2290
2291    @Override
2292    public void batteryPowerChanged(boolean onBattery) {
2293        // When plugging in, update the CPU stats first before changing
2294        // the plug state.
2295        updateCpuStatsNow();
2296        synchronized (this) {
2297            synchronized(mPidsSelfLocked) {
2298                mOnBattery = DEBUG_POWER ? true : onBattery;
2299            }
2300        }
2301    }
2302
2303    /**
2304     * Initialize the application bind args. These are passed to each
2305     * process when the bindApplication() IPC is sent to the process. They're
2306     * lazily setup to make sure the services are running when they're asked for.
2307     */
2308    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2309        if (mAppBindArgs == null) {
2310            mAppBindArgs = new HashMap<>();
2311
2312            // Isolated processes won't get this optimization, so that we don't
2313            // violate the rules about which services they have access to.
2314            if (!isolated) {
2315                // Setup the application init args
2316                mAppBindArgs.put("package", ServiceManager.getService("package"));
2317                mAppBindArgs.put("window", ServiceManager.getService("window"));
2318                mAppBindArgs.put(Context.ALARM_SERVICE,
2319                        ServiceManager.getService(Context.ALARM_SERVICE));
2320            }
2321        }
2322        return mAppBindArgs;
2323    }
2324
2325    final void setFocusedActivityLocked(ActivityRecord r) {
2326        if (mFocusedActivity != r) {
2327            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2328            mFocusedActivity = r;
2329            if (r.task != null && r.task.voiceInteractor != null) {
2330                startRunningVoiceLocked();
2331            } else {
2332                finishRunningVoiceLocked();
2333            }
2334            mStackSupervisor.setFocusedStack(r);
2335            if (r != null) {
2336                mWindowManager.setFocusedApp(r.appToken, true);
2337            }
2338            applyUpdateLockStateLocked(r);
2339        }
2340    }
2341
2342    final void clearFocusedActivity(ActivityRecord r) {
2343        if (mFocusedActivity == r) {
2344            mFocusedActivity = null;
2345        }
2346    }
2347
2348    @Override
2349    public void setFocusedStack(int stackId) {
2350        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2351        synchronized (ActivityManagerService.this) {
2352            ActivityStack stack = mStackSupervisor.getStack(stackId);
2353            if (stack != null) {
2354                ActivityRecord r = stack.topRunningActivityLocked(null);
2355                if (r != null) {
2356                    setFocusedActivityLocked(r);
2357                }
2358            }
2359        }
2360    }
2361
2362    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2363    @Override
2364    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2365        synchronized (ActivityManagerService.this) {
2366            if (listener != null) {
2367                mTaskStackListeners.register(listener);
2368            }
2369        }
2370    }
2371
2372    @Override
2373    public void notifyActivityDrawn(IBinder token) {
2374        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2375        synchronized (this) {
2376            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2377            if (r != null) {
2378                r.task.stack.notifyActivityDrawnLocked(r);
2379            }
2380        }
2381    }
2382
2383    final void applyUpdateLockStateLocked(ActivityRecord r) {
2384        // Modifications to the UpdateLock state are done on our handler, outside
2385        // the activity manager's locks.  The new state is determined based on the
2386        // state *now* of the relevant activity record.  The object is passed to
2387        // the handler solely for logging detail, not to be consulted/modified.
2388        final boolean nextState = r != null && r.immersive;
2389        mHandler.sendMessage(
2390                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2391    }
2392
2393    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2394        Message msg = Message.obtain();
2395        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2396        msg.obj = r.task.askedCompatMode ? null : r;
2397        mHandler.sendMessage(msg);
2398    }
2399
2400    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2401            String what, Object obj, ProcessRecord srcApp) {
2402        app.lastActivityTime = now;
2403
2404        if (app.activities.size() > 0) {
2405            // Don't want to touch dependent processes that are hosting activities.
2406            return index;
2407        }
2408
2409        int lrui = mLruProcesses.lastIndexOf(app);
2410        if (lrui < 0) {
2411            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2412                    + what + " " + obj + " from " + srcApp);
2413            return index;
2414        }
2415
2416        if (lrui >= index) {
2417            // Don't want to cause this to move dependent processes *back* in the
2418            // list as if they were less frequently used.
2419            return index;
2420        }
2421
2422        if (lrui >= mLruProcessActivityStart) {
2423            // Don't want to touch dependent processes that are hosting activities.
2424            return index;
2425        }
2426
2427        mLruProcesses.remove(lrui);
2428        if (index > 0) {
2429            index--;
2430        }
2431        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2432                + " in LRU list: " + app);
2433        mLruProcesses.add(index, app);
2434        return index;
2435    }
2436
2437    final void removeLruProcessLocked(ProcessRecord app) {
2438        int lrui = mLruProcesses.lastIndexOf(app);
2439        if (lrui >= 0) {
2440            if (!app.killed) {
2441                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2442                Process.killProcessQuiet(app.pid);
2443                Process.killProcessGroup(app.info.uid, app.pid);
2444            }
2445            if (lrui <= mLruProcessActivityStart) {
2446                mLruProcessActivityStart--;
2447            }
2448            if (lrui <= mLruProcessServiceStart) {
2449                mLruProcessServiceStart--;
2450            }
2451            mLruProcesses.remove(lrui);
2452        }
2453    }
2454
2455    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2456            ProcessRecord client) {
2457        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2458                || app.treatLikeActivity;
2459        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2460        if (!activityChange && hasActivity) {
2461            // The process has activities, so we are only allowing activity-based adjustments
2462            // to move it.  It should be kept in the front of the list with other
2463            // processes that have activities, and we don't want those to change their
2464            // order except due to activity operations.
2465            return;
2466        }
2467
2468        mLruSeq++;
2469        final long now = SystemClock.uptimeMillis();
2470        app.lastActivityTime = now;
2471
2472        // First a quick reject: if the app is already at the position we will
2473        // put it, then there is nothing to do.
2474        if (hasActivity) {
2475            final int N = mLruProcesses.size();
2476            if (N > 0 && mLruProcesses.get(N-1) == app) {
2477                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2478                return;
2479            }
2480        } else {
2481            if (mLruProcessServiceStart > 0
2482                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2483                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2484                return;
2485            }
2486        }
2487
2488        int lrui = mLruProcesses.lastIndexOf(app);
2489
2490        if (app.persistent && lrui >= 0) {
2491            // We don't care about the position of persistent processes, as long as
2492            // they are in the list.
2493            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2494            return;
2495        }
2496
2497        /* In progress: compute new position first, so we can avoid doing work
2498           if the process is not actually going to move.  Not yet working.
2499        int addIndex;
2500        int nextIndex;
2501        boolean inActivity = false, inService = false;
2502        if (hasActivity) {
2503            // Process has activities, put it at the very tipsy-top.
2504            addIndex = mLruProcesses.size();
2505            nextIndex = mLruProcessServiceStart;
2506            inActivity = true;
2507        } else if (hasService) {
2508            // Process has services, put it at the top of the service list.
2509            addIndex = mLruProcessActivityStart;
2510            nextIndex = mLruProcessServiceStart;
2511            inActivity = true;
2512            inService = true;
2513        } else  {
2514            // Process not otherwise of interest, it goes to the top of the non-service area.
2515            addIndex = mLruProcessServiceStart;
2516            if (client != null) {
2517                int clientIndex = mLruProcesses.lastIndexOf(client);
2518                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2519                        + app);
2520                if (clientIndex >= 0 && addIndex > clientIndex) {
2521                    addIndex = clientIndex;
2522                }
2523            }
2524            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2525        }
2526
2527        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2528                + mLruProcessActivityStart + "): " + app);
2529        */
2530
2531        if (lrui >= 0) {
2532            if (lrui < mLruProcessActivityStart) {
2533                mLruProcessActivityStart--;
2534            }
2535            if (lrui < mLruProcessServiceStart) {
2536                mLruProcessServiceStart--;
2537            }
2538            /*
2539            if (addIndex > lrui) {
2540                addIndex--;
2541            }
2542            if (nextIndex > lrui) {
2543                nextIndex--;
2544            }
2545            */
2546            mLruProcesses.remove(lrui);
2547        }
2548
2549        /*
2550        mLruProcesses.add(addIndex, app);
2551        if (inActivity) {
2552            mLruProcessActivityStart++;
2553        }
2554        if (inService) {
2555            mLruProcessActivityStart++;
2556        }
2557        */
2558
2559        int nextIndex;
2560        if (hasActivity) {
2561            final int N = mLruProcesses.size();
2562            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2563                // Process doesn't have activities, but has clients with
2564                // activities...  move it up, but one below the top (the top
2565                // should always have a real activity).
2566                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2567                mLruProcesses.add(N-1, app);
2568                // To keep it from spamming the LRU list (by making a bunch of clients),
2569                // we will push down any other entries owned by the app.
2570                final int uid = app.info.uid;
2571                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2572                    ProcessRecord subProc = mLruProcesses.get(i);
2573                    if (subProc.info.uid == uid) {
2574                        // We want to push this one down the list.  If the process after
2575                        // it is for the same uid, however, don't do so, because we don't
2576                        // want them internally to be re-ordered.
2577                        if (mLruProcesses.get(i-1).info.uid != uid) {
2578                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2579                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2580                            ProcessRecord tmp = mLruProcesses.get(i);
2581                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2582                            mLruProcesses.set(i-1, tmp);
2583                            i--;
2584                        }
2585                    } else {
2586                        // A gap, we can stop here.
2587                        break;
2588                    }
2589                }
2590            } else {
2591                // Process has activities, put it at the very tipsy-top.
2592                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2593                mLruProcesses.add(app);
2594            }
2595            nextIndex = mLruProcessServiceStart;
2596        } else if (hasService) {
2597            // Process has services, put it at the top of the service list.
2598            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2599            mLruProcesses.add(mLruProcessActivityStart, app);
2600            nextIndex = mLruProcessServiceStart;
2601            mLruProcessActivityStart++;
2602        } else  {
2603            // Process not otherwise of interest, it goes to the top of the non-service area.
2604            int index = mLruProcessServiceStart;
2605            if (client != null) {
2606                // If there is a client, don't allow the process to be moved up higher
2607                // in the list than that client.
2608                int clientIndex = mLruProcesses.lastIndexOf(client);
2609                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2610                        + " when updating " + app);
2611                if (clientIndex <= lrui) {
2612                    // Don't allow the client index restriction to push it down farther in the
2613                    // list than it already is.
2614                    clientIndex = lrui;
2615                }
2616                if (clientIndex >= 0 && index > clientIndex) {
2617                    index = clientIndex;
2618                }
2619            }
2620            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2621            mLruProcesses.add(index, app);
2622            nextIndex = index-1;
2623            mLruProcessActivityStart++;
2624            mLruProcessServiceStart++;
2625        }
2626
2627        // If the app is currently using a content provider or service,
2628        // bump those processes as well.
2629        for (int j=app.connections.size()-1; j>=0; j--) {
2630            ConnectionRecord cr = app.connections.valueAt(j);
2631            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2632                    && cr.binding.service.app != null
2633                    && cr.binding.service.app.lruSeq != mLruSeq
2634                    && !cr.binding.service.app.persistent) {
2635                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2636                        "service connection", cr, app);
2637            }
2638        }
2639        for (int j=app.conProviders.size()-1; j>=0; j--) {
2640            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2641            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2642                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2643                        "provider reference", cpr, app);
2644            }
2645        }
2646    }
2647
2648    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2649        if (uid == Process.SYSTEM_UID) {
2650            // The system gets to run in any process.  If there are multiple
2651            // processes with the same uid, just pick the first (this
2652            // should never happen).
2653            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2654            if (procs == null) return null;
2655            final int N = procs.size();
2656            for (int i = 0; i < N; i++) {
2657                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2658            }
2659        }
2660        ProcessRecord proc = mProcessNames.get(processName, uid);
2661        if (false && proc != null && !keepIfLarge
2662                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2663                && proc.lastCachedPss >= 4000) {
2664            // Turn this condition on to cause killing to happen regularly, for testing.
2665            if (proc.baseProcessTracker != null) {
2666                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2667            }
2668            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2669        } else if (proc != null && !keepIfLarge
2670                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2671                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2672            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2673            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2674                if (proc.baseProcessTracker != null) {
2675                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2676                }
2677                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2678            }
2679        }
2680        return proc;
2681    }
2682
2683    void ensurePackageDexOpt(String packageName) {
2684        IPackageManager pm = AppGlobals.getPackageManager();
2685        try {
2686            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2687                mDidDexOpt = true;
2688            }
2689        } catch (RemoteException e) {
2690        }
2691    }
2692
2693    boolean isNextTransitionForward() {
2694        int transit = mWindowManager.getPendingAppTransition();
2695        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2696                || transit == AppTransition.TRANSIT_TASK_OPEN
2697                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2698    }
2699
2700    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2701            String processName, String abiOverride, int uid, Runnable crashHandler) {
2702        synchronized(this) {
2703            ApplicationInfo info = new ApplicationInfo();
2704            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2705            // For isolated processes, the former contains the parent's uid and the latter the
2706            // actual uid of the isolated process.
2707            // In the special case introduced by this method (which is, starting an isolated
2708            // process directly from the SystemServer without an actual parent app process) the
2709            // closest thing to a parent's uid is SYSTEM_UID.
2710            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2711            // the |isolated| logic in the ProcessRecord constructor.
2712            info.uid = Process.SYSTEM_UID;
2713            info.processName = processName;
2714            info.className = entryPoint;
2715            info.packageName = "android";
2716            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2717                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2718                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2719                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2720                    crashHandler);
2721            return proc != null ? proc.pid : 0;
2722        }
2723    }
2724
2725    final ProcessRecord startProcessLocked(String processName,
2726            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2727            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2728            boolean isolated, boolean keepIfLarge) {
2729        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2730                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2731                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2732                null /* crashHandler */);
2733    }
2734
2735    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2736            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2737            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2738            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2739        long startTime = SystemClock.elapsedRealtime();
2740        ProcessRecord app;
2741        if (!isolated) {
2742            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2743            checkTime(startTime, "startProcess: after getProcessRecord");
2744        } else {
2745            // If this is an isolated process, it can't re-use an existing process.
2746            app = null;
2747        }
2748        // We don't have to do anything more if:
2749        // (1) There is an existing application record; and
2750        // (2) The caller doesn't think it is dead, OR there is no thread
2751        //     object attached to it so we know it couldn't have crashed; and
2752        // (3) There is a pid assigned to it, so it is either starting or
2753        //     already running.
2754        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2755                + " app=" + app + " knownToBeDead=" + knownToBeDead
2756                + " thread=" + (app != null ? app.thread : null)
2757                + " pid=" + (app != null ? app.pid : -1));
2758        if (app != null && app.pid > 0) {
2759            if (!knownToBeDead || app.thread == null) {
2760                // We already have the app running, or are waiting for it to
2761                // come up (we have a pid but not yet its thread), so keep it.
2762                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2763                // If this is a new package in the process, add the package to the list
2764                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2765                checkTime(startTime, "startProcess: done, added package to proc");
2766                return app;
2767            }
2768
2769            // An application record is attached to a previous process,
2770            // clean it up now.
2771            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2772            checkTime(startTime, "startProcess: bad proc running, killing");
2773            Process.killProcessGroup(app.info.uid, app.pid);
2774            handleAppDiedLocked(app, true, true);
2775            checkTime(startTime, "startProcess: done killing old proc");
2776        }
2777
2778        String hostingNameStr = hostingName != null
2779                ? hostingName.flattenToShortString() : null;
2780
2781        if (!isolated) {
2782            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2783                // If we are in the background, then check to see if this process
2784                // is bad.  If so, we will just silently fail.
2785                if (mBadProcesses.get(info.processName, info.uid) != null) {
2786                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2787                            + "/" + info.processName);
2788                    return null;
2789                }
2790            } else {
2791                // When the user is explicitly starting a process, then clear its
2792                // crash count so that we won't make it bad until they see at
2793                // least one crash dialog again, and make the process good again
2794                // if it had been bad.
2795                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2796                        + "/" + info.processName);
2797                mProcessCrashTimes.remove(info.processName, info.uid);
2798                if (mBadProcesses.get(info.processName, info.uid) != null) {
2799                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2800                            UserHandle.getUserId(info.uid), info.uid,
2801                            info.processName);
2802                    mBadProcesses.remove(info.processName, info.uid);
2803                    if (app != null) {
2804                        app.bad = false;
2805                    }
2806                }
2807            }
2808        }
2809
2810        if (app == null) {
2811            checkTime(startTime, "startProcess: creating new process record");
2812            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2813            if (app == null) {
2814                Slog.w(TAG, "Failed making new process record for "
2815                        + processName + "/" + info.uid + " isolated=" + isolated);
2816                return null;
2817            }
2818            app.crashHandler = crashHandler;
2819            mProcessNames.put(processName, app.uid, app);
2820            if (isolated) {
2821                mIsolatedProcesses.put(app.uid, app);
2822            }
2823            checkTime(startTime, "startProcess: done creating new process record");
2824        } else {
2825            // If this is a new package in the process, add the package to the list
2826            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2827            checkTime(startTime, "startProcess: added package to existing proc");
2828        }
2829
2830        // If the system is not ready yet, then hold off on starting this
2831        // process until it is.
2832        if (!mProcessesReady
2833                && !isAllowedWhileBooting(info)
2834                && !allowWhileBooting) {
2835            if (!mProcessesOnHold.contains(app)) {
2836                mProcessesOnHold.add(app);
2837            }
2838            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2839            checkTime(startTime, "startProcess: returning with proc on hold");
2840            return app;
2841        }
2842
2843        checkTime(startTime, "startProcess: stepping in to startProcess");
2844        startProcessLocked(
2845                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2846        checkTime(startTime, "startProcess: done starting proc!");
2847        return (app.pid != 0) ? app : null;
2848    }
2849
2850    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2851        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2852    }
2853
2854    private final void startProcessLocked(ProcessRecord app,
2855            String hostingType, String hostingNameStr) {
2856        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2857                null /* entryPoint */, null /* entryPointArgs */);
2858    }
2859
2860    private final void startProcessLocked(ProcessRecord app, String hostingType,
2861            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2862        long startTime = SystemClock.elapsedRealtime();
2863        if (app.pid > 0 && app.pid != MY_PID) {
2864            checkTime(startTime, "startProcess: removing from pids map");
2865            synchronized (mPidsSelfLocked) {
2866                mPidsSelfLocked.remove(app.pid);
2867                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2868            }
2869            checkTime(startTime, "startProcess: done removing from pids map");
2870            app.setPid(0);
2871        }
2872
2873        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2874                "startProcessLocked removing on hold: " + app);
2875        mProcessesOnHold.remove(app);
2876
2877        checkTime(startTime, "startProcess: starting to update cpu stats");
2878        updateCpuStats();
2879        checkTime(startTime, "startProcess: done updating cpu stats");
2880
2881        try {
2882            int uid = app.uid;
2883
2884            int[] gids = null;
2885            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2886            if (!app.isolated) {
2887                int[] permGids = null;
2888                try {
2889                    checkTime(startTime, "startProcess: getting gids from package manager");
2890                    final PackageManager pm = mContext.getPackageManager();
2891                    permGids = pm.getPackageGids(app.info.packageName);
2892
2893                    if (Environment.isExternalStorageEmulated()) {
2894                        checkTime(startTime, "startProcess: checking external storage perm");
2895                        if (pm.checkPermission(
2896                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2897                                app.info.packageName) == PERMISSION_GRANTED) {
2898                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2899                        } else {
2900                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2901                        }
2902                    }
2903                } catch (PackageManager.NameNotFoundException e) {
2904                    Slog.w(TAG, "Unable to retrieve gids", e);
2905                }
2906
2907                /*
2908                 * Add shared application and profile GIDs so applications can share some
2909                 * resources like shared libraries and access user-wide resources
2910                 */
2911                if (permGids == null) {
2912                    gids = new int[2];
2913                } else {
2914                    gids = new int[permGids.length + 2];
2915                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2916                }
2917                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2918                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2919            }
2920            checkTime(startTime, "startProcess: building args");
2921            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2922                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2923                        && mTopComponent != null
2924                        && app.processName.equals(mTopComponent.getPackageName())) {
2925                    uid = 0;
2926                }
2927                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2928                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2929                    uid = 0;
2930                }
2931            }
2932            int debugFlags = 0;
2933            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2934                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2935                // Also turn on CheckJNI for debuggable apps. It's quite
2936                // awkward to turn on otherwise.
2937                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2938            }
2939            // Run the app in safe mode if its manifest requests so or the
2940            // system is booted in safe mode.
2941            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2942                mSafeMode == true) {
2943                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2944            }
2945            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2946                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2947            }
2948            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2949                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2950            }
2951            if ("1".equals(SystemProperties.get("debug.assert"))) {
2952                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2953            }
2954
2955            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2956            if (requiredAbi == null) {
2957                requiredAbi = Build.SUPPORTED_ABIS[0];
2958            }
2959
2960            String instructionSet = null;
2961            if (app.info.primaryCpuAbi != null) {
2962                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2963            }
2964
2965            // Start the process.  It will either succeed and return a result containing
2966            // the PID of the new process, or else throw a RuntimeException.
2967            boolean isActivityProcess = (entryPoint == null);
2968            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2969            checkTime(startTime, "startProcess: asking zygote to start proc");
2970            Process.ProcessStartResult startResult = Process.start(entryPoint,
2971                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2972                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2973                    app.info.dataDir, entryPointArgs);
2974            checkTime(startTime, "startProcess: returned from zygote!");
2975
2976            if (app.isolated) {
2977                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2978            }
2979            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2980            checkTime(startTime, "startProcess: done updating battery stats");
2981
2982            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2983                    UserHandle.getUserId(uid), startResult.pid, uid,
2984                    app.processName, hostingType,
2985                    hostingNameStr != null ? hostingNameStr : "");
2986
2987            if (app.persistent) {
2988                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2989            }
2990
2991            checkTime(startTime, "startProcess: building log message");
2992            StringBuilder buf = mStringBuilder;
2993            buf.setLength(0);
2994            buf.append("Start proc ");
2995            buf.append(app.processName);
2996            if (!isActivityProcess) {
2997                buf.append(" [");
2998                buf.append(entryPoint);
2999                buf.append("]");
3000            }
3001            buf.append(" for ");
3002            buf.append(hostingType);
3003            if (hostingNameStr != null) {
3004                buf.append(" ");
3005                buf.append(hostingNameStr);
3006            }
3007            buf.append(": pid=");
3008            buf.append(startResult.pid);
3009            buf.append(" uid=");
3010            buf.append(uid);
3011            buf.append(" gids={");
3012            if (gids != null) {
3013                for (int gi=0; gi<gids.length; gi++) {
3014                    if (gi != 0) buf.append(", ");
3015                    buf.append(gids[gi]);
3016
3017                }
3018            }
3019            buf.append("}");
3020            if (requiredAbi != null) {
3021                buf.append(" abi=");
3022                buf.append(requiredAbi);
3023            }
3024            Slog.i(TAG, buf.toString());
3025            app.setPid(startResult.pid);
3026            app.usingWrapper = startResult.usingWrapper;
3027            app.removed = false;
3028            app.killed = false;
3029            app.killedByAm = false;
3030            checkTime(startTime, "startProcess: starting to update pids map");
3031            synchronized (mPidsSelfLocked) {
3032                this.mPidsSelfLocked.put(startResult.pid, app);
3033                if (isActivityProcess) {
3034                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3035                    msg.obj = app;
3036                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3037                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3038                }
3039            }
3040            checkTime(startTime, "startProcess: done updating pids map");
3041        } catch (RuntimeException e) {
3042            // XXX do better error recovery.
3043            app.setPid(0);
3044            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3045            if (app.isolated) {
3046                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3047            }
3048            Slog.e(TAG, "Failure starting process " + app.processName, e);
3049        }
3050    }
3051
3052    void updateUsageStats(ActivityRecord component, boolean resumed) {
3053        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3054        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3055        if (resumed) {
3056            if (mUsageStatsService != null) {
3057                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3058                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3059            }
3060            synchronized (stats) {
3061                stats.noteActivityResumedLocked(component.app.uid);
3062            }
3063        } else {
3064            if (mUsageStatsService != null) {
3065                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3066                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3067            }
3068            synchronized (stats) {
3069                stats.noteActivityPausedLocked(component.app.uid);
3070            }
3071        }
3072    }
3073
3074    Intent getHomeIntent() {
3075        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3076        intent.setComponent(mTopComponent);
3077        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3078            intent.addCategory(Intent.CATEGORY_HOME);
3079        }
3080        return intent;
3081    }
3082
3083    boolean startHomeActivityLocked(int userId) {
3084        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3085                && mTopAction == null) {
3086            // We are running in factory test mode, but unable to find
3087            // the factory test app, so just sit around displaying the
3088            // error message and don't try to start anything.
3089            return false;
3090        }
3091        Intent intent = getHomeIntent();
3092        ActivityInfo aInfo =
3093            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3094        if (aInfo != null) {
3095            intent.setComponent(new ComponentName(
3096                    aInfo.applicationInfo.packageName, aInfo.name));
3097            // Don't do this if the home app is currently being
3098            // instrumented.
3099            aInfo = new ActivityInfo(aInfo);
3100            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3101            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3102                    aInfo.applicationInfo.uid, true);
3103            if (app == null || app.instrumentationClass == null) {
3104                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3105                mStackSupervisor.startHomeActivity(intent, aInfo);
3106            }
3107        }
3108
3109        return true;
3110    }
3111
3112    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3113        ActivityInfo ai = null;
3114        ComponentName comp = intent.getComponent();
3115        try {
3116            if (comp != null) {
3117                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3118            } else {
3119                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3120                        intent,
3121                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3122                            flags, userId);
3123
3124                if (info != null) {
3125                    ai = info.activityInfo;
3126                }
3127            }
3128        } catch (RemoteException e) {
3129            // ignore
3130        }
3131
3132        return ai;
3133    }
3134
3135    /**
3136     * Starts the "new version setup screen" if appropriate.
3137     */
3138    void startSetupActivityLocked() {
3139        // Only do this once per boot.
3140        if (mCheckedForSetup) {
3141            return;
3142        }
3143
3144        // We will show this screen if the current one is a different
3145        // version than the last one shown, and we are not running in
3146        // low-level factory test mode.
3147        final ContentResolver resolver = mContext.getContentResolver();
3148        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3149                Settings.Global.getInt(resolver,
3150                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3151            mCheckedForSetup = true;
3152
3153            // See if we should be showing the platform update setup UI.
3154            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3155            List<ResolveInfo> ris = mContext.getPackageManager()
3156                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3157
3158            // We don't allow third party apps to replace this.
3159            ResolveInfo ri = null;
3160            for (int i=0; ris != null && i<ris.size(); i++) {
3161                if ((ris.get(i).activityInfo.applicationInfo.flags
3162                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3163                    ri = ris.get(i);
3164                    break;
3165                }
3166            }
3167
3168            if (ri != null) {
3169                String vers = ri.activityInfo.metaData != null
3170                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3171                        : null;
3172                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3173                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3174                            Intent.METADATA_SETUP_VERSION);
3175                }
3176                String lastVers = Settings.Secure.getString(
3177                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3178                if (vers != null && !vers.equals(lastVers)) {
3179                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3180                    intent.setComponent(new ComponentName(
3181                            ri.activityInfo.packageName, ri.activityInfo.name));
3182                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3183                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3184                            null);
3185                }
3186            }
3187        }
3188    }
3189
3190    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3191        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3192    }
3193
3194    void enforceNotIsolatedCaller(String caller) {
3195        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3196            throw new SecurityException("Isolated process not allowed to call " + caller);
3197        }
3198    }
3199
3200    void enforceShellRestriction(String restriction, int userHandle) {
3201        if (Binder.getCallingUid() == Process.SHELL_UID) {
3202            if (userHandle < 0
3203                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3204                throw new SecurityException("Shell does not have permission to access user "
3205                        + userHandle);
3206            }
3207        }
3208    }
3209
3210    @Override
3211    public int getFrontActivityScreenCompatMode() {
3212        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3213        synchronized (this) {
3214            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3215        }
3216    }
3217
3218    @Override
3219    public void setFrontActivityScreenCompatMode(int mode) {
3220        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3221                "setFrontActivityScreenCompatMode");
3222        synchronized (this) {
3223            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3224        }
3225    }
3226
3227    @Override
3228    public int getPackageScreenCompatMode(String packageName) {
3229        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3230        synchronized (this) {
3231            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3232        }
3233    }
3234
3235    @Override
3236    public void setPackageScreenCompatMode(String packageName, int mode) {
3237        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3238                "setPackageScreenCompatMode");
3239        synchronized (this) {
3240            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3241        }
3242    }
3243
3244    @Override
3245    public boolean getPackageAskScreenCompat(String packageName) {
3246        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3247        synchronized (this) {
3248            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3249        }
3250    }
3251
3252    @Override
3253    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3254        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3255                "setPackageAskScreenCompat");
3256        synchronized (this) {
3257            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3258        }
3259    }
3260
3261    private void dispatchProcessesChanged() {
3262        int N;
3263        synchronized (this) {
3264            N = mPendingProcessChanges.size();
3265            if (mActiveProcessChanges.length < N) {
3266                mActiveProcessChanges = new ProcessChangeItem[N];
3267            }
3268            mPendingProcessChanges.toArray(mActiveProcessChanges);
3269            mAvailProcessChanges.addAll(mPendingProcessChanges);
3270            mPendingProcessChanges.clear();
3271            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3272        }
3273
3274        int i = mProcessObservers.beginBroadcast();
3275        while (i > 0) {
3276            i--;
3277            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3278            if (observer != null) {
3279                try {
3280                    for (int j=0; j<N; j++) {
3281                        ProcessChangeItem item = mActiveProcessChanges[j];
3282                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3283                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3284                                    + item.pid + " uid=" + item.uid + ": "
3285                                    + item.foregroundActivities);
3286                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3287                                    item.foregroundActivities);
3288                        }
3289                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3290                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3291                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3292                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3293                        }
3294                    }
3295                } catch (RemoteException e) {
3296                }
3297            }
3298        }
3299        mProcessObservers.finishBroadcast();
3300    }
3301
3302    private void dispatchProcessDied(int pid, int uid) {
3303        int i = mProcessObservers.beginBroadcast();
3304        while (i > 0) {
3305            i--;
3306            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3307            if (observer != null) {
3308                try {
3309                    observer.onProcessDied(pid, uid);
3310                } catch (RemoteException e) {
3311                }
3312            }
3313        }
3314        mProcessObservers.finishBroadcast();
3315    }
3316
3317    @Override
3318    public final int startActivity(IApplicationThread caller, String callingPackage,
3319            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3320            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3321        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3322            resultWho, requestCode, startFlags, profilerInfo, options,
3323            UserHandle.getCallingUserId());
3324    }
3325
3326    @Override
3327    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3329            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3330        enforceNotIsolatedCaller("startActivity");
3331        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3332                false, ALLOW_FULL_ONLY, "startActivity", null);
3333        // TODO: Switch to user app stacks here.
3334        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3335                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3336                profilerInfo, null, null, options, userId, null, null);
3337    }
3338
3339    @Override
3340    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3341            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3342            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3343
3344        // This is very dangerous -- it allows you to perform a start activity (including
3345        // permission grants) as any app that may launch one of your own activities.  So
3346        // we will only allow this to be done from activities that are part of the core framework,
3347        // and then only when they are running as the system.
3348        final ActivityRecord sourceRecord;
3349        final int targetUid;
3350        final String targetPackage;
3351        synchronized (this) {
3352            if (resultTo == null) {
3353                throw new SecurityException("Must be called from an activity");
3354            }
3355            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3356            if (sourceRecord == null) {
3357                throw new SecurityException("Called with bad activity token: " + resultTo);
3358            }
3359            if (!sourceRecord.info.packageName.equals("android")) {
3360                throw new SecurityException(
3361                        "Must be called from an activity that is declared in the android package");
3362            }
3363            if (sourceRecord.app == null) {
3364                throw new SecurityException("Called without a process attached to activity");
3365            }
3366            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3367                // This is still okay, as long as this activity is running under the
3368                // uid of the original calling activity.
3369                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3370                    throw new SecurityException(
3371                            "Calling activity in uid " + sourceRecord.app.uid
3372                                    + " must be system uid or original calling uid "
3373                                    + sourceRecord.launchedFromUid);
3374                }
3375            }
3376            targetUid = sourceRecord.launchedFromUid;
3377            targetPackage = sourceRecord.launchedFromPackage;
3378        }
3379
3380        if (userId == UserHandle.USER_NULL) {
3381            userId = UserHandle.getUserId(sourceRecord.app.uid);
3382        }
3383
3384        // TODO: Switch to user app stacks here.
3385        try {
3386            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3387                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3388                    null, null, options, userId, null, null);
3389            return ret;
3390        } catch (SecurityException e) {
3391            // XXX need to figure out how to propagate to original app.
3392            // A SecurityException here is generally actually a fault of the original
3393            // calling activity (such as a fairly granting permissions), so propagate it
3394            // back to them.
3395            /*
3396            StringBuilder msg = new StringBuilder();
3397            msg.append("While launching");
3398            msg.append(intent.toString());
3399            msg.append(": ");
3400            msg.append(e.getMessage());
3401            */
3402            throw e;
3403        }
3404    }
3405
3406    @Override
3407    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3408            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3409            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3410        enforceNotIsolatedCaller("startActivityAndWait");
3411        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3412                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3413        WaitResult res = new WaitResult();
3414        // TODO: Switch to user app stacks here.
3415        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3416                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3417                options, userId, null, null);
3418        return res;
3419    }
3420
3421    @Override
3422    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3423            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3424            int startFlags, Configuration config, Bundle options, int userId) {
3425        enforceNotIsolatedCaller("startActivityWithConfig");
3426        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3427                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3428        // TODO: Switch to user app stacks here.
3429        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3430                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3431                null, null, config, options, userId, null, null);
3432        return ret;
3433    }
3434
3435    @Override
3436    public int startActivityIntentSender(IApplicationThread caller,
3437            IntentSender intent, Intent fillInIntent, String resolvedType,
3438            IBinder resultTo, String resultWho, int requestCode,
3439            int flagsMask, int flagsValues, Bundle options) {
3440        enforceNotIsolatedCaller("startActivityIntentSender");
3441        // Refuse possible leaked file descriptors
3442        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3443            throw new IllegalArgumentException("File descriptors passed in Intent");
3444        }
3445
3446        IIntentSender sender = intent.getTarget();
3447        if (!(sender instanceof PendingIntentRecord)) {
3448            throw new IllegalArgumentException("Bad PendingIntent object");
3449        }
3450
3451        PendingIntentRecord pir = (PendingIntentRecord)sender;
3452
3453        synchronized (this) {
3454            // If this is coming from the currently resumed activity, it is
3455            // effectively saying that app switches are allowed at this point.
3456            final ActivityStack stack = getFocusedStack();
3457            if (stack.mResumedActivity != null &&
3458                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3459                mAppSwitchesAllowedTime = 0;
3460            }
3461        }
3462        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3463                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3469            Intent intent, String resolvedType, IVoiceInteractionSession session,
3470            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3471            Bundle options, int userId) {
3472        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3473                != PackageManager.PERMISSION_GRANTED) {
3474            String msg = "Permission Denial: startVoiceActivity() from pid="
3475                    + Binder.getCallingPid()
3476                    + ", uid=" + Binder.getCallingUid()
3477                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3478            Slog.w(TAG, msg);
3479            throw new SecurityException(msg);
3480        }
3481        if (session == null || interactor == null) {
3482            throw new NullPointerException("null session or interactor");
3483        }
3484        userId = handleIncomingUser(callingPid, callingUid, userId,
3485                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3486        // TODO: Switch to user app stacks here.
3487        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3488                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3489                null, options, userId, null, null);
3490    }
3491
3492    @Override
3493    public boolean startNextMatchingActivity(IBinder callingActivity,
3494            Intent intent, Bundle options) {
3495        // Refuse possible leaked file descriptors
3496        if (intent != null && intent.hasFileDescriptors() == true) {
3497            throw new IllegalArgumentException("File descriptors passed in Intent");
3498        }
3499
3500        synchronized (this) {
3501            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3502            if (r == null) {
3503                ActivityOptions.abort(options);
3504                return false;
3505            }
3506            if (r.app == null || r.app.thread == null) {
3507                // The caller is not running...  d'oh!
3508                ActivityOptions.abort(options);
3509                return false;
3510            }
3511            intent = new Intent(intent);
3512            // The caller is not allowed to change the data.
3513            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3514            // And we are resetting to find the next component...
3515            intent.setComponent(null);
3516
3517            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3518
3519            ActivityInfo aInfo = null;
3520            try {
3521                List<ResolveInfo> resolves =
3522                    AppGlobals.getPackageManager().queryIntentActivities(
3523                            intent, r.resolvedType,
3524                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3525                            UserHandle.getCallingUserId());
3526
3527                // Look for the original activity in the list...
3528                final int N = resolves != null ? resolves.size() : 0;
3529                for (int i=0; i<N; i++) {
3530                    ResolveInfo rInfo = resolves.get(i);
3531                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3532                            && rInfo.activityInfo.name.equals(r.info.name)) {
3533                        // We found the current one...  the next matching is
3534                        // after it.
3535                        i++;
3536                        if (i<N) {
3537                            aInfo = resolves.get(i).activityInfo;
3538                        }
3539                        if (debug) {
3540                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3541                                    + "/" + r.info.name);
3542                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3543                                    + "/" + aInfo.name);
3544                        }
3545                        break;
3546                    }
3547                }
3548            } catch (RemoteException e) {
3549            }
3550
3551            if (aInfo == null) {
3552                // Nobody who is next!
3553                ActivityOptions.abort(options);
3554                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3555                return false;
3556            }
3557
3558            intent.setComponent(new ComponentName(
3559                    aInfo.applicationInfo.packageName, aInfo.name));
3560            intent.setFlags(intent.getFlags()&~(
3561                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3562                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3563                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3564                    Intent.FLAG_ACTIVITY_NEW_TASK));
3565
3566            // Okay now we need to start the new activity, replacing the
3567            // currently running activity.  This is a little tricky because
3568            // we want to start the new one as if the current one is finished,
3569            // but not finish the current one first so that there is no flicker.
3570            // And thus...
3571            final boolean wasFinishing = r.finishing;
3572            r.finishing = true;
3573
3574            // Propagate reply information over to the new activity.
3575            final ActivityRecord resultTo = r.resultTo;
3576            final String resultWho = r.resultWho;
3577            final int requestCode = r.requestCode;
3578            r.resultTo = null;
3579            if (resultTo != null) {
3580                resultTo.removeResultsLocked(r, resultWho, requestCode);
3581            }
3582
3583            final long origId = Binder.clearCallingIdentity();
3584            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3585                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3586                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3587                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3588            Binder.restoreCallingIdentity(origId);
3589
3590            r.finishing = wasFinishing;
3591            if (res != ActivityManager.START_SUCCESS) {
3592                return false;
3593            }
3594            return true;
3595        }
3596    }
3597
3598    @Override
3599    public final int startActivityFromRecents(int taskId, Bundle options) {
3600        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3601            String msg = "Permission Denial: startActivityFromRecents called without " +
3602                    START_TASKS_FROM_RECENTS;
3603            Slog.w(TAG, msg);
3604            throw new SecurityException(msg);
3605        }
3606        return startActivityFromRecentsInner(taskId, options);
3607    }
3608
3609    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3610        final TaskRecord task;
3611        final int callingUid;
3612        final String callingPackage;
3613        final Intent intent;
3614        final int userId;
3615        synchronized (this) {
3616            task = recentTaskForIdLocked(taskId);
3617            if (task == null) {
3618                throw new IllegalArgumentException("Task " + taskId + " not found.");
3619            }
3620            callingUid = task.mCallingUid;
3621            callingPackage = task.mCallingPackage;
3622            intent = task.intent;
3623            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3624            userId = task.userId;
3625        }
3626        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3627                options, userId, null, task);
3628    }
3629
3630    final int startActivityInPackage(int uid, String callingPackage,
3631            Intent intent, String resolvedType, IBinder resultTo,
3632            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3633            IActivityContainer container, TaskRecord inTask) {
3634
3635        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3636                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3637
3638        // TODO: Switch to user app stacks here.
3639        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3640                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3641                null, null, null, options, userId, container, inTask);
3642        return ret;
3643    }
3644
3645    @Override
3646    public final int startActivities(IApplicationThread caller, String callingPackage,
3647            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3648            int userId) {
3649        enforceNotIsolatedCaller("startActivities");
3650        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3651                false, ALLOW_FULL_ONLY, "startActivity", null);
3652        // TODO: Switch to user app stacks here.
3653        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3654                resolvedTypes, resultTo, options, userId);
3655        return ret;
3656    }
3657
3658    final int startActivitiesInPackage(int uid, String callingPackage,
3659            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3660            Bundle options, int userId) {
3661
3662        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3663                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3664        // TODO: Switch to user app stacks here.
3665        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3666                resultTo, options, userId);
3667        return ret;
3668    }
3669
3670    //explicitly remove thd old information in mRecentTasks when removing existing user.
3671    private void removeRecentTasksForUserLocked(int userId) {
3672        if(userId <= 0) {
3673            Slog.i(TAG, "Can't remove recent task on user " + userId);
3674            return;
3675        }
3676
3677        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3678            TaskRecord tr = mRecentTasks.get(i);
3679            if (tr.userId == userId) {
3680                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3681                        + " when finishing user" + userId);
3682                mRecentTasks.remove(i);
3683                tr.removedFromRecents();
3684            }
3685        }
3686
3687        // Remove tasks from persistent storage.
3688        notifyTaskPersisterLocked(null, true);
3689    }
3690
3691    // Sort by taskId
3692    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3693        @Override
3694        public int compare(TaskRecord lhs, TaskRecord rhs) {
3695            return rhs.taskId - lhs.taskId;
3696        }
3697    };
3698
3699    // Extract the affiliates of the chain containing mRecentTasks[start].
3700    private int processNextAffiliateChainLocked(int start) {
3701        final TaskRecord startTask = mRecentTasks.get(start);
3702        final int affiliateId = startTask.mAffiliatedTaskId;
3703
3704        // Quick identification of isolated tasks. I.e. those not launched behind.
3705        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3706                startTask.mNextAffiliate == null) {
3707            // There is still a slim chance that there are other tasks that point to this task
3708            // and that the chain is so messed up that this task no longer points to them but
3709            // the gain of this optimization outweighs the risk.
3710            startTask.inRecents = true;
3711            return start + 1;
3712        }
3713
3714        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3715        mTmpRecents.clear();
3716        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3717            final TaskRecord task = mRecentTasks.get(i);
3718            if (task.mAffiliatedTaskId == affiliateId) {
3719                mRecentTasks.remove(i);
3720                mTmpRecents.add(task);
3721            }
3722        }
3723
3724        // Sort them all by taskId. That is the order they were create in and that order will
3725        // always be correct.
3726        Collections.sort(mTmpRecents, mTaskRecordComparator);
3727
3728        // Go through and fix up the linked list.
3729        // The first one is the end of the chain and has no next.
3730        final TaskRecord first = mTmpRecents.get(0);
3731        first.inRecents = true;
3732        if (first.mNextAffiliate != null) {
3733            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3734            first.setNextAffiliate(null);
3735            notifyTaskPersisterLocked(first, false);
3736        }
3737        // Everything in the middle is doubly linked from next to prev.
3738        final int tmpSize = mTmpRecents.size();
3739        for (int i = 0; i < tmpSize - 1; ++i) {
3740            final TaskRecord next = mTmpRecents.get(i);
3741            final TaskRecord prev = mTmpRecents.get(i + 1);
3742            if (next.mPrevAffiliate != prev) {
3743                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3744                        " setting prev=" + prev);
3745                next.setPrevAffiliate(prev);
3746                notifyTaskPersisterLocked(next, false);
3747            }
3748            if (prev.mNextAffiliate != next) {
3749                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3750                        " setting next=" + next);
3751                prev.setNextAffiliate(next);
3752                notifyTaskPersisterLocked(prev, false);
3753            }
3754            prev.inRecents = true;
3755        }
3756        // The last one is the beginning of the list and has no prev.
3757        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3758        if (last.mPrevAffiliate != null) {
3759            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3760            last.setPrevAffiliate(null);
3761            notifyTaskPersisterLocked(last, false);
3762        }
3763
3764        // Insert the group back into mRecentTasks at start.
3765        mRecentTasks.addAll(start, mTmpRecents);
3766
3767        // Let the caller know where we left off.
3768        return start + tmpSize;
3769    }
3770
3771    /**
3772     * Update the recent tasks lists: make sure tasks should still be here (their
3773     * applications / activities still exist), update their availability, fixup ordering
3774     * of affiliations.
3775     */
3776    void cleanupRecentTasksLocked(int userId) {
3777        if (mRecentTasks == null) {
3778            // Happens when called from the packagemanager broadcast before boot.
3779            return;
3780        }
3781
3782        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3783        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3784        final IPackageManager pm = AppGlobals.getPackageManager();
3785        final ActivityInfo dummyAct = new ActivityInfo();
3786        final ApplicationInfo dummyApp = new ApplicationInfo();
3787
3788        int N = mRecentTasks.size();
3789
3790        int[] users = userId == UserHandle.USER_ALL
3791                ? getUsersLocked() : new int[] { userId };
3792        for (int user : users) {
3793            for (int i = 0; i < N; i++) {
3794                TaskRecord task = mRecentTasks.get(i);
3795                if (task.userId != user) {
3796                    // Only look at tasks for the user ID of interest.
3797                    continue;
3798                }
3799                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3800                    // This situation is broken, and we should just get rid of it now.
3801                    mRecentTasks.remove(i);
3802                    task.removedFromRecents();
3803                    i--;
3804                    N--;
3805                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3806                    continue;
3807                }
3808                // Check whether this activity is currently available.
3809                if (task.realActivity != null) {
3810                    ActivityInfo ai = availActCache.get(task.realActivity);
3811                    if (ai == null) {
3812                        try {
3813                            ai = pm.getActivityInfo(task.realActivity,
3814                                    PackageManager.GET_UNINSTALLED_PACKAGES
3815                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3816                        } catch (RemoteException e) {
3817                            // Will never happen.
3818                            continue;
3819                        }
3820                        if (ai == null) {
3821                            ai = dummyAct;
3822                        }
3823                        availActCache.put(task.realActivity, ai);
3824                    }
3825                    if (ai == dummyAct) {
3826                        // This could be either because the activity no longer exists, or the
3827                        // app is temporarily gone.  For the former we want to remove the recents
3828                        // entry; for the latter we want to mark it as unavailable.
3829                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3830                        if (app == null) {
3831                            try {
3832                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3833                                        PackageManager.GET_UNINSTALLED_PACKAGES
3834                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3835                            } catch (RemoteException e) {
3836                                // Will never happen.
3837                                continue;
3838                            }
3839                            if (app == null) {
3840                                app = dummyApp;
3841                            }
3842                            availAppCache.put(task.realActivity.getPackageName(), app);
3843                        }
3844                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3845                            // Doesn't exist any more!  Good-bye.
3846                            mRecentTasks.remove(i);
3847                            task.removedFromRecents();
3848                            i--;
3849                            N--;
3850                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3851                            continue;
3852                        } else {
3853                            // Otherwise just not available for now.
3854                            if (task.isAvailable) {
3855                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3856                                        + task);
3857                            }
3858                            task.isAvailable = false;
3859                        }
3860                    } else {
3861                        if (!ai.enabled || !ai.applicationInfo.enabled
3862                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3863                            if (task.isAvailable) {
3864                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3865                                        + task + " (enabled=" + ai.enabled + "/"
3866                                        + ai.applicationInfo.enabled +  " flags="
3867                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3868                            }
3869                            task.isAvailable = false;
3870                        } else {
3871                            if (!task.isAvailable) {
3872                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3873                                        + task);
3874                            }
3875                            task.isAvailable = true;
3876                        }
3877                    }
3878                }
3879            }
3880        }
3881
3882        // Verify the affiliate chain for each task.
3883        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3884        }
3885
3886        mTmpRecents.clear();
3887        // mRecentTasks is now in sorted, affiliated order.
3888    }
3889
3890    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3891        int N = mRecentTasks.size();
3892        TaskRecord top = task;
3893        int topIndex = taskIndex;
3894        while (top.mNextAffiliate != null && topIndex > 0) {
3895            top = top.mNextAffiliate;
3896            topIndex--;
3897        }
3898        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3899                + topIndex + " from intial " + taskIndex);
3900        // Find the end of the chain, doing a sanity check along the way.
3901        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3902        int endIndex = topIndex;
3903        TaskRecord prev = top;
3904        while (endIndex < N) {
3905            TaskRecord cur = mRecentTasks.get(endIndex);
3906            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3907                    + endIndex + " " + cur);
3908            if (cur == top) {
3909                // Verify start of the chain.
3910                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3911                    Slog.wtf(TAG, "Bad chain @" + endIndex
3912                            + ": first task has next affiliate: " + prev);
3913                    sane = false;
3914                    break;
3915                }
3916            } else {
3917                // Verify middle of the chain's next points back to the one before.
3918                if (cur.mNextAffiliate != prev
3919                        || cur.mNextAffiliateTaskId != prev.taskId) {
3920                    Slog.wtf(TAG, "Bad chain @" + endIndex
3921                            + ": middle task " + cur + " @" + endIndex
3922                            + " has bad next affiliate "
3923                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3924                            + ", expected " + prev);
3925                    sane = false;
3926                    break;
3927                }
3928            }
3929            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3930                // Chain ends here.
3931                if (cur.mPrevAffiliate != null) {
3932                    Slog.wtf(TAG, "Bad chain @" + endIndex
3933                            + ": last task " + cur + " has previous affiliate "
3934                            + cur.mPrevAffiliate);
3935                    sane = false;
3936                }
3937                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3938                break;
3939            } else {
3940                // Verify middle of the chain's prev points to a valid item.
3941                if (cur.mPrevAffiliate == null) {
3942                    Slog.wtf(TAG, "Bad chain @" + endIndex
3943                            + ": task " + cur + " has previous affiliate "
3944                            + cur.mPrevAffiliate + " but should be id "
3945                            + cur.mPrevAffiliate);
3946                    sane = false;
3947                    break;
3948                }
3949            }
3950            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3951                Slog.wtf(TAG, "Bad chain @" + endIndex
3952                        + ": task " + cur + " has affiliated id "
3953                        + cur.mAffiliatedTaskId + " but should be "
3954                        + task.mAffiliatedTaskId);
3955                sane = false;
3956                break;
3957            }
3958            prev = cur;
3959            endIndex++;
3960            if (endIndex >= N) {
3961                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3962                        + ": last task " + prev);
3963                sane = false;
3964                break;
3965            }
3966        }
3967        if (sane) {
3968            if (endIndex < taskIndex) {
3969                Slog.wtf(TAG, "Bad chain @" + endIndex
3970                        + ": did not extend to task " + task + " @" + taskIndex);
3971                sane = false;
3972            }
3973        }
3974        if (sane) {
3975            // All looks good, we can just move all of the affiliated tasks
3976            // to the top.
3977            for (int i=topIndex; i<=endIndex; i++) {
3978                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3979                        + " from " + i + " to " + (i-topIndex));
3980                TaskRecord cur = mRecentTasks.remove(i);
3981                mRecentTasks.add(i-topIndex, cur);
3982            }
3983            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3984                    + " to " + endIndex);
3985            return true;
3986        }
3987
3988        // Whoops, couldn't do it.
3989        return false;
3990    }
3991
3992    final void addRecentTaskLocked(TaskRecord task) {
3993        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3994                || task.mNextAffiliateTaskId != INVALID_TASK_ID
3995                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
3996
3997        int N = mRecentTasks.size();
3998        // Quick case: check if the top-most recent task is the same.
3999        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4000            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4001            return;
4002        }
4003        // Another quick case: check if this is part of a set of affiliated
4004        // tasks that are at the top.
4005        if (isAffiliated && N > 0 && task.inRecents
4006                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4007            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4008                    + " at top when adding " + task);
4009            return;
4010        }
4011        // Another quick case: never add voice sessions.
4012        if (task.voiceSession != null) {
4013            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4014            return;
4015        }
4016
4017        boolean needAffiliationFix = false;
4018
4019        // Slightly less quick case: the task is already in recents, so all we need
4020        // to do is move it.
4021        if (task.inRecents) {
4022            int taskIndex = mRecentTasks.indexOf(task);
4023            if (taskIndex >= 0) {
4024                if (!isAffiliated) {
4025                    // Simple case: this is not an affiliated task, so we just move it to the front.
4026                    mRecentTasks.remove(taskIndex);
4027                    mRecentTasks.add(0, task);
4028                    notifyTaskPersisterLocked(task, false);
4029                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4030                            + " from " + taskIndex);
4031                    return;
4032                } else {
4033                    // More complicated: need to keep all affiliated tasks together.
4034                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4035                        // All went well.
4036                        return;
4037                    }
4038
4039                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4040                    // everything and then go through our general path of adding a new task.
4041                    needAffiliationFix = true;
4042                }
4043            } else {
4044                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4045                needAffiliationFix = true;
4046            }
4047        }
4048
4049        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4050        trimRecentsForTaskLocked(task, true);
4051
4052        N = mRecentTasks.size();
4053        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4054            final TaskRecord tr = mRecentTasks.remove(N - 1);
4055            tr.removedFromRecents();
4056            N--;
4057        }
4058        task.inRecents = true;
4059        if (!isAffiliated || needAffiliationFix) {
4060            // If this is a simple non-affiliated task, or we had some failure trying to
4061            // handle it as part of an affilated task, then just place it at the top.
4062            mRecentTasks.add(0, task);
4063        } else if (isAffiliated) {
4064            // If this is a new affiliated task, then move all of the affiliated tasks
4065            // to the front and insert this new one.
4066            TaskRecord other = task.mNextAffiliate;
4067            if (other == null) {
4068                other = task.mPrevAffiliate;
4069            }
4070            if (other != null) {
4071                int otherIndex = mRecentTasks.indexOf(other);
4072                if (otherIndex >= 0) {
4073                    // Insert new task at appropriate location.
4074                    int taskIndex;
4075                    if (other == task.mNextAffiliate) {
4076                        // We found the index of our next affiliation, which is who is
4077                        // before us in the list, so add after that point.
4078                        taskIndex = otherIndex+1;
4079                    } else {
4080                        // We found the index of our previous affiliation, which is who is
4081                        // after us in the list, so add at their position.
4082                        taskIndex = otherIndex;
4083                    }
4084                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4085                            + taskIndex + ": " + task);
4086                    mRecentTasks.add(taskIndex, task);
4087
4088                    // Now move everything to the front.
4089                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4090                        // All went well.
4091                        return;
4092                    }
4093
4094                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4095                    // everything and then go through our general path of adding a new task.
4096                    needAffiliationFix = true;
4097                } else {
4098                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4099                            + other);
4100                    needAffiliationFix = true;
4101                }
4102            } else {
4103                if (DEBUG_RECENTS) Slog.d(TAG,
4104                        "addRecent: adding affiliated task without next/prev:" + task);
4105                needAffiliationFix = true;
4106            }
4107        }
4108        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4109
4110        if (needAffiliationFix) {
4111            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4112            cleanupRecentTasksLocked(task.userId);
4113        }
4114    }
4115
4116    /**
4117     * If needed, remove oldest existing entries in recents that are for the same kind
4118     * of task as the given one.
4119     */
4120    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4121        int N = mRecentTasks.size();
4122        final Intent intent = task.intent;
4123        final boolean document = intent != null && intent.isDocument();
4124
4125        int maxRecents = task.maxRecents - 1;
4126        for (int i=0; i<N; i++) {
4127            final TaskRecord tr = mRecentTasks.get(i);
4128            if (task != tr) {
4129                if (task.userId != tr.userId) {
4130                    continue;
4131                }
4132                if (i > MAX_RECENT_BITMAPS) {
4133                    tr.freeLastThumbnail();
4134                }
4135                final Intent trIntent = tr.intent;
4136                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4137                    (intent == null || !intent.filterEquals(trIntent))) {
4138                    continue;
4139                }
4140                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4141                if (document && trIsDocument) {
4142                    // These are the same document activity (not necessarily the same doc).
4143                    if (maxRecents > 0) {
4144                        --maxRecents;
4145                        continue;
4146                    }
4147                    // Hit the maximum number of documents for this task. Fall through
4148                    // and remove this document from recents.
4149                } else if (document || trIsDocument) {
4150                    // Only one of these is a document. Not the droid we're looking for.
4151                    continue;
4152                }
4153            }
4154
4155            if (!doTrim) {
4156                // If the caller is not actually asking for a trim, just tell them we reached
4157                // a point where the trim would happen.
4158                return i;
4159            }
4160
4161            // Either task and tr are the same or, their affinities match or their intents match
4162            // and neither of them is a document, or they are documents using the same activity
4163            // and their maxRecents has been reached.
4164            tr.disposeThumbnail();
4165            mRecentTasks.remove(i);
4166            if (task != tr) {
4167                tr.removedFromRecents();
4168            }
4169            i--;
4170            N--;
4171            if (task.intent == null) {
4172                // If the new recent task we are adding is not fully
4173                // specified, then replace it with the existing recent task.
4174                task = tr;
4175            }
4176            notifyTaskPersisterLocked(tr, false);
4177        }
4178
4179        return -1;
4180    }
4181
4182    @Override
4183    public void reportActivityFullyDrawn(IBinder token) {
4184        synchronized (this) {
4185            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4186            if (r == null) {
4187                return;
4188            }
4189            r.reportFullyDrawnLocked();
4190        }
4191    }
4192
4193    @Override
4194    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4195        synchronized (this) {
4196            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4197            if (r == null) {
4198                return;
4199            }
4200            final long origId = Binder.clearCallingIdentity();
4201            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4202            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4203                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4204            if (config != null) {
4205                r.frozenBeforeDestroy = true;
4206                if (!updateConfigurationLocked(config, r, false, false)) {
4207                    mStackSupervisor.resumeTopActivitiesLocked();
4208                }
4209            }
4210            Binder.restoreCallingIdentity(origId);
4211        }
4212    }
4213
4214    @Override
4215    public int getRequestedOrientation(IBinder token) {
4216        synchronized (this) {
4217            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4218            if (r == null) {
4219                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4220            }
4221            return mWindowManager.getAppOrientation(r.appToken);
4222        }
4223    }
4224
4225    /**
4226     * This is the internal entry point for handling Activity.finish().
4227     *
4228     * @param token The Binder token referencing the Activity we want to finish.
4229     * @param resultCode Result code, if any, from this Activity.
4230     * @param resultData Result data (Intent), if any, from this Activity.
4231     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4232     *            the root Activity in the task.
4233     *
4234     * @return Returns true if the activity successfully finished, or false if it is still running.
4235     */
4236    @Override
4237    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4238            boolean finishTask) {
4239        // Refuse possible leaked file descriptors
4240        if (resultData != null && resultData.hasFileDescriptors() == true) {
4241            throw new IllegalArgumentException("File descriptors passed in Intent");
4242        }
4243
4244        synchronized(this) {
4245            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4246            if (r == null) {
4247                return true;
4248            }
4249            // Keep track of the root activity of the task before we finish it
4250            TaskRecord tr = r.task;
4251            ActivityRecord rootR = tr.getRootActivity();
4252            if (rootR == null) {
4253                Slog.w(TAG, "Finishing task with all activities already finished");
4254            }
4255            // Do not allow task to finish in Lock Task mode.
4256            if (tr == mStackSupervisor.mLockTaskModeTask) {
4257                if (rootR == r) {
4258                    Slog.i(TAG, "Not finishing task in lock task mode");
4259                    mStackSupervisor.showLockTaskToast();
4260                    return false;
4261                }
4262            }
4263            if (mController != null) {
4264                // Find the first activity that is not finishing.
4265                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4266                if (next != null) {
4267                    // ask watcher if this is allowed
4268                    boolean resumeOK = true;
4269                    try {
4270                        resumeOK = mController.activityResuming(next.packageName);
4271                    } catch (RemoteException e) {
4272                        mController = null;
4273                        Watchdog.getInstance().setActivityController(null);
4274                    }
4275
4276                    if (!resumeOK) {
4277                        Slog.i(TAG, "Not finishing activity because controller resumed");
4278                        return false;
4279                    }
4280                }
4281            }
4282            final long origId = Binder.clearCallingIdentity();
4283            try {
4284                boolean res;
4285                if (finishTask && r == rootR) {
4286                    // If requested, remove the task that is associated to this activity only if it
4287                    // was the root activity in the task. The result code and data is ignored
4288                    // because we don't support returning them across task boundaries.
4289                    res = removeTaskByIdLocked(tr.taskId, false);
4290                    if (!res) {
4291                        Slog.i(TAG, "Removing task failed to finish activity");
4292                    }
4293                } else {
4294                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4295                            resultData, "app-request", true);
4296                    if (!res) {
4297                        Slog.i(TAG, "Failed to finish by app-request");
4298                    }
4299                }
4300                return res;
4301            } finally {
4302                Binder.restoreCallingIdentity(origId);
4303            }
4304        }
4305    }
4306
4307    @Override
4308    public final void finishHeavyWeightApp() {
4309        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4310                != PackageManager.PERMISSION_GRANTED) {
4311            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4312                    + Binder.getCallingPid()
4313                    + ", uid=" + Binder.getCallingUid()
4314                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4315            Slog.w(TAG, msg);
4316            throw new SecurityException(msg);
4317        }
4318
4319        synchronized(this) {
4320            if (mHeavyWeightProcess == null) {
4321                return;
4322            }
4323
4324            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4325                    mHeavyWeightProcess.activities);
4326            for (int i=0; i<activities.size(); i++) {
4327                ActivityRecord r = activities.get(i);
4328                if (!r.finishing) {
4329                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4330                            null, "finish-heavy", true);
4331                }
4332            }
4333
4334            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4335                    mHeavyWeightProcess.userId, 0));
4336            mHeavyWeightProcess = null;
4337        }
4338    }
4339
4340    @Override
4341    public void crashApplication(int uid, int initialPid, String packageName,
4342            String message) {
4343        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4344                != PackageManager.PERMISSION_GRANTED) {
4345            String msg = "Permission Denial: crashApplication() 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            ProcessRecord proc = null;
4355
4356            // Figure out which process to kill.  We don't trust that initialPid
4357            // still has any relation to current pids, so must scan through the
4358            // list.
4359            synchronized (mPidsSelfLocked) {
4360                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4361                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4362                    if (p.uid != uid) {
4363                        continue;
4364                    }
4365                    if (p.pid == initialPid) {
4366                        proc = p;
4367                        break;
4368                    }
4369                    if (p.pkgList.containsKey(packageName)) {
4370                        proc = p;
4371                    }
4372                }
4373            }
4374
4375            if (proc == null) {
4376                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4377                        + " initialPid=" + initialPid
4378                        + " packageName=" + packageName);
4379                return;
4380            }
4381
4382            if (proc.thread != null) {
4383                if (proc.pid == Process.myPid()) {
4384                    Log.w(TAG, "crashApplication: trying to crash self!");
4385                    return;
4386                }
4387                long ident = Binder.clearCallingIdentity();
4388                try {
4389                    proc.thread.scheduleCrash(message);
4390                } catch (RemoteException e) {
4391                }
4392                Binder.restoreCallingIdentity(ident);
4393            }
4394        }
4395    }
4396
4397    @Override
4398    public final void finishSubActivity(IBinder token, String resultWho,
4399            int requestCode) {
4400        synchronized(this) {
4401            final long origId = Binder.clearCallingIdentity();
4402            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4403            if (r != null) {
4404                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4405            }
4406            Binder.restoreCallingIdentity(origId);
4407        }
4408    }
4409
4410    @Override
4411    public boolean finishActivityAffinity(IBinder token) {
4412        synchronized(this) {
4413            final long origId = Binder.clearCallingIdentity();
4414            try {
4415                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4416
4417                ActivityRecord rootR = r.task.getRootActivity();
4418                // Do not allow task to finish in Lock Task mode.
4419                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4420                    if (rootR == r) {
4421                        mStackSupervisor.showLockTaskToast();
4422                        return false;
4423                    }
4424                }
4425                boolean res = false;
4426                if (r != null) {
4427                    res = r.task.stack.finishActivityAffinityLocked(r);
4428                }
4429                return res;
4430            } finally {
4431                Binder.restoreCallingIdentity(origId);
4432            }
4433        }
4434    }
4435
4436    @Override
4437    public void finishVoiceTask(IVoiceInteractionSession session) {
4438        synchronized(this) {
4439            final long origId = Binder.clearCallingIdentity();
4440            try {
4441                mStackSupervisor.finishVoiceTask(session);
4442            } finally {
4443                Binder.restoreCallingIdentity(origId);
4444            }
4445        }
4446
4447    }
4448
4449    @Override
4450    public boolean releaseActivityInstance(IBinder token) {
4451        synchronized(this) {
4452            final long origId = Binder.clearCallingIdentity();
4453            try {
4454                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4455                if (r.task == null || r.task.stack == null) {
4456                    return false;
4457                }
4458                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4459            } finally {
4460                Binder.restoreCallingIdentity(origId);
4461            }
4462        }
4463    }
4464
4465    @Override
4466    public void releaseSomeActivities(IApplicationThread appInt) {
4467        synchronized(this) {
4468            final long origId = Binder.clearCallingIdentity();
4469            try {
4470                ProcessRecord app = getRecordForAppLocked(appInt);
4471                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4472            } finally {
4473                Binder.restoreCallingIdentity(origId);
4474            }
4475        }
4476    }
4477
4478    @Override
4479    public boolean willActivityBeVisible(IBinder token) {
4480        synchronized(this) {
4481            ActivityStack stack = ActivityRecord.getStackLocked(token);
4482            if (stack != null) {
4483                return stack.willActivityBeVisibleLocked(token);
4484            }
4485            return false;
4486        }
4487    }
4488
4489    @Override
4490    public void overridePendingTransition(IBinder token, String packageName,
4491            int enterAnim, int exitAnim) {
4492        synchronized(this) {
4493            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4494            if (self == null) {
4495                return;
4496            }
4497
4498            final long origId = Binder.clearCallingIdentity();
4499
4500            if (self.state == ActivityState.RESUMED
4501                    || self.state == ActivityState.PAUSING) {
4502                mWindowManager.overridePendingAppTransition(packageName,
4503                        enterAnim, exitAnim, null);
4504            }
4505
4506            Binder.restoreCallingIdentity(origId);
4507        }
4508    }
4509
4510    /**
4511     * Main function for removing an existing process from the activity manager
4512     * as a result of that process going away.  Clears out all connections
4513     * to the process.
4514     */
4515    private final void handleAppDiedLocked(ProcessRecord app,
4516            boolean restarting, boolean allowRestart) {
4517        int pid = app.pid;
4518        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4519        if (!kept && !restarting) {
4520            removeLruProcessLocked(app);
4521            if (pid > 0) {
4522                ProcessList.remove(pid);
4523            }
4524        }
4525
4526        if (mProfileProc == app) {
4527            clearProfilerLocked();
4528        }
4529
4530        // Remove this application's activities from active lists.
4531        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4532
4533        app.activities.clear();
4534
4535        if (app.instrumentationClass != null) {
4536            Slog.w(TAG, "Crash of app " + app.processName
4537                  + " running instrumentation " + app.instrumentationClass);
4538            Bundle info = new Bundle();
4539            info.putString("shortMsg", "Process crashed.");
4540            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4541        }
4542
4543        if (!restarting) {
4544            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4545                // If there was nothing to resume, and we are not already
4546                // restarting this process, but there is a visible activity that
4547                // is hosted by the process...  then make sure all visible
4548                // activities are running, taking care of restarting this
4549                // process.
4550                if (hasVisibleActivities) {
4551                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4552                }
4553            }
4554        }
4555    }
4556
4557    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4558        IBinder threadBinder = thread.asBinder();
4559        // Find the application record.
4560        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4561            ProcessRecord rec = mLruProcesses.get(i);
4562            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4563                return i;
4564            }
4565        }
4566        return -1;
4567    }
4568
4569    final ProcessRecord getRecordForAppLocked(
4570            IApplicationThread thread) {
4571        if (thread == null) {
4572            return null;
4573        }
4574
4575        int appIndex = getLRURecordIndexForAppLocked(thread);
4576        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4577    }
4578
4579    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4580        // If there are no longer any background processes running,
4581        // and the app that died was not running instrumentation,
4582        // then tell everyone we are now low on memory.
4583        boolean haveBg = false;
4584        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4585            ProcessRecord rec = mLruProcesses.get(i);
4586            if (rec.thread != null
4587                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4588                haveBg = true;
4589                break;
4590            }
4591        }
4592
4593        if (!haveBg) {
4594            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4595            if (doReport) {
4596                long now = SystemClock.uptimeMillis();
4597                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4598                    doReport = false;
4599                } else {
4600                    mLastMemUsageReportTime = now;
4601                }
4602            }
4603            final ArrayList<ProcessMemInfo> memInfos
4604                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4605            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4606            long now = SystemClock.uptimeMillis();
4607            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4608                ProcessRecord rec = mLruProcesses.get(i);
4609                if (rec == dyingProc || rec.thread == null) {
4610                    continue;
4611                }
4612                if (doReport) {
4613                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4614                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4615                }
4616                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4617                    // The low memory report is overriding any current
4618                    // state for a GC request.  Make sure to do
4619                    // heavy/important/visible/foreground processes first.
4620                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4621                        rec.lastRequestedGc = 0;
4622                    } else {
4623                        rec.lastRequestedGc = rec.lastLowMemory;
4624                    }
4625                    rec.reportLowMemory = true;
4626                    rec.lastLowMemory = now;
4627                    mProcessesToGc.remove(rec);
4628                    addProcessToGcListLocked(rec);
4629                }
4630            }
4631            if (doReport) {
4632                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4633                mHandler.sendMessage(msg);
4634            }
4635            scheduleAppGcsLocked();
4636        }
4637    }
4638
4639    final void appDiedLocked(ProcessRecord app) {
4640       appDiedLocked(app, app.pid, app.thread);
4641    }
4642
4643    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4644        // First check if this ProcessRecord is actually active for the pid.
4645        synchronized (mPidsSelfLocked) {
4646            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4647            if (curProc != app) {
4648                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4649                return;
4650            }
4651        }
4652
4653        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4654        synchronized (stats) {
4655            stats.noteProcessDiedLocked(app.info.uid, pid);
4656        }
4657
4658        Process.killProcessQuiet(pid);
4659        Process.killProcessGroup(app.info.uid, pid);
4660        app.killed = true;
4661
4662        // Clean up already done if the process has been re-started.
4663        if (app.pid == pid && app.thread != null &&
4664                app.thread.asBinder() == thread.asBinder()) {
4665            boolean doLowMem = app.instrumentationClass == null;
4666            boolean doOomAdj = doLowMem;
4667            if (!app.killedByAm) {
4668                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4669                        + ") has died");
4670                mAllowLowerMemLevel = true;
4671            } else {
4672                // Note that we always want to do oom adj to update our state with the
4673                // new number of procs.
4674                mAllowLowerMemLevel = false;
4675                doLowMem = false;
4676            }
4677            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4678            if (DEBUG_CLEANUP) Slog.v(
4679                TAG, "Dying app: " + app + ", pid: " + pid
4680                + ", thread: " + thread.asBinder());
4681            handleAppDiedLocked(app, false, true);
4682
4683            if (doOomAdj) {
4684                updateOomAdjLocked();
4685            }
4686            if (doLowMem) {
4687                doLowMemReportIfNeededLocked(app);
4688            }
4689        } else if (app.pid != pid) {
4690            // A new process has already been started.
4691            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4692                    + ") has died and restarted (pid " + app.pid + ").");
4693            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4694        } else if (DEBUG_PROCESSES) {
4695            Slog.d(TAG, "Received spurious death notification for thread "
4696                    + thread.asBinder());
4697        }
4698    }
4699
4700    /**
4701     * If a stack trace dump file is configured, dump process stack traces.
4702     * @param clearTraces causes the dump file to be erased prior to the new
4703     *    traces being written, if true; when false, the new traces will be
4704     *    appended to any existing file content.
4705     * @param firstPids of dalvik VM processes to dump stack traces for first
4706     * @param lastPids of dalvik VM processes to dump stack traces for last
4707     * @param nativeProcs optional list of native process names to dump stack crawls
4708     * @return file containing stack traces, or null if no dump file is configured
4709     */
4710    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4711            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4712        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4713        if (tracesPath == null || tracesPath.length() == 0) {
4714            return null;
4715        }
4716
4717        File tracesFile = new File(tracesPath);
4718        try {
4719            File tracesDir = tracesFile.getParentFile();
4720            if (!tracesDir.exists()) {
4721                tracesDir.mkdirs();
4722                if (!SELinux.restorecon(tracesDir)) {
4723                    return null;
4724                }
4725            }
4726            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4727
4728            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4729            tracesFile.createNewFile();
4730            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4731        } catch (IOException e) {
4732            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4733            return null;
4734        }
4735
4736        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4737        return tracesFile;
4738    }
4739
4740    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4741            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4742        // Use a FileObserver to detect when traces finish writing.
4743        // The order of traces is considered important to maintain for legibility.
4744        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4745            @Override
4746            public synchronized void onEvent(int event, String path) { notify(); }
4747        };
4748
4749        try {
4750            observer.startWatching();
4751
4752            // First collect all of the stacks of the most important pids.
4753            if (firstPids != null) {
4754                try {
4755                    int num = firstPids.size();
4756                    for (int i = 0; i < num; i++) {
4757                        synchronized (observer) {
4758                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4759                            observer.wait(200);  // Wait for write-close, give up after 200msec
4760                        }
4761                    }
4762                } catch (InterruptedException e) {
4763                    Slog.wtf(TAG, e);
4764                }
4765            }
4766
4767            // Next collect the stacks of the native pids
4768            if (nativeProcs != null) {
4769                int[] pids = Process.getPidsForCommands(nativeProcs);
4770                if (pids != null) {
4771                    for (int pid : pids) {
4772                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4773                    }
4774                }
4775            }
4776
4777            // Lastly, measure CPU usage.
4778            if (processCpuTracker != null) {
4779                processCpuTracker.init();
4780                System.gc();
4781                processCpuTracker.update();
4782                try {
4783                    synchronized (processCpuTracker) {
4784                        processCpuTracker.wait(500); // measure over 1/2 second.
4785                    }
4786                } catch (InterruptedException e) {
4787                }
4788                processCpuTracker.update();
4789
4790                // We'll take the stack crawls of just the top apps using CPU.
4791                final int N = processCpuTracker.countWorkingStats();
4792                int numProcs = 0;
4793                for (int i=0; i<N && numProcs<5; i++) {
4794                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4795                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4796                        numProcs++;
4797                        try {
4798                            synchronized (observer) {
4799                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4800                                observer.wait(200);  // Wait for write-close, give up after 200msec
4801                            }
4802                        } catch (InterruptedException e) {
4803                            Slog.wtf(TAG, e);
4804                        }
4805
4806                    }
4807                }
4808            }
4809        } finally {
4810            observer.stopWatching();
4811        }
4812    }
4813
4814    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4815        if (true || IS_USER_BUILD) {
4816            return;
4817        }
4818        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4819        if (tracesPath == null || tracesPath.length() == 0) {
4820            return;
4821        }
4822
4823        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4824        StrictMode.allowThreadDiskWrites();
4825        try {
4826            final File tracesFile = new File(tracesPath);
4827            final File tracesDir = tracesFile.getParentFile();
4828            final File tracesTmp = new File(tracesDir, "__tmp__");
4829            try {
4830                if (!tracesDir.exists()) {
4831                    tracesDir.mkdirs();
4832                    if (!SELinux.restorecon(tracesDir.getPath())) {
4833                        return;
4834                    }
4835                }
4836                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4837
4838                if (tracesFile.exists()) {
4839                    tracesTmp.delete();
4840                    tracesFile.renameTo(tracesTmp);
4841                }
4842                StringBuilder sb = new StringBuilder();
4843                Time tobj = new Time();
4844                tobj.set(System.currentTimeMillis());
4845                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4846                sb.append(": ");
4847                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4848                sb.append(" since ");
4849                sb.append(msg);
4850                FileOutputStream fos = new FileOutputStream(tracesFile);
4851                fos.write(sb.toString().getBytes());
4852                if (app == null) {
4853                    fos.write("\n*** No application process!".getBytes());
4854                }
4855                fos.close();
4856                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4857            } catch (IOException e) {
4858                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4859                return;
4860            }
4861
4862            if (app != null) {
4863                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4864                firstPids.add(app.pid);
4865                dumpStackTraces(tracesPath, firstPids, null, null, null);
4866            }
4867
4868            File lastTracesFile = null;
4869            File curTracesFile = null;
4870            for (int i=9; i>=0; i--) {
4871                String name = String.format(Locale.US, "slow%02d.txt", i);
4872                curTracesFile = new File(tracesDir, name);
4873                if (curTracesFile.exists()) {
4874                    if (lastTracesFile != null) {
4875                        curTracesFile.renameTo(lastTracesFile);
4876                    } else {
4877                        curTracesFile.delete();
4878                    }
4879                }
4880                lastTracesFile = curTracesFile;
4881            }
4882            tracesFile.renameTo(curTracesFile);
4883            if (tracesTmp.exists()) {
4884                tracesTmp.renameTo(tracesFile);
4885            }
4886        } finally {
4887            StrictMode.setThreadPolicy(oldPolicy);
4888        }
4889    }
4890
4891    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4892            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4893        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4894        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4895
4896        if (mController != null) {
4897            try {
4898                // 0 == continue, -1 = kill process immediately
4899                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4900                if (res < 0 && app.pid != MY_PID) {
4901                    app.kill("anr", true);
4902                }
4903            } catch (RemoteException e) {
4904                mController = null;
4905                Watchdog.getInstance().setActivityController(null);
4906            }
4907        }
4908
4909        long anrTime = SystemClock.uptimeMillis();
4910        if (MONITOR_CPU_USAGE) {
4911            updateCpuStatsNow();
4912        }
4913
4914        synchronized (this) {
4915            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4916            if (mShuttingDown) {
4917                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4918                return;
4919            } else if (app.notResponding) {
4920                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4921                return;
4922            } else if (app.crashing) {
4923                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4924                return;
4925            }
4926
4927            // In case we come through here for the same app before completing
4928            // this one, mark as anring now so we will bail out.
4929            app.notResponding = true;
4930
4931            // Log the ANR to the event log.
4932            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4933                    app.processName, app.info.flags, annotation);
4934
4935            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4936            firstPids.add(app.pid);
4937
4938            int parentPid = app.pid;
4939            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4940            if (parentPid != app.pid) firstPids.add(parentPid);
4941
4942            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4943
4944            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4945                ProcessRecord r = mLruProcesses.get(i);
4946                if (r != null && r.thread != null) {
4947                    int pid = r.pid;
4948                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4949                        if (r.persistent) {
4950                            firstPids.add(pid);
4951                        } else {
4952                            lastPids.put(pid, Boolean.TRUE);
4953                        }
4954                    }
4955                }
4956            }
4957        }
4958
4959        // Log the ANR to the main log.
4960        StringBuilder info = new StringBuilder();
4961        info.setLength(0);
4962        info.append("ANR in ").append(app.processName);
4963        if (activity != null && activity.shortComponentName != null) {
4964            info.append(" (").append(activity.shortComponentName).append(")");
4965        }
4966        info.append("\n");
4967        info.append("PID: ").append(app.pid).append("\n");
4968        if (annotation != null) {
4969            info.append("Reason: ").append(annotation).append("\n");
4970        }
4971        if (parent != null && parent != activity) {
4972            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4973        }
4974
4975        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4976
4977        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4978                NATIVE_STACKS_OF_INTEREST);
4979
4980        String cpuInfo = null;
4981        if (MONITOR_CPU_USAGE) {
4982            updateCpuStatsNow();
4983            synchronized (mProcessCpuTracker) {
4984                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4985            }
4986            info.append(processCpuTracker.printCurrentLoad());
4987            info.append(cpuInfo);
4988        }
4989
4990        info.append(processCpuTracker.printCurrentState(anrTime));
4991
4992        Slog.e(TAG, info.toString());
4993        if (tracesFile == null) {
4994            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4995            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4996        }
4997
4998        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4999                cpuInfo, tracesFile, null);
5000
5001        if (mController != null) {
5002            try {
5003                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5004                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5005                if (res != 0) {
5006                    if (res < 0 && app.pid != MY_PID) {
5007                        app.kill("anr", true);
5008                    } else {
5009                        synchronized (this) {
5010                            mServices.scheduleServiceTimeoutLocked(app);
5011                        }
5012                    }
5013                    return;
5014                }
5015            } catch (RemoteException e) {
5016                mController = null;
5017                Watchdog.getInstance().setActivityController(null);
5018            }
5019        }
5020
5021        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5022        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5023                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5024
5025        synchronized (this) {
5026            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5027
5028            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5029                app.kill("bg anr", true);
5030                return;
5031            }
5032
5033            // Set the app's notResponding state, and look up the errorReportReceiver
5034            makeAppNotRespondingLocked(app,
5035                    activity != null ? activity.shortComponentName : null,
5036                    annotation != null ? "ANR " + annotation : "ANR",
5037                    info.toString());
5038
5039            // Bring up the infamous App Not Responding dialog
5040            Message msg = Message.obtain();
5041            HashMap<String, Object> map = new HashMap<String, Object>();
5042            msg.what = SHOW_NOT_RESPONDING_MSG;
5043            msg.obj = map;
5044            msg.arg1 = aboveSystem ? 1 : 0;
5045            map.put("app", app);
5046            if (activity != null) {
5047                map.put("activity", activity);
5048            }
5049
5050            mHandler.sendMessage(msg);
5051        }
5052    }
5053
5054    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5055        if (!mLaunchWarningShown) {
5056            mLaunchWarningShown = true;
5057            mHandler.post(new Runnable() {
5058                @Override
5059                public void run() {
5060                    synchronized (ActivityManagerService.this) {
5061                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5062                        d.show();
5063                        mHandler.postDelayed(new Runnable() {
5064                            @Override
5065                            public void run() {
5066                                synchronized (ActivityManagerService.this) {
5067                                    d.dismiss();
5068                                    mLaunchWarningShown = false;
5069                                }
5070                            }
5071                        }, 4000);
5072                    }
5073                }
5074            });
5075        }
5076    }
5077
5078    @Override
5079    public boolean clearApplicationUserData(final String packageName,
5080            final IPackageDataObserver observer, int userId) {
5081        enforceNotIsolatedCaller("clearApplicationUserData");
5082        int uid = Binder.getCallingUid();
5083        int pid = Binder.getCallingPid();
5084        userId = handleIncomingUser(pid, uid,
5085                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5086        long callingId = Binder.clearCallingIdentity();
5087        try {
5088            IPackageManager pm = AppGlobals.getPackageManager();
5089            int pkgUid = -1;
5090            synchronized(this) {
5091                try {
5092                    pkgUid = pm.getPackageUid(packageName, userId);
5093                } catch (RemoteException e) {
5094                }
5095                if (pkgUid == -1) {
5096                    Slog.w(TAG, "Invalid packageName: " + packageName);
5097                    if (observer != null) {
5098                        try {
5099                            observer.onRemoveCompleted(packageName, false);
5100                        } catch (RemoteException e) {
5101                            Slog.i(TAG, "Observer no longer exists.");
5102                        }
5103                    }
5104                    return false;
5105                }
5106                if (uid == pkgUid || checkComponentPermission(
5107                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5108                        pid, uid, -1, true)
5109                        == PackageManager.PERMISSION_GRANTED) {
5110                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5111                } else {
5112                    throw new SecurityException("PID " + pid + " does not have permission "
5113                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5114                                    + " of package " + packageName);
5115                }
5116
5117                // Remove all tasks match the cleared application package and user
5118                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5119                    final TaskRecord tr = mRecentTasks.get(i);
5120                    final String taskPackageName =
5121                            tr.getBaseIntent().getComponent().getPackageName();
5122                    if (tr.userId != userId) continue;
5123                    if (!taskPackageName.equals(packageName)) continue;
5124                    removeTaskByIdLocked(tr.taskId, false);
5125                }
5126            }
5127
5128            try {
5129                // Clear application user data
5130                pm.clearApplicationUserData(packageName, observer, userId);
5131
5132                synchronized(this) {
5133                    // Remove all permissions granted from/to this package
5134                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5135                }
5136
5137                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5138                        Uri.fromParts("package", packageName, null));
5139                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5140                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5141                        null, null, 0, null, null, null, false, false, userId);
5142            } catch (RemoteException e) {
5143            }
5144        } finally {
5145            Binder.restoreCallingIdentity(callingId);
5146        }
5147        return true;
5148    }
5149
5150    @Override
5151    public void killBackgroundProcesses(final String packageName, int userId) {
5152        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5153                != PackageManager.PERMISSION_GRANTED &&
5154                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5155                        != PackageManager.PERMISSION_GRANTED) {
5156            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5157                    + Binder.getCallingPid()
5158                    + ", uid=" + Binder.getCallingUid()
5159                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5160            Slog.w(TAG, msg);
5161            throw new SecurityException(msg);
5162        }
5163
5164        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5165                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5166        long callingId = Binder.clearCallingIdentity();
5167        try {
5168            IPackageManager pm = AppGlobals.getPackageManager();
5169            synchronized(this) {
5170                int appId = -1;
5171                try {
5172                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5173                } catch (RemoteException e) {
5174                }
5175                if (appId == -1) {
5176                    Slog.w(TAG, "Invalid packageName: " + packageName);
5177                    return;
5178                }
5179                killPackageProcessesLocked(packageName, appId, userId,
5180                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5181            }
5182        } finally {
5183            Binder.restoreCallingIdentity(callingId);
5184        }
5185    }
5186
5187    @Override
5188    public void killAllBackgroundProcesses() {
5189        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5190                != PackageManager.PERMISSION_GRANTED) {
5191            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5192                    + Binder.getCallingPid()
5193                    + ", uid=" + Binder.getCallingUid()
5194                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5195            Slog.w(TAG, msg);
5196            throw new SecurityException(msg);
5197        }
5198
5199        long callingId = Binder.clearCallingIdentity();
5200        try {
5201            synchronized(this) {
5202                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5203                final int NP = mProcessNames.getMap().size();
5204                for (int ip=0; ip<NP; ip++) {
5205                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5206                    final int NA = apps.size();
5207                    for (int ia=0; ia<NA; ia++) {
5208                        ProcessRecord app = apps.valueAt(ia);
5209                        if (app.persistent) {
5210                            // we don't kill persistent processes
5211                            continue;
5212                        }
5213                        if (app.removed) {
5214                            procs.add(app);
5215                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5216                            app.removed = true;
5217                            procs.add(app);
5218                        }
5219                    }
5220                }
5221
5222                int N = procs.size();
5223                for (int i=0; i<N; i++) {
5224                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5225                }
5226                mAllowLowerMemLevel = true;
5227                updateOomAdjLocked();
5228                doLowMemReportIfNeededLocked(null);
5229            }
5230        } finally {
5231            Binder.restoreCallingIdentity(callingId);
5232        }
5233    }
5234
5235    @Override
5236    public void forceStopPackage(final String packageName, int userId) {
5237        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5238                != PackageManager.PERMISSION_GRANTED) {
5239            String msg = "Permission Denial: forceStopPackage() from pid="
5240                    + Binder.getCallingPid()
5241                    + ", uid=" + Binder.getCallingUid()
5242                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5243            Slog.w(TAG, msg);
5244            throw new SecurityException(msg);
5245        }
5246        final int callingPid = Binder.getCallingPid();
5247        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5248                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5249        long callingId = Binder.clearCallingIdentity();
5250        try {
5251            IPackageManager pm = AppGlobals.getPackageManager();
5252            synchronized(this) {
5253                int[] users = userId == UserHandle.USER_ALL
5254                        ? getUsersLocked() : new int[] { userId };
5255                for (int user : users) {
5256                    int pkgUid = -1;
5257                    try {
5258                        pkgUid = pm.getPackageUid(packageName, user);
5259                    } catch (RemoteException e) {
5260                    }
5261                    if (pkgUid == -1) {
5262                        Slog.w(TAG, "Invalid packageName: " + packageName);
5263                        continue;
5264                    }
5265                    try {
5266                        pm.setPackageStoppedState(packageName, true, user);
5267                    } catch (RemoteException e) {
5268                    } catch (IllegalArgumentException e) {
5269                        Slog.w(TAG, "Failed trying to unstop package "
5270                                + packageName + ": " + e);
5271                    }
5272                    if (isUserRunningLocked(user, false)) {
5273                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5274                    }
5275                }
5276            }
5277        } finally {
5278            Binder.restoreCallingIdentity(callingId);
5279        }
5280    }
5281
5282    @Override
5283    public void addPackageDependency(String packageName) {
5284        synchronized (this) {
5285            int callingPid = Binder.getCallingPid();
5286            if (callingPid == Process.myPid()) {
5287                //  Yeah, um, no.
5288                Slog.w(TAG, "Can't addPackageDependency on system process");
5289                return;
5290            }
5291            ProcessRecord proc;
5292            synchronized (mPidsSelfLocked) {
5293                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5294            }
5295            if (proc != null) {
5296                if (proc.pkgDeps == null) {
5297                    proc.pkgDeps = new ArraySet<String>(1);
5298                }
5299                proc.pkgDeps.add(packageName);
5300            }
5301        }
5302    }
5303
5304    /*
5305     * The pkg name and app id have to be specified.
5306     */
5307    @Override
5308    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5309        if (pkg == null) {
5310            return;
5311        }
5312        // Make sure the uid is valid.
5313        if (appid < 0) {
5314            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5315            return;
5316        }
5317        int callerUid = Binder.getCallingUid();
5318        // Only the system server can kill an application
5319        if (callerUid == Process.SYSTEM_UID) {
5320            // Post an aysnc message to kill the application
5321            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5322            msg.arg1 = appid;
5323            msg.arg2 = 0;
5324            Bundle bundle = new Bundle();
5325            bundle.putString("pkg", pkg);
5326            bundle.putString("reason", reason);
5327            msg.obj = bundle;
5328            mHandler.sendMessage(msg);
5329        } else {
5330            throw new SecurityException(callerUid + " cannot kill pkg: " +
5331                    pkg);
5332        }
5333    }
5334
5335    @Override
5336    public void closeSystemDialogs(String reason) {
5337        enforceNotIsolatedCaller("closeSystemDialogs");
5338
5339        final int pid = Binder.getCallingPid();
5340        final int uid = Binder.getCallingUid();
5341        final long origId = Binder.clearCallingIdentity();
5342        try {
5343            synchronized (this) {
5344                // Only allow this from foreground processes, so that background
5345                // applications can't abuse it to prevent system UI from being shown.
5346                if (uid >= Process.FIRST_APPLICATION_UID) {
5347                    ProcessRecord proc;
5348                    synchronized (mPidsSelfLocked) {
5349                        proc = mPidsSelfLocked.get(pid);
5350                    }
5351                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5352                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5353                                + " from background process " + proc);
5354                        return;
5355                    }
5356                }
5357                closeSystemDialogsLocked(reason);
5358            }
5359        } finally {
5360            Binder.restoreCallingIdentity(origId);
5361        }
5362    }
5363
5364    void closeSystemDialogsLocked(String reason) {
5365        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5366        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5367                | Intent.FLAG_RECEIVER_FOREGROUND);
5368        if (reason != null) {
5369            intent.putExtra("reason", reason);
5370        }
5371        mWindowManager.closeSystemDialogs(reason);
5372
5373        mStackSupervisor.closeSystemDialogsLocked();
5374
5375        broadcastIntentLocked(null, null, intent, null,
5376                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5377                Process.SYSTEM_UID, UserHandle.USER_ALL);
5378    }
5379
5380    @Override
5381    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5382        enforceNotIsolatedCaller("getProcessMemoryInfo");
5383        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5384        for (int i=pids.length-1; i>=0; i--) {
5385            ProcessRecord proc;
5386            int oomAdj;
5387            synchronized (this) {
5388                synchronized (mPidsSelfLocked) {
5389                    proc = mPidsSelfLocked.get(pids[i]);
5390                    oomAdj = proc != null ? proc.setAdj : 0;
5391                }
5392            }
5393            infos[i] = new Debug.MemoryInfo();
5394            Debug.getMemoryInfo(pids[i], infos[i]);
5395            if (proc != null) {
5396                synchronized (this) {
5397                    if (proc.thread != null && proc.setAdj == oomAdj) {
5398                        // Record this for posterity if the process has been stable.
5399                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5400                                infos[i].getTotalUss(), false, proc.pkgList);
5401                    }
5402                }
5403            }
5404        }
5405        return infos;
5406    }
5407
5408    @Override
5409    public long[] getProcessPss(int[] pids) {
5410        enforceNotIsolatedCaller("getProcessPss");
5411        long[] pss = new long[pids.length];
5412        for (int i=pids.length-1; i>=0; i--) {
5413            ProcessRecord proc;
5414            int oomAdj;
5415            synchronized (this) {
5416                synchronized (mPidsSelfLocked) {
5417                    proc = mPidsSelfLocked.get(pids[i]);
5418                    oomAdj = proc != null ? proc.setAdj : 0;
5419                }
5420            }
5421            long[] tmpUss = new long[1];
5422            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5423            if (proc != null) {
5424                synchronized (this) {
5425                    if (proc.thread != null && proc.setAdj == oomAdj) {
5426                        // Record this for posterity if the process has been stable.
5427                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5428                    }
5429                }
5430            }
5431        }
5432        return pss;
5433    }
5434
5435    @Override
5436    public void killApplicationProcess(String processName, int uid) {
5437        if (processName == null) {
5438            return;
5439        }
5440
5441        int callerUid = Binder.getCallingUid();
5442        // Only the system server can kill an application
5443        if (callerUid == Process.SYSTEM_UID) {
5444            synchronized (this) {
5445                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5446                if (app != null && app.thread != null) {
5447                    try {
5448                        app.thread.scheduleSuicide();
5449                    } catch (RemoteException e) {
5450                        // If the other end already died, then our work here is done.
5451                    }
5452                } else {
5453                    Slog.w(TAG, "Process/uid not found attempting kill of "
5454                            + processName + " / " + uid);
5455                }
5456            }
5457        } else {
5458            throw new SecurityException(callerUid + " cannot kill app process: " +
5459                    processName);
5460        }
5461    }
5462
5463    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5464        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5465                false, true, false, false, UserHandle.getUserId(uid), reason);
5466        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5467                Uri.fromParts("package", packageName, null));
5468        if (!mProcessesReady) {
5469            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5470                    | Intent.FLAG_RECEIVER_FOREGROUND);
5471        }
5472        intent.putExtra(Intent.EXTRA_UID, uid);
5473        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5474        broadcastIntentLocked(null, null, intent,
5475                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5476                false, false,
5477                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5478    }
5479
5480    private void forceStopUserLocked(int userId, String reason) {
5481        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5482        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5483        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5484                | Intent.FLAG_RECEIVER_FOREGROUND);
5485        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5486        broadcastIntentLocked(null, null, intent,
5487                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5488                false, false,
5489                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5490    }
5491
5492    private final boolean killPackageProcessesLocked(String packageName, int appId,
5493            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5494            boolean doit, boolean evenPersistent, String reason) {
5495        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5496
5497        // Remove all processes this package may have touched: all with the
5498        // same UID (except for the system or root user), and all whose name
5499        // matches the package name.
5500        final int NP = mProcessNames.getMap().size();
5501        for (int ip=0; ip<NP; ip++) {
5502            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5503            final int NA = apps.size();
5504            for (int ia=0; ia<NA; ia++) {
5505                ProcessRecord app = apps.valueAt(ia);
5506                if (app.persistent && !evenPersistent) {
5507                    // we don't kill persistent processes
5508                    continue;
5509                }
5510                if (app.removed) {
5511                    if (doit) {
5512                        procs.add(app);
5513                    }
5514                    continue;
5515                }
5516
5517                // Skip process if it doesn't meet our oom adj requirement.
5518                if (app.setAdj < minOomAdj) {
5519                    continue;
5520                }
5521
5522                // If no package is specified, we call all processes under the
5523                // give user id.
5524                if (packageName == null) {
5525                    if (app.userId != userId) {
5526                        continue;
5527                    }
5528                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5529                        continue;
5530                    }
5531                // Package has been specified, we want to hit all processes
5532                // that match it.  We need to qualify this by the processes
5533                // that are running under the specified app and user ID.
5534                } else {
5535                    final boolean isDep = app.pkgDeps != null
5536                            && app.pkgDeps.contains(packageName);
5537                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5538                        continue;
5539                    }
5540                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5541                        continue;
5542                    }
5543                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5544                        continue;
5545                    }
5546                }
5547
5548                // Process has passed all conditions, kill it!
5549                if (!doit) {
5550                    return true;
5551                }
5552                app.removed = true;
5553                procs.add(app);
5554            }
5555        }
5556
5557        int N = procs.size();
5558        for (int i=0; i<N; i++) {
5559            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5560        }
5561        updateOomAdjLocked();
5562        return N > 0;
5563    }
5564
5565    private final boolean forceStopPackageLocked(String name, int appId,
5566            boolean callerWillRestart, boolean purgeCache, boolean doit,
5567            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5568        int i;
5569        int N;
5570
5571        if (userId == UserHandle.USER_ALL && name == null) {
5572            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5573        }
5574
5575        if (appId < 0 && name != null) {
5576            try {
5577                appId = UserHandle.getAppId(
5578                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5579            } catch (RemoteException e) {
5580            }
5581        }
5582
5583        if (doit) {
5584            if (name != null) {
5585                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5586                        + " user=" + userId + ": " + reason);
5587            } else {
5588                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5589            }
5590
5591            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5592            for (int ip=pmap.size()-1; ip>=0; ip--) {
5593                SparseArray<Long> ba = pmap.valueAt(ip);
5594                for (i=ba.size()-1; i>=0; i--) {
5595                    boolean remove = false;
5596                    final int entUid = ba.keyAt(i);
5597                    if (name != null) {
5598                        if (userId == UserHandle.USER_ALL) {
5599                            if (UserHandle.getAppId(entUid) == appId) {
5600                                remove = true;
5601                            }
5602                        } else {
5603                            if (entUid == UserHandle.getUid(userId, appId)) {
5604                                remove = true;
5605                            }
5606                        }
5607                    } else if (UserHandle.getUserId(entUid) == userId) {
5608                        remove = true;
5609                    }
5610                    if (remove) {
5611                        ba.removeAt(i);
5612                    }
5613                }
5614                if (ba.size() == 0) {
5615                    pmap.removeAt(ip);
5616                }
5617            }
5618        }
5619
5620        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5621                -100, callerWillRestart, true, doit, evenPersistent,
5622                name == null ? ("stop user " + userId) : ("stop " + name));
5623
5624        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5625            if (!doit) {
5626                return true;
5627            }
5628            didSomething = true;
5629        }
5630
5631        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5632            if (!doit) {
5633                return true;
5634            }
5635            didSomething = true;
5636        }
5637
5638        if (name == null) {
5639            // Remove all sticky broadcasts from this user.
5640            mStickyBroadcasts.remove(userId);
5641        }
5642
5643        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5644        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5645                userId, providers)) {
5646            if (!doit) {
5647                return true;
5648            }
5649            didSomething = true;
5650        }
5651        N = providers.size();
5652        for (i=0; i<N; i++) {
5653            removeDyingProviderLocked(null, providers.get(i), true);
5654        }
5655
5656        // Remove transient permissions granted from/to this package/user
5657        removeUriPermissionsForPackageLocked(name, userId, false);
5658
5659        if (name == null || uninstalling) {
5660            // Remove pending intents.  For now we only do this when force
5661            // stopping users, because we have some problems when doing this
5662            // for packages -- app widgets are not currently cleaned up for
5663            // such packages, so they can be left with bad pending intents.
5664            if (mIntentSenderRecords.size() > 0) {
5665                Iterator<WeakReference<PendingIntentRecord>> it
5666                        = mIntentSenderRecords.values().iterator();
5667                while (it.hasNext()) {
5668                    WeakReference<PendingIntentRecord> wpir = it.next();
5669                    if (wpir == null) {
5670                        it.remove();
5671                        continue;
5672                    }
5673                    PendingIntentRecord pir = wpir.get();
5674                    if (pir == null) {
5675                        it.remove();
5676                        continue;
5677                    }
5678                    if (name == null) {
5679                        // Stopping user, remove all objects for the user.
5680                        if (pir.key.userId != userId) {
5681                            // Not the same user, skip it.
5682                            continue;
5683                        }
5684                    } else {
5685                        if (UserHandle.getAppId(pir.uid) != appId) {
5686                            // Different app id, skip it.
5687                            continue;
5688                        }
5689                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5690                            // Different user, skip it.
5691                            continue;
5692                        }
5693                        if (!pir.key.packageName.equals(name)) {
5694                            // Different package, skip it.
5695                            continue;
5696                        }
5697                    }
5698                    if (!doit) {
5699                        return true;
5700                    }
5701                    didSomething = true;
5702                    it.remove();
5703                    pir.canceled = true;
5704                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5705                        pir.key.activity.pendingResults.remove(pir.ref);
5706                    }
5707                }
5708            }
5709        }
5710
5711        if (doit) {
5712            if (purgeCache && name != null) {
5713                AttributeCache ac = AttributeCache.instance();
5714                if (ac != null) {
5715                    ac.removePackage(name);
5716                }
5717            }
5718            if (mBooted) {
5719                mStackSupervisor.resumeTopActivitiesLocked();
5720                mStackSupervisor.scheduleIdleLocked();
5721            }
5722        }
5723
5724        return didSomething;
5725    }
5726
5727    private final boolean removeProcessLocked(ProcessRecord app,
5728            boolean callerWillRestart, boolean allowRestart, String reason) {
5729        final String name = app.processName;
5730        final int uid = app.uid;
5731        if (DEBUG_PROCESSES) Slog.d(
5732            TAG, "Force removing proc " + app.toShortString() + " (" + name
5733            + "/" + uid + ")");
5734
5735        mProcessNames.remove(name, uid);
5736        mIsolatedProcesses.remove(app.uid);
5737        if (mHeavyWeightProcess == app) {
5738            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5739                    mHeavyWeightProcess.userId, 0));
5740            mHeavyWeightProcess = null;
5741        }
5742        boolean needRestart = false;
5743        if (app.pid > 0 && app.pid != MY_PID) {
5744            int pid = app.pid;
5745            synchronized (mPidsSelfLocked) {
5746                mPidsSelfLocked.remove(pid);
5747                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5748            }
5749            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5750            if (app.isolated) {
5751                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5752            }
5753            app.kill(reason, true);
5754            handleAppDiedLocked(app, true, allowRestart);
5755            removeLruProcessLocked(app);
5756
5757            if (app.persistent && !app.isolated) {
5758                if (!callerWillRestart) {
5759                    addAppLocked(app.info, false, null /* ABI override */);
5760                } else {
5761                    needRestart = true;
5762                }
5763            }
5764        } else {
5765            mRemovedProcesses.add(app);
5766        }
5767
5768        return needRestart;
5769    }
5770
5771    private final void processStartTimedOutLocked(ProcessRecord app) {
5772        final int pid = app.pid;
5773        boolean gone = false;
5774        synchronized (mPidsSelfLocked) {
5775            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5776            if (knownApp != null && knownApp.thread == null) {
5777                mPidsSelfLocked.remove(pid);
5778                gone = true;
5779            }
5780        }
5781
5782        if (gone) {
5783            Slog.w(TAG, "Process " + app + " failed to attach");
5784            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5785                    pid, app.uid, app.processName);
5786            mProcessNames.remove(app.processName, app.uid);
5787            mIsolatedProcesses.remove(app.uid);
5788            if (mHeavyWeightProcess == app) {
5789                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5790                        mHeavyWeightProcess.userId, 0));
5791                mHeavyWeightProcess = null;
5792            }
5793            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5794            if (app.isolated) {
5795                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5796            }
5797            // Take care of any launching providers waiting for this process.
5798            checkAppInLaunchingProvidersLocked(app, true);
5799            // Take care of any services that are waiting for the process.
5800            mServices.processStartTimedOutLocked(app);
5801            app.kill("start timeout", true);
5802            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5803                Slog.w(TAG, "Unattached app died before backup, skipping");
5804                try {
5805                    IBackupManager bm = IBackupManager.Stub.asInterface(
5806                            ServiceManager.getService(Context.BACKUP_SERVICE));
5807                    bm.agentDisconnected(app.info.packageName);
5808                } catch (RemoteException e) {
5809                    // Can't happen; the backup manager is local
5810                }
5811            }
5812            if (isPendingBroadcastProcessLocked(pid)) {
5813                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5814                skipPendingBroadcastLocked(pid);
5815            }
5816        } else {
5817            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5818        }
5819    }
5820
5821    private final boolean attachApplicationLocked(IApplicationThread thread,
5822            int pid) {
5823
5824        // Find the application record that is being attached...  either via
5825        // the pid if we are running in multiple processes, or just pull the
5826        // next app record if we are emulating process with anonymous threads.
5827        ProcessRecord app;
5828        if (pid != MY_PID && pid >= 0) {
5829            synchronized (mPidsSelfLocked) {
5830                app = mPidsSelfLocked.get(pid);
5831            }
5832        } else {
5833            app = null;
5834        }
5835
5836        if (app == null) {
5837            Slog.w(TAG, "No pending application record for pid " + pid
5838                    + " (IApplicationThread " + thread + "); dropping process");
5839            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5840            if (pid > 0 && pid != MY_PID) {
5841                Process.killProcessQuiet(pid);
5842                //TODO: Process.killProcessGroup(app.info.uid, pid);
5843            } else {
5844                try {
5845                    thread.scheduleExit();
5846                } catch (Exception e) {
5847                    // Ignore exceptions.
5848                }
5849            }
5850            return false;
5851        }
5852
5853        // If this application record is still attached to a previous
5854        // process, clean it up now.
5855        if (app.thread != null) {
5856            handleAppDiedLocked(app, true, true);
5857        }
5858
5859        // Tell the process all about itself.
5860
5861        if (localLOGV) Slog.v(
5862                TAG, "Binding process pid " + pid + " to record " + app);
5863
5864        final String processName = app.processName;
5865        try {
5866            AppDeathRecipient adr = new AppDeathRecipient(
5867                    app, pid, thread);
5868            thread.asBinder().linkToDeath(adr, 0);
5869            app.deathRecipient = adr;
5870        } catch (RemoteException e) {
5871            app.resetPackageList(mProcessStats);
5872            startProcessLocked(app, "link fail", processName);
5873            return false;
5874        }
5875
5876        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5877
5878        app.makeActive(thread, mProcessStats);
5879        app.curAdj = app.setAdj = -100;
5880        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5881        app.forcingToForeground = null;
5882        updateProcessForegroundLocked(app, false, false);
5883        app.hasShownUi = false;
5884        app.debugging = false;
5885        app.cached = false;
5886        app.killedByAm = false;
5887
5888        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5889
5890        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5891        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5892
5893        if (!normalMode) {
5894            Slog.i(TAG, "Launching preboot mode app: " + app);
5895        }
5896
5897        if (localLOGV) Slog.v(
5898            TAG, "New app record " + app
5899            + " thread=" + thread.asBinder() + " pid=" + pid);
5900        try {
5901            int testMode = IApplicationThread.DEBUG_OFF;
5902            if (mDebugApp != null && mDebugApp.equals(processName)) {
5903                testMode = mWaitForDebugger
5904                    ? IApplicationThread.DEBUG_WAIT
5905                    : IApplicationThread.DEBUG_ON;
5906                app.debugging = true;
5907                if (mDebugTransient) {
5908                    mDebugApp = mOrigDebugApp;
5909                    mWaitForDebugger = mOrigWaitForDebugger;
5910                }
5911            }
5912            String profileFile = app.instrumentationProfileFile;
5913            ParcelFileDescriptor profileFd = null;
5914            int samplingInterval = 0;
5915            boolean profileAutoStop = false;
5916            if (mProfileApp != null && mProfileApp.equals(processName)) {
5917                mProfileProc = app;
5918                profileFile = mProfileFile;
5919                profileFd = mProfileFd;
5920                samplingInterval = mSamplingInterval;
5921                profileAutoStop = mAutoStopProfiler;
5922            }
5923            boolean enableOpenGlTrace = false;
5924            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5925                enableOpenGlTrace = true;
5926                mOpenGlTraceApp = null;
5927            }
5928
5929            // If the app is being launched for restore or full backup, set it up specially
5930            boolean isRestrictedBackupMode = false;
5931            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5932                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5933                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5934                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5935            }
5936
5937            ensurePackageDexOpt(app.instrumentationInfo != null
5938                    ? app.instrumentationInfo.packageName
5939                    : app.info.packageName);
5940            if (app.instrumentationClass != null) {
5941                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5942            }
5943            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5944                    + processName + " with config " + mConfiguration);
5945            ApplicationInfo appInfo = app.instrumentationInfo != null
5946                    ? app.instrumentationInfo : app.info;
5947            app.compat = compatibilityInfoForPackageLocked(appInfo);
5948            if (profileFd != null) {
5949                profileFd = profileFd.dup();
5950            }
5951            ProfilerInfo profilerInfo = profileFile == null ? null
5952                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5953            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5954                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5955                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5956                    isRestrictedBackupMode || !normalMode, app.persistent,
5957                    new Configuration(mConfiguration), app.compat,
5958                    getCommonServicesLocked(app.isolated),
5959                    mCoreSettingsObserver.getCoreSettingsLocked());
5960            updateLruProcessLocked(app, false, null);
5961            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5962        } catch (Exception e) {
5963            // todo: Yikes!  What should we do?  For now we will try to
5964            // start another process, but that could easily get us in
5965            // an infinite loop of restarting processes...
5966            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5967
5968            app.resetPackageList(mProcessStats);
5969            app.unlinkDeathRecipient();
5970            startProcessLocked(app, "bind fail", processName);
5971            return false;
5972        }
5973
5974        // Remove this record from the list of starting applications.
5975        mPersistentStartingProcesses.remove(app);
5976        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5977                "Attach application locked removing on hold: " + app);
5978        mProcessesOnHold.remove(app);
5979
5980        boolean badApp = false;
5981        boolean didSomething = false;
5982
5983        // See if the top visible activity is waiting to run in this process...
5984        if (normalMode) {
5985            try {
5986                if (mStackSupervisor.attachApplicationLocked(app)) {
5987                    didSomething = true;
5988                }
5989            } catch (Exception e) {
5990                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5991                badApp = true;
5992            }
5993        }
5994
5995        // Find any services that should be running in this process...
5996        if (!badApp) {
5997            try {
5998                didSomething |= mServices.attachApplicationLocked(app, processName);
5999            } catch (Exception e) {
6000                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6001                badApp = true;
6002            }
6003        }
6004
6005        // Check if a next-broadcast receiver is in this process...
6006        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6007            try {
6008                didSomething |= sendPendingBroadcastsLocked(app);
6009            } catch (Exception e) {
6010                // If the app died trying to launch the receiver we declare it 'bad'
6011                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6012                badApp = true;
6013            }
6014        }
6015
6016        // Check whether the next backup agent is in this process...
6017        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6018            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6019            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6020            try {
6021                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6022                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6023                        mBackupTarget.backupMode);
6024            } catch (Exception e) {
6025                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6026                badApp = true;
6027            }
6028        }
6029
6030        if (badApp) {
6031            app.kill("error during init", true);
6032            handleAppDiedLocked(app, false, true);
6033            return false;
6034        }
6035
6036        if (!didSomething) {
6037            updateOomAdjLocked();
6038        }
6039
6040        return true;
6041    }
6042
6043    @Override
6044    public final void attachApplication(IApplicationThread thread) {
6045        synchronized (this) {
6046            int callingPid = Binder.getCallingPid();
6047            final long origId = Binder.clearCallingIdentity();
6048            attachApplicationLocked(thread, callingPid);
6049            Binder.restoreCallingIdentity(origId);
6050        }
6051    }
6052
6053    @Override
6054    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6055        final long origId = Binder.clearCallingIdentity();
6056        synchronized (this) {
6057            ActivityStack stack = ActivityRecord.getStackLocked(token);
6058            if (stack != null) {
6059                ActivityRecord r =
6060                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6061                if (stopProfiling) {
6062                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6063                        try {
6064                            mProfileFd.close();
6065                        } catch (IOException e) {
6066                        }
6067                        clearProfilerLocked();
6068                    }
6069                }
6070            }
6071        }
6072        Binder.restoreCallingIdentity(origId);
6073    }
6074
6075    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6076        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6077                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6078    }
6079
6080    void enableScreenAfterBoot() {
6081        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6082                SystemClock.uptimeMillis());
6083        mWindowManager.enableScreenAfterBoot();
6084
6085        synchronized (this) {
6086            updateEventDispatchingLocked();
6087        }
6088    }
6089
6090    @Override
6091    public void showBootMessage(final CharSequence msg, final boolean always) {
6092        enforceNotIsolatedCaller("showBootMessage");
6093        mWindowManager.showBootMessage(msg, always);
6094    }
6095
6096    @Override
6097    public void keyguardWaitingForActivityDrawn() {
6098        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6099        final long token = Binder.clearCallingIdentity();
6100        try {
6101            synchronized (this) {
6102                if (DEBUG_LOCKSCREEN) logLockScreen("");
6103                mWindowManager.keyguardWaitingForActivityDrawn();
6104                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6105                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6106                    updateSleepIfNeededLocked();
6107                }
6108            }
6109        } finally {
6110            Binder.restoreCallingIdentity(token);
6111        }
6112    }
6113
6114    final void finishBooting() {
6115        synchronized (this) {
6116            if (!mBootAnimationComplete) {
6117                mCallFinishBooting = true;
6118                return;
6119            }
6120            mCallFinishBooting = false;
6121        }
6122
6123        ArraySet<String> completedIsas = new ArraySet<String>();
6124        for (String abi : Build.SUPPORTED_ABIS) {
6125            Process.establishZygoteConnectionForAbi(abi);
6126            final String instructionSet = VMRuntime.getInstructionSet(abi);
6127            if (!completedIsas.contains(instructionSet)) {
6128                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6129                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6130                }
6131                completedIsas.add(instructionSet);
6132            }
6133        }
6134
6135        IntentFilter pkgFilter = new IntentFilter();
6136        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6137        pkgFilter.addDataScheme("package");
6138        mContext.registerReceiver(new BroadcastReceiver() {
6139            @Override
6140            public void onReceive(Context context, Intent intent) {
6141                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6142                if (pkgs != null) {
6143                    for (String pkg : pkgs) {
6144                        synchronized (ActivityManagerService.this) {
6145                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6146                                    0, "finished booting")) {
6147                                setResultCode(Activity.RESULT_OK);
6148                                return;
6149                            }
6150                        }
6151                    }
6152                }
6153            }
6154        }, pkgFilter);
6155
6156        // Let system services know.
6157        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6158
6159        synchronized (this) {
6160            // Ensure that any processes we had put on hold are now started
6161            // up.
6162            final int NP = mProcessesOnHold.size();
6163            if (NP > 0) {
6164                ArrayList<ProcessRecord> procs =
6165                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6166                for (int ip=0; ip<NP; ip++) {
6167                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6168                            + procs.get(ip));
6169                    startProcessLocked(procs.get(ip), "on-hold", null);
6170                }
6171            }
6172
6173            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6174                // Start looking for apps that are abusing wake locks.
6175                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6176                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6177                // Tell anyone interested that we are done booting!
6178                SystemProperties.set("sys.boot_completed", "1");
6179
6180                // And trigger dev.bootcomplete if we are not showing encryption progress
6181                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6182                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6183                    SystemProperties.set("dev.bootcomplete", "1");
6184                }
6185                for (int i=0; i<mStartedUsers.size(); i++) {
6186                    UserStartedState uss = mStartedUsers.valueAt(i);
6187                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6188                        uss.mState = UserStartedState.STATE_RUNNING;
6189                        final int userId = mStartedUsers.keyAt(i);
6190                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6191                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6192                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6193                        broadcastIntentLocked(null, null, intent, null,
6194                                new IIntentReceiver.Stub() {
6195                                    @Override
6196                                    public void performReceive(Intent intent, int resultCode,
6197                                            String data, Bundle extras, boolean ordered,
6198                                            boolean sticky, int sendingUser) {
6199                                        synchronized (ActivityManagerService.this) {
6200                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6201                                                    true, false);
6202                                        }
6203                                    }
6204                                },
6205                                0, null, null,
6206                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6207                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6208                                userId);
6209                    }
6210                }
6211                scheduleStartProfilesLocked();
6212            }
6213        }
6214    }
6215
6216    @Override
6217    public void bootAnimationComplete() {
6218        final boolean callFinishBooting;
6219        synchronized (this) {
6220            callFinishBooting = mCallFinishBooting;
6221            mBootAnimationComplete = true;
6222        }
6223        if (callFinishBooting) {
6224            finishBooting();
6225        }
6226    }
6227
6228    @Override
6229    public void systemBackupRestored() {
6230        synchronized (this) {
6231            if (mSystemReady) {
6232                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6233            } else {
6234                Slog.w(TAG, "System backup restored before system is ready");
6235            }
6236        }
6237    }
6238
6239    final void ensureBootCompleted() {
6240        boolean booting;
6241        boolean enableScreen;
6242        synchronized (this) {
6243            booting = mBooting;
6244            mBooting = false;
6245            enableScreen = !mBooted;
6246            mBooted = true;
6247        }
6248
6249        if (booting) {
6250            finishBooting();
6251        }
6252
6253        if (enableScreen) {
6254            enableScreenAfterBoot();
6255        }
6256    }
6257
6258    @Override
6259    public final void activityResumed(IBinder token) {
6260        final long origId = Binder.clearCallingIdentity();
6261        synchronized(this) {
6262            ActivityStack stack = ActivityRecord.getStackLocked(token);
6263            if (stack != null) {
6264                ActivityRecord.activityResumedLocked(token);
6265            }
6266        }
6267        Binder.restoreCallingIdentity(origId);
6268    }
6269
6270    @Override
6271    public final void activityPaused(IBinder token) {
6272        final long origId = Binder.clearCallingIdentity();
6273        synchronized(this) {
6274            ActivityStack stack = ActivityRecord.getStackLocked(token);
6275            if (stack != null) {
6276                stack.activityPausedLocked(token, false);
6277            }
6278        }
6279        Binder.restoreCallingIdentity(origId);
6280    }
6281
6282    @Override
6283    public final void activityStopped(IBinder token, Bundle icicle,
6284            PersistableBundle persistentState, CharSequence description) {
6285        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6286
6287        // Refuse possible leaked file descriptors
6288        if (icicle != null && icicle.hasFileDescriptors()) {
6289            throw new IllegalArgumentException("File descriptors passed in Bundle");
6290        }
6291
6292        final long origId = Binder.clearCallingIdentity();
6293
6294        synchronized (this) {
6295            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6296            if (r != null) {
6297                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6298            }
6299        }
6300
6301        trimApplications();
6302
6303        Binder.restoreCallingIdentity(origId);
6304    }
6305
6306    @Override
6307    public final void activityDestroyed(IBinder token) {
6308        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6309        synchronized (this) {
6310            ActivityStack stack = ActivityRecord.getStackLocked(token);
6311            if (stack != null) {
6312                stack.activityDestroyedLocked(token);
6313            }
6314        }
6315    }
6316
6317    @Override
6318    public final void backgroundResourcesReleased(IBinder token) {
6319        final long origId = Binder.clearCallingIdentity();
6320        try {
6321            synchronized (this) {
6322                ActivityStack stack = ActivityRecord.getStackLocked(token);
6323                if (stack != null) {
6324                    stack.backgroundResourcesReleased();
6325                }
6326            }
6327        } finally {
6328            Binder.restoreCallingIdentity(origId);
6329        }
6330    }
6331
6332    @Override
6333    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6334        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6335    }
6336
6337    @Override
6338    public final void notifyEnterAnimationComplete(IBinder token) {
6339        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6340    }
6341
6342    @Override
6343    public String getCallingPackage(IBinder token) {
6344        synchronized (this) {
6345            ActivityRecord r = getCallingRecordLocked(token);
6346            return r != null ? r.info.packageName : null;
6347        }
6348    }
6349
6350    @Override
6351    public ComponentName getCallingActivity(IBinder token) {
6352        synchronized (this) {
6353            ActivityRecord r = getCallingRecordLocked(token);
6354            return r != null ? r.intent.getComponent() : null;
6355        }
6356    }
6357
6358    private ActivityRecord getCallingRecordLocked(IBinder token) {
6359        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6360        if (r == null) {
6361            return null;
6362        }
6363        return r.resultTo;
6364    }
6365
6366    @Override
6367    public ComponentName getActivityClassForToken(IBinder token) {
6368        synchronized(this) {
6369            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6370            if (r == null) {
6371                return null;
6372            }
6373            return r.intent.getComponent();
6374        }
6375    }
6376
6377    @Override
6378    public String getPackageForToken(IBinder token) {
6379        synchronized(this) {
6380            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6381            if (r == null) {
6382                return null;
6383            }
6384            return r.packageName;
6385        }
6386    }
6387
6388    @Override
6389    public IIntentSender getIntentSender(int type,
6390            String packageName, IBinder token, String resultWho,
6391            int requestCode, Intent[] intents, String[] resolvedTypes,
6392            int flags, Bundle options, int userId) {
6393        enforceNotIsolatedCaller("getIntentSender");
6394        // Refuse possible leaked file descriptors
6395        if (intents != null) {
6396            if (intents.length < 1) {
6397                throw new IllegalArgumentException("Intents array length must be >= 1");
6398            }
6399            for (int i=0; i<intents.length; i++) {
6400                Intent intent = intents[i];
6401                if (intent != null) {
6402                    if (intent.hasFileDescriptors()) {
6403                        throw new IllegalArgumentException("File descriptors passed in Intent");
6404                    }
6405                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6406                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6407                        throw new IllegalArgumentException(
6408                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6409                    }
6410                    intents[i] = new Intent(intent);
6411                }
6412            }
6413            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6414                throw new IllegalArgumentException(
6415                        "Intent array length does not match resolvedTypes length");
6416            }
6417        }
6418        if (options != null) {
6419            if (options.hasFileDescriptors()) {
6420                throw new IllegalArgumentException("File descriptors passed in options");
6421            }
6422        }
6423
6424        synchronized(this) {
6425            int callingUid = Binder.getCallingUid();
6426            int origUserId = userId;
6427            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6428                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6429                    ALLOW_NON_FULL, "getIntentSender", null);
6430            if (origUserId == UserHandle.USER_CURRENT) {
6431                // We don't want to evaluate this until the pending intent is
6432                // actually executed.  However, we do want to always do the
6433                // security checking for it above.
6434                userId = UserHandle.USER_CURRENT;
6435            }
6436            try {
6437                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6438                    int uid = AppGlobals.getPackageManager()
6439                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6440                    if (!UserHandle.isSameApp(callingUid, uid)) {
6441                        String msg = "Permission Denial: getIntentSender() from pid="
6442                            + Binder.getCallingPid()
6443                            + ", uid=" + Binder.getCallingUid()
6444                            + ", (need uid=" + uid + ")"
6445                            + " is not allowed to send as package " + packageName;
6446                        Slog.w(TAG, msg);
6447                        throw new SecurityException(msg);
6448                    }
6449                }
6450
6451                return getIntentSenderLocked(type, packageName, callingUid, userId,
6452                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6453
6454            } catch (RemoteException e) {
6455                throw new SecurityException(e);
6456            }
6457        }
6458    }
6459
6460    IIntentSender getIntentSenderLocked(int type, String packageName,
6461            int callingUid, int userId, IBinder token, String resultWho,
6462            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6463            Bundle options) {
6464        if (DEBUG_MU)
6465            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6466        ActivityRecord activity = null;
6467        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6468            activity = ActivityRecord.isInStackLocked(token);
6469            if (activity == null) {
6470                return null;
6471            }
6472            if (activity.finishing) {
6473                return null;
6474            }
6475        }
6476
6477        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6478        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6479        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6480        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6481                |PendingIntent.FLAG_UPDATE_CURRENT);
6482
6483        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6484                type, packageName, activity, resultWho,
6485                requestCode, intents, resolvedTypes, flags, options, userId);
6486        WeakReference<PendingIntentRecord> ref;
6487        ref = mIntentSenderRecords.get(key);
6488        PendingIntentRecord rec = ref != null ? ref.get() : null;
6489        if (rec != null) {
6490            if (!cancelCurrent) {
6491                if (updateCurrent) {
6492                    if (rec.key.requestIntent != null) {
6493                        rec.key.requestIntent.replaceExtras(intents != null ?
6494                                intents[intents.length - 1] : null);
6495                    }
6496                    if (intents != null) {
6497                        intents[intents.length-1] = rec.key.requestIntent;
6498                        rec.key.allIntents = intents;
6499                        rec.key.allResolvedTypes = resolvedTypes;
6500                    } else {
6501                        rec.key.allIntents = null;
6502                        rec.key.allResolvedTypes = null;
6503                    }
6504                }
6505                return rec;
6506            }
6507            rec.canceled = true;
6508            mIntentSenderRecords.remove(key);
6509        }
6510        if (noCreate) {
6511            return rec;
6512        }
6513        rec = new PendingIntentRecord(this, key, callingUid);
6514        mIntentSenderRecords.put(key, rec.ref);
6515        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6516            if (activity.pendingResults == null) {
6517                activity.pendingResults
6518                        = new HashSet<WeakReference<PendingIntentRecord>>();
6519            }
6520            activity.pendingResults.add(rec.ref);
6521        }
6522        return rec;
6523    }
6524
6525    @Override
6526    public void cancelIntentSender(IIntentSender sender) {
6527        if (!(sender instanceof PendingIntentRecord)) {
6528            return;
6529        }
6530        synchronized(this) {
6531            PendingIntentRecord rec = (PendingIntentRecord)sender;
6532            try {
6533                int uid = AppGlobals.getPackageManager()
6534                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6535                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6536                    String msg = "Permission Denial: cancelIntentSender() from pid="
6537                        + Binder.getCallingPid()
6538                        + ", uid=" + Binder.getCallingUid()
6539                        + " is not allowed to cancel packges "
6540                        + rec.key.packageName;
6541                    Slog.w(TAG, msg);
6542                    throw new SecurityException(msg);
6543                }
6544            } catch (RemoteException e) {
6545                throw new SecurityException(e);
6546            }
6547            cancelIntentSenderLocked(rec, true);
6548        }
6549    }
6550
6551    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6552        rec.canceled = true;
6553        mIntentSenderRecords.remove(rec.key);
6554        if (cleanActivity && rec.key.activity != null) {
6555            rec.key.activity.pendingResults.remove(rec.ref);
6556        }
6557    }
6558
6559    @Override
6560    public String getPackageForIntentSender(IIntentSender pendingResult) {
6561        if (!(pendingResult instanceof PendingIntentRecord)) {
6562            return null;
6563        }
6564        try {
6565            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6566            return res.key.packageName;
6567        } catch (ClassCastException e) {
6568        }
6569        return null;
6570    }
6571
6572    @Override
6573    public int getUidForIntentSender(IIntentSender sender) {
6574        if (sender instanceof PendingIntentRecord) {
6575            try {
6576                PendingIntentRecord res = (PendingIntentRecord)sender;
6577                return res.uid;
6578            } catch (ClassCastException e) {
6579            }
6580        }
6581        return -1;
6582    }
6583
6584    @Override
6585    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6586        if (!(pendingResult instanceof PendingIntentRecord)) {
6587            return false;
6588        }
6589        try {
6590            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6591            if (res.key.allIntents == null) {
6592                return false;
6593            }
6594            for (int i=0; i<res.key.allIntents.length; i++) {
6595                Intent intent = res.key.allIntents[i];
6596                if (intent.getPackage() != null && intent.getComponent() != null) {
6597                    return false;
6598                }
6599            }
6600            return true;
6601        } catch (ClassCastException e) {
6602        }
6603        return false;
6604    }
6605
6606    @Override
6607    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6608        if (!(pendingResult instanceof PendingIntentRecord)) {
6609            return false;
6610        }
6611        try {
6612            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6613            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6614                return true;
6615            }
6616            return false;
6617        } catch (ClassCastException e) {
6618        }
6619        return false;
6620    }
6621
6622    @Override
6623    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6624        if (!(pendingResult instanceof PendingIntentRecord)) {
6625            return null;
6626        }
6627        try {
6628            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6629            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6630        } catch (ClassCastException e) {
6631        }
6632        return null;
6633    }
6634
6635    @Override
6636    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6637        if (!(pendingResult instanceof PendingIntentRecord)) {
6638            return null;
6639        }
6640        try {
6641            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6642            Intent intent = res.key.requestIntent;
6643            if (intent != null) {
6644                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6645                        || res.lastTagPrefix.equals(prefix))) {
6646                    return res.lastTag;
6647                }
6648                res.lastTagPrefix = prefix;
6649                StringBuilder sb = new StringBuilder(128);
6650                if (prefix != null) {
6651                    sb.append(prefix);
6652                }
6653                if (intent.getAction() != null) {
6654                    sb.append(intent.getAction());
6655                } else if (intent.getComponent() != null) {
6656                    intent.getComponent().appendShortString(sb);
6657                } else {
6658                    sb.append("?");
6659                }
6660                return res.lastTag = sb.toString();
6661            }
6662        } catch (ClassCastException e) {
6663        }
6664        return null;
6665    }
6666
6667    @Override
6668    public void setProcessLimit(int max) {
6669        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6670                "setProcessLimit()");
6671        synchronized (this) {
6672            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6673            mProcessLimitOverride = max;
6674        }
6675        trimApplications();
6676    }
6677
6678    @Override
6679    public int getProcessLimit() {
6680        synchronized (this) {
6681            return mProcessLimitOverride;
6682        }
6683    }
6684
6685    void foregroundTokenDied(ForegroundToken token) {
6686        synchronized (ActivityManagerService.this) {
6687            synchronized (mPidsSelfLocked) {
6688                ForegroundToken cur
6689                    = mForegroundProcesses.get(token.pid);
6690                if (cur != token) {
6691                    return;
6692                }
6693                mForegroundProcesses.remove(token.pid);
6694                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6695                if (pr == null) {
6696                    return;
6697                }
6698                pr.forcingToForeground = null;
6699                updateProcessForegroundLocked(pr, false, false);
6700            }
6701            updateOomAdjLocked();
6702        }
6703    }
6704
6705    @Override
6706    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6707        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6708                "setProcessForeground()");
6709        synchronized(this) {
6710            boolean changed = false;
6711
6712            synchronized (mPidsSelfLocked) {
6713                ProcessRecord pr = mPidsSelfLocked.get(pid);
6714                if (pr == null && isForeground) {
6715                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6716                    return;
6717                }
6718                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6719                if (oldToken != null) {
6720                    oldToken.token.unlinkToDeath(oldToken, 0);
6721                    mForegroundProcesses.remove(pid);
6722                    if (pr != null) {
6723                        pr.forcingToForeground = null;
6724                    }
6725                    changed = true;
6726                }
6727                if (isForeground && token != null) {
6728                    ForegroundToken newToken = new ForegroundToken() {
6729                        @Override
6730                        public void binderDied() {
6731                            foregroundTokenDied(this);
6732                        }
6733                    };
6734                    newToken.pid = pid;
6735                    newToken.token = token;
6736                    try {
6737                        token.linkToDeath(newToken, 0);
6738                        mForegroundProcesses.put(pid, newToken);
6739                        pr.forcingToForeground = token;
6740                        changed = true;
6741                    } catch (RemoteException e) {
6742                        // If the process died while doing this, we will later
6743                        // do the cleanup with the process death link.
6744                    }
6745                }
6746            }
6747
6748            if (changed) {
6749                updateOomAdjLocked();
6750            }
6751        }
6752    }
6753
6754    // =========================================================
6755    // PERMISSIONS
6756    // =========================================================
6757
6758    static class PermissionController extends IPermissionController.Stub {
6759        ActivityManagerService mActivityManagerService;
6760        PermissionController(ActivityManagerService activityManagerService) {
6761            mActivityManagerService = activityManagerService;
6762        }
6763
6764        @Override
6765        public boolean checkPermission(String permission, int pid, int uid) {
6766            return mActivityManagerService.checkPermission(permission, pid,
6767                    uid) == PackageManager.PERMISSION_GRANTED;
6768        }
6769    }
6770
6771    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6772        @Override
6773        public int checkComponentPermission(String permission, int pid, int uid,
6774                int owningUid, boolean exported) {
6775            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6776                    owningUid, exported);
6777        }
6778
6779        @Override
6780        public Object getAMSLock() {
6781            return ActivityManagerService.this;
6782        }
6783    }
6784
6785    /**
6786     * This can be called with or without the global lock held.
6787     */
6788    int checkComponentPermission(String permission, int pid, int uid,
6789            int owningUid, boolean exported) {
6790        if (pid == MY_PID) {
6791            return PackageManager.PERMISSION_GRANTED;
6792        }
6793        return ActivityManager.checkComponentPermission(permission, uid,
6794                owningUid, exported);
6795    }
6796
6797    /**
6798     * As the only public entry point for permissions checking, this method
6799     * can enforce the semantic that requesting a check on a null global
6800     * permission is automatically denied.  (Internally a null permission
6801     * string is used when calling {@link #checkComponentPermission} in cases
6802     * when only uid-based security is needed.)
6803     *
6804     * This can be called with or without the global lock held.
6805     */
6806    @Override
6807    public int checkPermission(String permission, int pid, int uid) {
6808        if (permission == null) {
6809            return PackageManager.PERMISSION_DENIED;
6810        }
6811        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6812    }
6813
6814    @Override
6815    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6816        if (permission == null) {
6817            return PackageManager.PERMISSION_DENIED;
6818        }
6819
6820        // We might be performing an operation on behalf of an indirect binder
6821        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6822        // client identity accordingly before proceeding.
6823        Identity tlsIdentity = sCallerIdentity.get();
6824        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6825            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6826                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6827            uid = tlsIdentity.uid;
6828            pid = tlsIdentity.pid;
6829        }
6830
6831        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6832    }
6833
6834    /**
6835     * Binder IPC calls go through the public entry point.
6836     * This can be called with or without the global lock held.
6837     */
6838    int checkCallingPermission(String permission) {
6839        return checkPermission(permission,
6840                Binder.getCallingPid(),
6841                UserHandle.getAppId(Binder.getCallingUid()));
6842    }
6843
6844    /**
6845     * This can be called with or without the global lock held.
6846     */
6847    void enforceCallingPermission(String permission, String func) {
6848        if (checkCallingPermission(permission)
6849                == PackageManager.PERMISSION_GRANTED) {
6850            return;
6851        }
6852
6853        String msg = "Permission Denial: " + func + " from pid="
6854                + Binder.getCallingPid()
6855                + ", uid=" + Binder.getCallingUid()
6856                + " requires " + permission;
6857        Slog.w(TAG, msg);
6858        throw new SecurityException(msg);
6859    }
6860
6861    /**
6862     * Determine if UID is holding permissions required to access {@link Uri} in
6863     * the given {@link ProviderInfo}. Final permission checking is always done
6864     * in {@link ContentProvider}.
6865     */
6866    private final boolean checkHoldingPermissionsLocked(
6867            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6868        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6869                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6870        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6871            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6872                    != PERMISSION_GRANTED) {
6873                return false;
6874            }
6875        }
6876        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6877    }
6878
6879    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6880            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6881        if (pi.applicationInfo.uid == uid) {
6882            return true;
6883        } else if (!pi.exported) {
6884            return false;
6885        }
6886
6887        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6888        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6889        try {
6890            // check if target holds top-level <provider> permissions
6891            if (!readMet && pi.readPermission != null && considerUidPermissions
6892                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6893                readMet = true;
6894            }
6895            if (!writeMet && pi.writePermission != null && considerUidPermissions
6896                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6897                writeMet = true;
6898            }
6899
6900            // track if unprotected read/write is allowed; any denied
6901            // <path-permission> below removes this ability
6902            boolean allowDefaultRead = pi.readPermission == null;
6903            boolean allowDefaultWrite = pi.writePermission == null;
6904
6905            // check if target holds any <path-permission> that match uri
6906            final PathPermission[] pps = pi.pathPermissions;
6907            if (pps != null) {
6908                final String path = grantUri.uri.getPath();
6909                int i = pps.length;
6910                while (i > 0 && (!readMet || !writeMet)) {
6911                    i--;
6912                    PathPermission pp = pps[i];
6913                    if (pp.match(path)) {
6914                        if (!readMet) {
6915                            final String pprperm = pp.getReadPermission();
6916                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6917                                    + pprperm + " for " + pp.getPath()
6918                                    + ": match=" + pp.match(path)
6919                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6920                            if (pprperm != null) {
6921                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6922                                        == PERMISSION_GRANTED) {
6923                                    readMet = true;
6924                                } else {
6925                                    allowDefaultRead = false;
6926                                }
6927                            }
6928                        }
6929                        if (!writeMet) {
6930                            final String ppwperm = pp.getWritePermission();
6931                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6932                                    + ppwperm + " for " + pp.getPath()
6933                                    + ": match=" + pp.match(path)
6934                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6935                            if (ppwperm != null) {
6936                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6937                                        == PERMISSION_GRANTED) {
6938                                    writeMet = true;
6939                                } else {
6940                                    allowDefaultWrite = false;
6941                                }
6942                            }
6943                        }
6944                    }
6945                }
6946            }
6947
6948            // grant unprotected <provider> read/write, if not blocked by
6949            // <path-permission> above
6950            if (allowDefaultRead) readMet = true;
6951            if (allowDefaultWrite) writeMet = true;
6952
6953        } catch (RemoteException e) {
6954            return false;
6955        }
6956
6957        return readMet && writeMet;
6958    }
6959
6960    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6961        ProviderInfo pi = null;
6962        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6963        if (cpr != null) {
6964            pi = cpr.info;
6965        } else {
6966            try {
6967                pi = AppGlobals.getPackageManager().resolveContentProvider(
6968                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6969            } catch (RemoteException ex) {
6970            }
6971        }
6972        return pi;
6973    }
6974
6975    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6976        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6977        if (targetUris != null) {
6978            return targetUris.get(grantUri);
6979        }
6980        return null;
6981    }
6982
6983    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6984            String targetPkg, int targetUid, GrantUri grantUri) {
6985        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6986        if (targetUris == null) {
6987            targetUris = Maps.newArrayMap();
6988            mGrantedUriPermissions.put(targetUid, targetUris);
6989        }
6990
6991        UriPermission perm = targetUris.get(grantUri);
6992        if (perm == null) {
6993            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6994            targetUris.put(grantUri, perm);
6995        }
6996
6997        return perm;
6998    }
6999
7000    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7001            final int modeFlags) {
7002        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7003        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7004                : UriPermission.STRENGTH_OWNED;
7005
7006        // Root gets to do everything.
7007        if (uid == 0) {
7008            return true;
7009        }
7010
7011        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7012        if (perms == null) return false;
7013
7014        // First look for exact match
7015        final UriPermission exactPerm = perms.get(grantUri);
7016        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7017            return true;
7018        }
7019
7020        // No exact match, look for prefixes
7021        final int N = perms.size();
7022        for (int i = 0; i < N; i++) {
7023            final UriPermission perm = perms.valueAt(i);
7024            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7025                    && perm.getStrength(modeFlags) >= minStrength) {
7026                return true;
7027            }
7028        }
7029
7030        return false;
7031    }
7032
7033    /**
7034     * @param uri This uri must NOT contain an embedded userId.
7035     * @param userId The userId in which the uri is to be resolved.
7036     */
7037    @Override
7038    public int checkUriPermission(Uri uri, int pid, int uid,
7039            final int modeFlags, int userId, IBinder callerToken) {
7040        enforceNotIsolatedCaller("checkUriPermission");
7041
7042        // Another redirected-binder-call permissions check as in
7043        // {@link checkPermissionWithToken}.
7044        Identity tlsIdentity = sCallerIdentity.get();
7045        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7046            uid = tlsIdentity.uid;
7047            pid = tlsIdentity.pid;
7048        }
7049
7050        // Our own process gets to do everything.
7051        if (pid == MY_PID) {
7052            return PackageManager.PERMISSION_GRANTED;
7053        }
7054        synchronized (this) {
7055            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7056                    ? PackageManager.PERMISSION_GRANTED
7057                    : PackageManager.PERMISSION_DENIED;
7058        }
7059    }
7060
7061    /**
7062     * Check if the targetPkg can be granted permission to access uri by
7063     * the callingUid using the given modeFlags.  Throws a security exception
7064     * if callingUid is not allowed to do this.  Returns the uid of the target
7065     * if the URI permission grant should be performed; returns -1 if it is not
7066     * needed (for example targetPkg already has permission to access the URI).
7067     * If you already know the uid of the target, you can supply it in
7068     * lastTargetUid else set that to -1.
7069     */
7070    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7071            final int modeFlags, int lastTargetUid) {
7072        if (!Intent.isAccessUriMode(modeFlags)) {
7073            return -1;
7074        }
7075
7076        if (targetPkg != null) {
7077            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7078                    "Checking grant " + targetPkg + " permission to " + grantUri);
7079        }
7080
7081        final IPackageManager pm = AppGlobals.getPackageManager();
7082
7083        // If this is not a content: uri, we can't do anything with it.
7084        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7085            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7086                    "Can't grant URI permission for non-content URI: " + grantUri);
7087            return -1;
7088        }
7089
7090        final String authority = grantUri.uri.getAuthority();
7091        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7092        if (pi == null) {
7093            Slog.w(TAG, "No content provider found for permission check: " +
7094                    grantUri.uri.toSafeString());
7095            return -1;
7096        }
7097
7098        int targetUid = lastTargetUid;
7099        if (targetUid < 0 && targetPkg != null) {
7100            try {
7101                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7102                if (targetUid < 0) {
7103                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7104                            "Can't grant URI permission no uid for: " + targetPkg);
7105                    return -1;
7106                }
7107            } catch (RemoteException ex) {
7108                return -1;
7109            }
7110        }
7111
7112        if (targetUid >= 0) {
7113            // First...  does the target actually need this permission?
7114            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7115                // No need to grant the target this permission.
7116                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7117                        "Target " + targetPkg + " already has full permission to " + grantUri);
7118                return -1;
7119            }
7120        } else {
7121            // First...  there is no target package, so can anyone access it?
7122            boolean allowed = pi.exported;
7123            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7124                if (pi.readPermission != null) {
7125                    allowed = false;
7126                }
7127            }
7128            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7129                if (pi.writePermission != null) {
7130                    allowed = false;
7131                }
7132            }
7133            if (allowed) {
7134                return -1;
7135            }
7136        }
7137
7138        /* There is a special cross user grant if:
7139         * - The target is on another user.
7140         * - Apps on the current user can access the uri without any uid permissions.
7141         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7142         * grant uri permissions.
7143         */
7144        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7145                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7146                modeFlags, false /*without considering the uid permissions*/);
7147
7148        // Second...  is the provider allowing granting of URI permissions?
7149        if (!specialCrossUserGrant) {
7150            if (!pi.grantUriPermissions) {
7151                throw new SecurityException("Provider " + pi.packageName
7152                        + "/" + pi.name
7153                        + " does not allow granting of Uri permissions (uri "
7154                        + grantUri + ")");
7155            }
7156            if (pi.uriPermissionPatterns != null) {
7157                final int N = pi.uriPermissionPatterns.length;
7158                boolean allowed = false;
7159                for (int i=0; i<N; i++) {
7160                    if (pi.uriPermissionPatterns[i] != null
7161                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7162                        allowed = true;
7163                        break;
7164                    }
7165                }
7166                if (!allowed) {
7167                    throw new SecurityException("Provider " + pi.packageName
7168                            + "/" + pi.name
7169                            + " does not allow granting of permission to path of Uri "
7170                            + grantUri);
7171                }
7172            }
7173        }
7174
7175        // Third...  does the caller itself have permission to access
7176        // this uri?
7177        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7178            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7179                // Require they hold a strong enough Uri permission
7180                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7181                    throw new SecurityException("Uid " + callingUid
7182                            + " does not have permission to uri " + grantUri);
7183                }
7184            }
7185        }
7186        return targetUid;
7187    }
7188
7189    /**
7190     * @param uri This uri must NOT contain an embedded userId.
7191     * @param userId The userId in which the uri is to be resolved.
7192     */
7193    @Override
7194    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7195            final int modeFlags, int userId) {
7196        enforceNotIsolatedCaller("checkGrantUriPermission");
7197        synchronized(this) {
7198            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7199                    new GrantUri(userId, uri, false), modeFlags, -1);
7200        }
7201    }
7202
7203    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7204            final int modeFlags, UriPermissionOwner owner) {
7205        if (!Intent.isAccessUriMode(modeFlags)) {
7206            return;
7207        }
7208
7209        // So here we are: the caller has the assumed permission
7210        // to the uri, and the target doesn't.  Let's now give this to
7211        // the target.
7212
7213        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7214                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7215
7216        final String authority = grantUri.uri.getAuthority();
7217        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7218        if (pi == null) {
7219            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7220            return;
7221        }
7222
7223        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7224            grantUri.prefix = true;
7225        }
7226        final UriPermission perm = findOrCreateUriPermissionLocked(
7227                pi.packageName, targetPkg, targetUid, grantUri);
7228        perm.grantModes(modeFlags, owner);
7229    }
7230
7231    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7232            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7233        if (targetPkg == null) {
7234            throw new NullPointerException("targetPkg");
7235        }
7236        int targetUid;
7237        final IPackageManager pm = AppGlobals.getPackageManager();
7238        try {
7239            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7240        } catch (RemoteException ex) {
7241            return;
7242        }
7243
7244        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7245                targetUid);
7246        if (targetUid < 0) {
7247            return;
7248        }
7249
7250        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7251                owner);
7252    }
7253
7254    static class NeededUriGrants extends ArrayList<GrantUri> {
7255        final String targetPkg;
7256        final int targetUid;
7257        final int flags;
7258
7259        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7260            this.targetPkg = targetPkg;
7261            this.targetUid = targetUid;
7262            this.flags = flags;
7263        }
7264    }
7265
7266    /**
7267     * Like checkGrantUriPermissionLocked, but takes an Intent.
7268     */
7269    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7270            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7271        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7272                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7273                + " clip=" + (intent != null ? intent.getClipData() : null)
7274                + " from " + intent + "; flags=0x"
7275                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7276
7277        if (targetPkg == null) {
7278            throw new NullPointerException("targetPkg");
7279        }
7280
7281        if (intent == null) {
7282            return null;
7283        }
7284        Uri data = intent.getData();
7285        ClipData clip = intent.getClipData();
7286        if (data == null && clip == null) {
7287            return null;
7288        }
7289        // Default userId for uris in the intent (if they don't specify it themselves)
7290        int contentUserHint = intent.getContentUserHint();
7291        if (contentUserHint == UserHandle.USER_CURRENT) {
7292            contentUserHint = UserHandle.getUserId(callingUid);
7293        }
7294        final IPackageManager pm = AppGlobals.getPackageManager();
7295        int targetUid;
7296        if (needed != null) {
7297            targetUid = needed.targetUid;
7298        } else {
7299            try {
7300                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7301            } catch (RemoteException ex) {
7302                return null;
7303            }
7304            if (targetUid < 0) {
7305                if (DEBUG_URI_PERMISSION) {
7306                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7307                            + " on user " + targetUserId);
7308                }
7309                return null;
7310            }
7311        }
7312        if (data != null) {
7313            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7314            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7315                    targetUid);
7316            if (targetUid > 0) {
7317                if (needed == null) {
7318                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7319                }
7320                needed.add(grantUri);
7321            }
7322        }
7323        if (clip != null) {
7324            for (int i=0; i<clip.getItemCount(); i++) {
7325                Uri uri = clip.getItemAt(i).getUri();
7326                if (uri != null) {
7327                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7328                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7329                            targetUid);
7330                    if (targetUid > 0) {
7331                        if (needed == null) {
7332                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7333                        }
7334                        needed.add(grantUri);
7335                    }
7336                } else {
7337                    Intent clipIntent = clip.getItemAt(i).getIntent();
7338                    if (clipIntent != null) {
7339                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7340                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7341                        if (newNeeded != null) {
7342                            needed = newNeeded;
7343                        }
7344                    }
7345                }
7346            }
7347        }
7348
7349        return needed;
7350    }
7351
7352    /**
7353     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7354     */
7355    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7356            UriPermissionOwner owner) {
7357        if (needed != null) {
7358            for (int i=0; i<needed.size(); i++) {
7359                GrantUri grantUri = needed.get(i);
7360                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7361                        grantUri, needed.flags, owner);
7362            }
7363        }
7364    }
7365
7366    void grantUriPermissionFromIntentLocked(int callingUid,
7367            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7368        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7369                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7370        if (needed == null) {
7371            return;
7372        }
7373
7374        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7375    }
7376
7377    /**
7378     * @param uri This uri must NOT contain an embedded userId.
7379     * @param userId The userId in which the uri is to be resolved.
7380     */
7381    @Override
7382    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7383            final int modeFlags, int userId) {
7384        enforceNotIsolatedCaller("grantUriPermission");
7385        GrantUri grantUri = new GrantUri(userId, uri, false);
7386        synchronized(this) {
7387            final ProcessRecord r = getRecordForAppLocked(caller);
7388            if (r == null) {
7389                throw new SecurityException("Unable to find app for caller "
7390                        + caller
7391                        + " when granting permission to uri " + grantUri);
7392            }
7393            if (targetPkg == null) {
7394                throw new IllegalArgumentException("null target");
7395            }
7396            if (grantUri == null) {
7397                throw new IllegalArgumentException("null uri");
7398            }
7399
7400            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7401                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7402                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7403                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7404
7405            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7406                    UserHandle.getUserId(r.uid));
7407        }
7408    }
7409
7410    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7411        if (perm.modeFlags == 0) {
7412            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7413                    perm.targetUid);
7414            if (perms != null) {
7415                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7416                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7417
7418                perms.remove(perm.uri);
7419                if (perms.isEmpty()) {
7420                    mGrantedUriPermissions.remove(perm.targetUid);
7421                }
7422            }
7423        }
7424    }
7425
7426    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7427        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7428
7429        final IPackageManager pm = AppGlobals.getPackageManager();
7430        final String authority = grantUri.uri.getAuthority();
7431        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7432        if (pi == null) {
7433            Slog.w(TAG, "No content provider found for permission revoke: "
7434                    + grantUri.toSafeString());
7435            return;
7436        }
7437
7438        // Does the caller have this permission on the URI?
7439        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7440            // If they don't have direct access to the URI, then revoke any
7441            // ownerless URI permissions that have been granted to them.
7442            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7443            if (perms != null) {
7444                boolean persistChanged = false;
7445                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7446                    final UriPermission perm = it.next();
7447                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7448                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7449                        if (DEBUG_URI_PERMISSION)
7450                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7451                                    " permission to " + perm.uri);
7452                        persistChanged |= perm.revokeModes(
7453                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7454                        if (perm.modeFlags == 0) {
7455                            it.remove();
7456                        }
7457                    }
7458                }
7459                if (perms.isEmpty()) {
7460                    mGrantedUriPermissions.remove(callingUid);
7461                }
7462                if (persistChanged) {
7463                    schedulePersistUriGrants();
7464                }
7465            }
7466            return;
7467        }
7468
7469        boolean persistChanged = false;
7470
7471        // Go through all of the permissions and remove any that match.
7472        int N = mGrantedUriPermissions.size();
7473        for (int i = 0; i < N; i++) {
7474            final int targetUid = mGrantedUriPermissions.keyAt(i);
7475            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7476
7477            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7478                final UriPermission perm = it.next();
7479                if (perm.uri.sourceUserId == grantUri.sourceUserId
7480                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7481                    if (DEBUG_URI_PERMISSION)
7482                        Slog.v(TAG,
7483                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7484                    persistChanged |= perm.revokeModes(
7485                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7486                    if (perm.modeFlags == 0) {
7487                        it.remove();
7488                    }
7489                }
7490            }
7491
7492            if (perms.isEmpty()) {
7493                mGrantedUriPermissions.remove(targetUid);
7494                N--;
7495                i--;
7496            }
7497        }
7498
7499        if (persistChanged) {
7500            schedulePersistUriGrants();
7501        }
7502    }
7503
7504    /**
7505     * @param uri This uri must NOT contain an embedded userId.
7506     * @param userId The userId in which the uri is to be resolved.
7507     */
7508    @Override
7509    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7510            int userId) {
7511        enforceNotIsolatedCaller("revokeUriPermission");
7512        synchronized(this) {
7513            final ProcessRecord r = getRecordForAppLocked(caller);
7514            if (r == null) {
7515                throw new SecurityException("Unable to find app for caller "
7516                        + caller
7517                        + " when revoking permission to uri " + uri);
7518            }
7519            if (uri == null) {
7520                Slog.w(TAG, "revokeUriPermission: null uri");
7521                return;
7522            }
7523
7524            if (!Intent.isAccessUriMode(modeFlags)) {
7525                return;
7526            }
7527
7528            final IPackageManager pm = AppGlobals.getPackageManager();
7529            final String authority = uri.getAuthority();
7530            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7531            if (pi == null) {
7532                Slog.w(TAG, "No content provider found for permission revoke: "
7533                        + uri.toSafeString());
7534                return;
7535            }
7536
7537            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7538        }
7539    }
7540
7541    /**
7542     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7543     * given package.
7544     *
7545     * @param packageName Package name to match, or {@code null} to apply to all
7546     *            packages.
7547     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7548     *            to all users.
7549     * @param persistable If persistable grants should be removed.
7550     */
7551    private void removeUriPermissionsForPackageLocked(
7552            String packageName, int userHandle, boolean persistable) {
7553        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7554            throw new IllegalArgumentException("Must narrow by either package or user");
7555        }
7556
7557        boolean persistChanged = false;
7558
7559        int N = mGrantedUriPermissions.size();
7560        for (int i = 0; i < N; i++) {
7561            final int targetUid = mGrantedUriPermissions.keyAt(i);
7562            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7563
7564            // Only inspect grants matching user
7565            if (userHandle == UserHandle.USER_ALL
7566                    || userHandle == UserHandle.getUserId(targetUid)) {
7567                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7568                    final UriPermission perm = it.next();
7569
7570                    // Only inspect grants matching package
7571                    if (packageName == null || perm.sourcePkg.equals(packageName)
7572                            || perm.targetPkg.equals(packageName)) {
7573                        persistChanged |= perm.revokeModes(persistable
7574                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7575
7576                        // Only remove when no modes remain; any persisted grants
7577                        // will keep this alive.
7578                        if (perm.modeFlags == 0) {
7579                            it.remove();
7580                        }
7581                    }
7582                }
7583
7584                if (perms.isEmpty()) {
7585                    mGrantedUriPermissions.remove(targetUid);
7586                    N--;
7587                    i--;
7588                }
7589            }
7590        }
7591
7592        if (persistChanged) {
7593            schedulePersistUriGrants();
7594        }
7595    }
7596
7597    @Override
7598    public IBinder newUriPermissionOwner(String name) {
7599        enforceNotIsolatedCaller("newUriPermissionOwner");
7600        synchronized(this) {
7601            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7602            return owner.getExternalTokenLocked();
7603        }
7604    }
7605
7606    /**
7607     * @param uri This uri must NOT contain an embedded userId.
7608     * @param sourceUserId The userId in which the uri is to be resolved.
7609     * @param targetUserId The userId of the app that receives the grant.
7610     */
7611    @Override
7612    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7613            final int modeFlags, int sourceUserId, int targetUserId) {
7614        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7615                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7616        synchronized(this) {
7617            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7618            if (owner == null) {
7619                throw new IllegalArgumentException("Unknown owner: " + token);
7620            }
7621            if (fromUid != Binder.getCallingUid()) {
7622                if (Binder.getCallingUid() != Process.myUid()) {
7623                    // Only system code can grant URI permissions on behalf
7624                    // of other users.
7625                    throw new SecurityException("nice try");
7626                }
7627            }
7628            if (targetPkg == null) {
7629                throw new IllegalArgumentException("null target");
7630            }
7631            if (uri == null) {
7632                throw new IllegalArgumentException("null uri");
7633            }
7634
7635            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7636                    modeFlags, owner, targetUserId);
7637        }
7638    }
7639
7640    /**
7641     * @param uri This uri must NOT contain an embedded userId.
7642     * @param userId The userId in which the uri is to be resolved.
7643     */
7644    @Override
7645    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7646        synchronized(this) {
7647            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7648            if (owner == null) {
7649                throw new IllegalArgumentException("Unknown owner: " + token);
7650            }
7651
7652            if (uri == null) {
7653                owner.removeUriPermissionsLocked(mode);
7654            } else {
7655                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7656            }
7657        }
7658    }
7659
7660    private void schedulePersistUriGrants() {
7661        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7662            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7663                    10 * DateUtils.SECOND_IN_MILLIS);
7664        }
7665    }
7666
7667    private void writeGrantedUriPermissions() {
7668        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7669
7670        // Snapshot permissions so we can persist without lock
7671        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7672        synchronized (this) {
7673            final int size = mGrantedUriPermissions.size();
7674            for (int i = 0; i < size; i++) {
7675                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7676                for (UriPermission perm : perms.values()) {
7677                    if (perm.persistedModeFlags != 0) {
7678                        persist.add(perm.snapshot());
7679                    }
7680                }
7681            }
7682        }
7683
7684        FileOutputStream fos = null;
7685        try {
7686            fos = mGrantFile.startWrite();
7687
7688            XmlSerializer out = new FastXmlSerializer();
7689            out.setOutput(fos, "utf-8");
7690            out.startDocument(null, true);
7691            out.startTag(null, TAG_URI_GRANTS);
7692            for (UriPermission.Snapshot perm : persist) {
7693                out.startTag(null, TAG_URI_GRANT);
7694                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7695                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7696                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7697                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7698                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7699                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7700                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7701                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7702                out.endTag(null, TAG_URI_GRANT);
7703            }
7704            out.endTag(null, TAG_URI_GRANTS);
7705            out.endDocument();
7706
7707            mGrantFile.finishWrite(fos);
7708        } catch (IOException e) {
7709            if (fos != null) {
7710                mGrantFile.failWrite(fos);
7711            }
7712        }
7713    }
7714
7715    private void readGrantedUriPermissionsLocked() {
7716        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7717
7718        final long now = System.currentTimeMillis();
7719
7720        FileInputStream fis = null;
7721        try {
7722            fis = mGrantFile.openRead();
7723            final XmlPullParser in = Xml.newPullParser();
7724            in.setInput(fis, null);
7725
7726            int type;
7727            while ((type = in.next()) != END_DOCUMENT) {
7728                final String tag = in.getName();
7729                if (type == START_TAG) {
7730                    if (TAG_URI_GRANT.equals(tag)) {
7731                        final int sourceUserId;
7732                        final int targetUserId;
7733                        final int userHandle = readIntAttribute(in,
7734                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7735                        if (userHandle != UserHandle.USER_NULL) {
7736                            // For backwards compatibility.
7737                            sourceUserId = userHandle;
7738                            targetUserId = userHandle;
7739                        } else {
7740                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7741                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7742                        }
7743                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7744                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7745                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7746                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7747                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7748                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7749
7750                        // Sanity check that provider still belongs to source package
7751                        final ProviderInfo pi = getProviderInfoLocked(
7752                                uri.getAuthority(), sourceUserId);
7753                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7754                            int targetUid = -1;
7755                            try {
7756                                targetUid = AppGlobals.getPackageManager()
7757                                        .getPackageUid(targetPkg, targetUserId);
7758                            } catch (RemoteException e) {
7759                            }
7760                            if (targetUid != -1) {
7761                                final UriPermission perm = findOrCreateUriPermissionLocked(
7762                                        sourcePkg, targetPkg, targetUid,
7763                                        new GrantUri(sourceUserId, uri, prefix));
7764                                perm.initPersistedModes(modeFlags, createdTime);
7765                            }
7766                        } else {
7767                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7768                                    + " but instead found " + pi);
7769                        }
7770                    }
7771                }
7772            }
7773        } catch (FileNotFoundException e) {
7774            // Missing grants is okay
7775        } catch (IOException e) {
7776            Slog.wtf(TAG, "Failed reading Uri grants", e);
7777        } catch (XmlPullParserException e) {
7778            Slog.wtf(TAG, "Failed reading Uri grants", e);
7779        } finally {
7780            IoUtils.closeQuietly(fis);
7781        }
7782    }
7783
7784    /**
7785     * @param uri This uri must NOT contain an embedded userId.
7786     * @param userId The userId in which the uri is to be resolved.
7787     */
7788    @Override
7789    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7790        enforceNotIsolatedCaller("takePersistableUriPermission");
7791
7792        Preconditions.checkFlagsArgument(modeFlags,
7793                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7794
7795        synchronized (this) {
7796            final int callingUid = Binder.getCallingUid();
7797            boolean persistChanged = false;
7798            GrantUri grantUri = new GrantUri(userId, uri, false);
7799
7800            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7801                    new GrantUri(userId, uri, false));
7802            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7803                    new GrantUri(userId, uri, true));
7804
7805            final boolean exactValid = (exactPerm != null)
7806                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7807            final boolean prefixValid = (prefixPerm != null)
7808                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7809
7810            if (!(exactValid || prefixValid)) {
7811                throw new SecurityException("No persistable permission grants found for UID "
7812                        + callingUid + " and Uri " + grantUri.toSafeString());
7813            }
7814
7815            if (exactValid) {
7816                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7817            }
7818            if (prefixValid) {
7819                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7820            }
7821
7822            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7823
7824            if (persistChanged) {
7825                schedulePersistUriGrants();
7826            }
7827        }
7828    }
7829
7830    /**
7831     * @param uri This uri must NOT contain an embedded userId.
7832     * @param userId The userId in which the uri is to be resolved.
7833     */
7834    @Override
7835    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7836        enforceNotIsolatedCaller("releasePersistableUriPermission");
7837
7838        Preconditions.checkFlagsArgument(modeFlags,
7839                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7840
7841        synchronized (this) {
7842            final int callingUid = Binder.getCallingUid();
7843            boolean persistChanged = false;
7844
7845            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7846                    new GrantUri(userId, uri, false));
7847            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7848                    new GrantUri(userId, uri, true));
7849            if (exactPerm == null && prefixPerm == null) {
7850                throw new SecurityException("No permission grants found for UID " + callingUid
7851                        + " and Uri " + uri.toSafeString());
7852            }
7853
7854            if (exactPerm != null) {
7855                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7856                removeUriPermissionIfNeededLocked(exactPerm);
7857            }
7858            if (prefixPerm != null) {
7859                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7860                removeUriPermissionIfNeededLocked(prefixPerm);
7861            }
7862
7863            if (persistChanged) {
7864                schedulePersistUriGrants();
7865            }
7866        }
7867    }
7868
7869    /**
7870     * Prune any older {@link UriPermission} for the given UID until outstanding
7871     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7872     *
7873     * @return if any mutations occured that require persisting.
7874     */
7875    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7876        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7877        if (perms == null) return false;
7878        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7879
7880        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7881        for (UriPermission perm : perms.values()) {
7882            if (perm.persistedModeFlags != 0) {
7883                persisted.add(perm);
7884            }
7885        }
7886
7887        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7888        if (trimCount <= 0) return false;
7889
7890        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7891        for (int i = 0; i < trimCount; i++) {
7892            final UriPermission perm = persisted.get(i);
7893
7894            if (DEBUG_URI_PERMISSION) {
7895                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7896            }
7897
7898            perm.releasePersistableModes(~0);
7899            removeUriPermissionIfNeededLocked(perm);
7900        }
7901
7902        return true;
7903    }
7904
7905    @Override
7906    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7907            String packageName, boolean incoming) {
7908        enforceNotIsolatedCaller("getPersistedUriPermissions");
7909        Preconditions.checkNotNull(packageName, "packageName");
7910
7911        final int callingUid = Binder.getCallingUid();
7912        final IPackageManager pm = AppGlobals.getPackageManager();
7913        try {
7914            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7915            if (packageUid != callingUid) {
7916                throw new SecurityException(
7917                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7918            }
7919        } catch (RemoteException e) {
7920            throw new SecurityException("Failed to verify package name ownership");
7921        }
7922
7923        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7924        synchronized (this) {
7925            if (incoming) {
7926                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7927                        callingUid);
7928                if (perms == null) {
7929                    Slog.w(TAG, "No permission grants found for " + packageName);
7930                } else {
7931                    for (UriPermission perm : perms.values()) {
7932                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7933                            result.add(perm.buildPersistedPublicApiObject());
7934                        }
7935                    }
7936                }
7937            } else {
7938                final int size = mGrantedUriPermissions.size();
7939                for (int i = 0; i < size; i++) {
7940                    final ArrayMap<GrantUri, UriPermission> perms =
7941                            mGrantedUriPermissions.valueAt(i);
7942                    for (UriPermission perm : perms.values()) {
7943                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7944                            result.add(perm.buildPersistedPublicApiObject());
7945                        }
7946                    }
7947                }
7948            }
7949        }
7950        return new ParceledListSlice<android.content.UriPermission>(result);
7951    }
7952
7953    @Override
7954    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7955        synchronized (this) {
7956            ProcessRecord app =
7957                who != null ? getRecordForAppLocked(who) : null;
7958            if (app == null) return;
7959
7960            Message msg = Message.obtain();
7961            msg.what = WAIT_FOR_DEBUGGER_MSG;
7962            msg.obj = app;
7963            msg.arg1 = waiting ? 1 : 0;
7964            mHandler.sendMessage(msg);
7965        }
7966    }
7967
7968    @Override
7969    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7970        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7971        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7972        outInfo.availMem = Process.getFreeMemory();
7973        outInfo.totalMem = Process.getTotalMemory();
7974        outInfo.threshold = homeAppMem;
7975        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7976        outInfo.hiddenAppThreshold = cachedAppMem;
7977        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7978                ProcessList.SERVICE_ADJ);
7979        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7980                ProcessList.VISIBLE_APP_ADJ);
7981        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7982                ProcessList.FOREGROUND_APP_ADJ);
7983    }
7984
7985    // =========================================================
7986    // TASK MANAGEMENT
7987    // =========================================================
7988
7989    @Override
7990    public List<IAppTask> getAppTasks(String callingPackage) {
7991        int callingUid = Binder.getCallingUid();
7992        long ident = Binder.clearCallingIdentity();
7993
7994        synchronized(this) {
7995            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7996            try {
7997                if (localLOGV) Slog.v(TAG, "getAppTasks");
7998
7999                final int N = mRecentTasks.size();
8000                for (int i = 0; i < N; i++) {
8001                    TaskRecord tr = mRecentTasks.get(i);
8002                    // Skip tasks that do not match the caller.  We don't need to verify
8003                    // callingPackage, because we are also limiting to callingUid and know
8004                    // that will limit to the correct security sandbox.
8005                    if (tr.effectiveUid != callingUid) {
8006                        continue;
8007                    }
8008                    Intent intent = tr.getBaseIntent();
8009                    if (intent == null ||
8010                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8011                        continue;
8012                    }
8013                    ActivityManager.RecentTaskInfo taskInfo =
8014                            createRecentTaskInfoFromTaskRecord(tr);
8015                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8016                    list.add(taskImpl);
8017                }
8018            } finally {
8019                Binder.restoreCallingIdentity(ident);
8020            }
8021            return list;
8022        }
8023    }
8024
8025    @Override
8026    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8027        final int callingUid = Binder.getCallingUid();
8028        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8029
8030        synchronized(this) {
8031            if (localLOGV) Slog.v(
8032                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8033
8034            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8035                    callingUid);
8036
8037            // TODO: Improve with MRU list from all ActivityStacks.
8038            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8039        }
8040
8041        return list;
8042    }
8043
8044    /**
8045     * Creates a new RecentTaskInfo from a TaskRecord.
8046     */
8047    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8048        // Update the task description to reflect any changes in the task stack
8049        tr.updateTaskDescription();
8050
8051        // Compose the recent task info
8052        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8053        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8054        rti.persistentId = tr.taskId;
8055        rti.baseIntent = new Intent(tr.getBaseIntent());
8056        rti.origActivity = tr.origActivity;
8057        rti.description = tr.lastDescription;
8058        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8059        rti.userId = tr.userId;
8060        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8061        rti.firstActiveTime = tr.firstActiveTime;
8062        rti.lastActiveTime = tr.lastActiveTime;
8063        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8064        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8065        return rti;
8066    }
8067
8068    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8069        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8070                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8071        if (!allowed) {
8072            if (checkPermission(android.Manifest.permission.GET_TASKS,
8073                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8074                // Temporary compatibility: some existing apps on the system image may
8075                // still be requesting the old permission and not switched to the new
8076                // one; if so, we'll still allow them full access.  This means we need
8077                // to see if they are holding the old permission and are a system app.
8078                try {
8079                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8080                        allowed = true;
8081                        Slog.w(TAG, caller + ": caller " + callingUid
8082                                + " is using old GET_TASKS but privileged; allowing");
8083                    }
8084                } catch (RemoteException e) {
8085                }
8086            }
8087        }
8088        if (!allowed) {
8089            Slog.w(TAG, caller + ": caller " + callingUid
8090                    + " does not hold GET_TASKS; limiting output");
8091        }
8092        return allowed;
8093    }
8094
8095    @Override
8096    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8097        final int callingUid = Binder.getCallingUid();
8098        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8099                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8100
8101        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8102        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8103        synchronized (this) {
8104            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8105                    callingUid);
8106            final boolean detailed = checkCallingPermission(
8107                    android.Manifest.permission.GET_DETAILED_TASKS)
8108                    == PackageManager.PERMISSION_GRANTED;
8109
8110            final int N = mRecentTasks.size();
8111            ArrayList<ActivityManager.RecentTaskInfo> res
8112                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8113                            maxNum < N ? maxNum : N);
8114
8115            final Set<Integer> includedUsers;
8116            if (includeProfiles) {
8117                includedUsers = getProfileIdsLocked(userId);
8118            } else {
8119                includedUsers = new HashSet<Integer>();
8120            }
8121            includedUsers.add(Integer.valueOf(userId));
8122
8123            for (int i=0; i<N && maxNum > 0; i++) {
8124                TaskRecord tr = mRecentTasks.get(i);
8125                // Only add calling user or related users recent tasks
8126                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8127                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8128                    continue;
8129                }
8130
8131                // Return the entry if desired by the caller.  We always return
8132                // the first entry, because callers always expect this to be the
8133                // foreground app.  We may filter others if the caller has
8134                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8135                // we should exclude the entry.
8136
8137                if (i == 0
8138                        || withExcluded
8139                        || (tr.intent == null)
8140                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8141                                == 0)) {
8142                    if (!allowed) {
8143                        // If the caller doesn't have the GET_TASKS permission, then only
8144                        // allow them to see a small subset of tasks -- their own and home.
8145                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8146                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8147                            continue;
8148                        }
8149                    }
8150                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8151                        if (tr.stack != null && tr.stack.isHomeStack()) {
8152                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8153                            continue;
8154                        }
8155                    }
8156                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8157                        // Don't include auto remove tasks that are finished or finishing.
8158                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8159                                + tr);
8160                        continue;
8161                    }
8162                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8163                            && !tr.isAvailable) {
8164                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8165                        continue;
8166                    }
8167
8168                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8169                    if (!detailed) {
8170                        rti.baseIntent.replaceExtras((Bundle)null);
8171                    }
8172
8173                    res.add(rti);
8174                    maxNum--;
8175                }
8176            }
8177            return res;
8178        }
8179    }
8180
8181    private TaskRecord taskForIdLocked(int id) {
8182        final TaskRecord task = recentTaskForIdLocked(id);
8183        if (task != null) {
8184            return task;
8185        }
8186
8187        // Don't give up. Sometimes it just hasn't made it to recents yet.
8188        return mStackSupervisor.anyTaskForIdLocked(id);
8189    }
8190
8191    private TaskRecord recentTaskForIdLocked(int id) {
8192        final int N = mRecentTasks.size();
8193            for (int i=0; i<N; i++) {
8194                TaskRecord tr = mRecentTasks.get(i);
8195                if (tr.taskId == id) {
8196                    return tr;
8197                }
8198            }
8199            return null;
8200    }
8201
8202    @Override
8203    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8204        synchronized (this) {
8205            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8206                    "getTaskThumbnail()");
8207            TaskRecord tr = recentTaskForIdLocked(id);
8208            if (tr != null) {
8209                return tr.getTaskThumbnailLocked();
8210            }
8211        }
8212        return null;
8213    }
8214
8215    @Override
8216    public int addAppTask(IBinder activityToken, Intent intent,
8217            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8218        final int callingUid = Binder.getCallingUid();
8219        final long callingIdent = Binder.clearCallingIdentity();
8220
8221        try {
8222            synchronized (this) {
8223                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8224                if (r == null) {
8225                    throw new IllegalArgumentException("Activity does not exist; token="
8226                            + activityToken);
8227                }
8228                ComponentName comp = intent.getComponent();
8229                if (comp == null) {
8230                    throw new IllegalArgumentException("Intent " + intent
8231                            + " must specify explicit component");
8232                }
8233                if (thumbnail.getWidth() != mThumbnailWidth
8234                        || thumbnail.getHeight() != mThumbnailHeight) {
8235                    throw new IllegalArgumentException("Bad thumbnail size: got "
8236                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8237                            + mThumbnailWidth + "x" + mThumbnailHeight);
8238                }
8239                if (intent.getSelector() != null) {
8240                    intent.setSelector(null);
8241                }
8242                if (intent.getSourceBounds() != null) {
8243                    intent.setSourceBounds(null);
8244                }
8245                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8246                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8247                        // The caller has added this as an auto-remove task...  that makes no
8248                        // sense, so turn off auto-remove.
8249                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8250                    }
8251                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8252                    // Must be a new task.
8253                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8254                }
8255                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8256                    mLastAddedTaskActivity = null;
8257                }
8258                ActivityInfo ainfo = mLastAddedTaskActivity;
8259                if (ainfo == null) {
8260                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8261                            comp, 0, UserHandle.getUserId(callingUid));
8262                    if (ainfo.applicationInfo.uid != callingUid) {
8263                        throw new SecurityException(
8264                                "Can't add task for another application: target uid="
8265                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8266                    }
8267                }
8268
8269                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8270                        intent, description);
8271
8272                int trimIdx = trimRecentsForTaskLocked(task, false);
8273                if (trimIdx >= 0) {
8274                    // If this would have caused a trim, then we'll abort because that
8275                    // means it would be added at the end of the list but then just removed.
8276                    return INVALID_TASK_ID;
8277                }
8278
8279                final int N = mRecentTasks.size();
8280                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8281                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8282                    tr.removedFromRecents();
8283                }
8284
8285                task.inRecents = true;
8286                mRecentTasks.add(task);
8287                r.task.stack.addTask(task, false, false);
8288
8289                task.setLastThumbnail(thumbnail);
8290                task.freeLastThumbnail();
8291
8292                return task.taskId;
8293            }
8294        } finally {
8295            Binder.restoreCallingIdentity(callingIdent);
8296        }
8297    }
8298
8299    @Override
8300    public Point getAppTaskThumbnailSize() {
8301        synchronized (this) {
8302            return new Point(mThumbnailWidth,  mThumbnailHeight);
8303        }
8304    }
8305
8306    @Override
8307    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8308        synchronized (this) {
8309            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8310            if (r != null) {
8311                r.setTaskDescription(td);
8312                r.task.updateTaskDescription();
8313            }
8314        }
8315    }
8316
8317    @Override
8318    public Bitmap getTaskDescriptionIcon(String filename) {
8319        if (!FileUtils.isValidExtFilename(filename)
8320                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8321            throw new IllegalArgumentException("Bad filename: " + filename);
8322        }
8323        return mTaskPersister.getTaskDescriptionIcon(filename);
8324    }
8325
8326    @Override
8327    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8328            throws RemoteException {
8329        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8330                opts.getCustomInPlaceResId() == 0) {
8331            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8332                    "with valid animation");
8333        }
8334        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8335        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8336                opts.getCustomInPlaceResId());
8337        mWindowManager.executeAppTransition();
8338    }
8339
8340    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8341        mRecentTasks.remove(tr);
8342        tr.removedFromRecents();
8343        ComponentName component = tr.getBaseIntent().getComponent();
8344        if (component == null) {
8345            Slog.w(TAG, "No component for base intent of task: " + tr);
8346            return;
8347        }
8348
8349        if (!killProcess) {
8350            return;
8351        }
8352
8353        // Determine if the process(es) for this task should be killed.
8354        final String pkg = component.getPackageName();
8355        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8356        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8357        for (int i = 0; i < pmap.size(); i++) {
8358
8359            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8360            for (int j = 0; j < uids.size(); j++) {
8361                ProcessRecord proc = uids.valueAt(j);
8362                if (proc.userId != tr.userId) {
8363                    // Don't kill process for a different user.
8364                    continue;
8365                }
8366                if (proc == mHomeProcess) {
8367                    // Don't kill the home process along with tasks from the same package.
8368                    continue;
8369                }
8370                if (!proc.pkgList.containsKey(pkg)) {
8371                    // Don't kill process that is not associated with this task.
8372                    continue;
8373                }
8374
8375                for (int k = 0; k < proc.activities.size(); k++) {
8376                    TaskRecord otherTask = proc.activities.get(k).task;
8377                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8378                        // Don't kill process(es) that has an activity in a different task that is
8379                        // also in recents.
8380                        return;
8381                    }
8382                }
8383
8384                // Add process to kill list.
8385                procsToKill.add(proc);
8386            }
8387        }
8388
8389        // Find any running services associated with this app and stop if needed.
8390        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8391
8392        // Kill the running processes.
8393        for (int i = 0; i < procsToKill.size(); i++) {
8394            ProcessRecord pr = procsToKill.get(i);
8395            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8396                pr.kill("remove task", true);
8397            } else {
8398                pr.waitingToKill = "remove task";
8399            }
8400        }
8401    }
8402
8403    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8404        // Remove all tasks with activities in the specified package from the list of recent tasks
8405        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8406            TaskRecord tr = mRecentTasks.get(i);
8407            if (tr.userId != userId) continue;
8408
8409            ComponentName cn = tr.intent.getComponent();
8410            if (cn != null && cn.getPackageName().equals(packageName)) {
8411                // If the package name matches, remove the task.
8412                removeTaskByIdLocked(tr.taskId, true);
8413            }
8414        }
8415    }
8416
8417    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8418        final IPackageManager pm = AppGlobals.getPackageManager();
8419        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8420
8421        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8422            TaskRecord tr = mRecentTasks.get(i);
8423            if (tr.userId != userId) continue;
8424
8425            ComponentName cn = tr.intent.getComponent();
8426            if (cn != null && cn.getPackageName().equals(packageName)) {
8427                // Skip if component still exists in the package.
8428                if (componentsKnownToExist.contains(cn)) continue;
8429
8430                try {
8431                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8432                    if (info != null) {
8433                        componentsKnownToExist.add(cn);
8434                    } else {
8435                        removeTaskByIdLocked(tr.taskId, false);
8436                    }
8437                } catch (RemoteException e) {
8438                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8439                }
8440            }
8441        }
8442    }
8443
8444    /**
8445     * Removes the task with the specified task id.
8446     *
8447     * @param taskId Identifier of the task to be removed.
8448     * @param killProcess Kill any process associated with the task if possible.
8449     * @return Returns true if the given task was found and removed.
8450     */
8451    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8452        TaskRecord tr = taskForIdLocked(taskId);
8453        if (tr != null) {
8454            tr.removeTaskActivitiesLocked();
8455            cleanUpRemovedTaskLocked(tr, killProcess);
8456            if (tr.isPersistable) {
8457                notifyTaskPersisterLocked(null, true);
8458            }
8459            return true;
8460        }
8461        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8462        return false;
8463    }
8464
8465    @Override
8466    public boolean removeTask(int taskId) {
8467        synchronized (this) {
8468            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8469                    "removeTask()");
8470            long ident = Binder.clearCallingIdentity();
8471            try {
8472                return removeTaskByIdLocked(taskId, true);
8473            } finally {
8474                Binder.restoreCallingIdentity(ident);
8475            }
8476        }
8477    }
8478
8479    /**
8480     * TODO: Add mController hook
8481     */
8482    @Override
8483    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8484        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8485                "moveTaskToFront()");
8486
8487        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8488        synchronized(this) {
8489            moveTaskToFrontLocked(taskId, flags, options);
8490        }
8491    }
8492
8493    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8494        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8495                Binder.getCallingUid(), -1, -1, "Task to front")) {
8496            ActivityOptions.abort(options);
8497            return;
8498        }
8499        final long origId = Binder.clearCallingIdentity();
8500        try {
8501            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8502            if (task == null) {
8503                Slog.d(TAG, "Could not find task for id: "+ taskId);
8504                return;
8505            }
8506            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8507                mStackSupervisor.showLockTaskToast();
8508                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8509                return;
8510            }
8511            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8512            if (prev != null && prev.isRecentsActivity()) {
8513                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8514            }
8515            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8516        } finally {
8517            Binder.restoreCallingIdentity(origId);
8518        }
8519        ActivityOptions.abort(options);
8520    }
8521
8522    @Override
8523    public void moveTaskToBack(int taskId) {
8524        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8525                "moveTaskToBack()");
8526
8527        synchronized(this) {
8528            TaskRecord tr = taskForIdLocked(taskId);
8529            if (tr != null) {
8530                if (tr == mStackSupervisor.mLockTaskModeTask) {
8531                    mStackSupervisor.showLockTaskToast();
8532                    return;
8533                }
8534                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8535                ActivityStack stack = tr.stack;
8536                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8537                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8538                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8539                        return;
8540                    }
8541                }
8542                final long origId = Binder.clearCallingIdentity();
8543                try {
8544                    stack.moveTaskToBackLocked(taskId, null);
8545                } finally {
8546                    Binder.restoreCallingIdentity(origId);
8547                }
8548            }
8549        }
8550    }
8551
8552    /**
8553     * Moves an activity, and all of the other activities within the same task, to the bottom
8554     * of the history stack.  The activity's order within the task is unchanged.
8555     *
8556     * @param token A reference to the activity we wish to move
8557     * @param nonRoot If false then this only works if the activity is the root
8558     *                of a task; if true it will work for any activity in a task.
8559     * @return Returns true if the move completed, false if not.
8560     */
8561    @Override
8562    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8563        enforceNotIsolatedCaller("moveActivityTaskToBack");
8564        synchronized(this) {
8565            final long origId = Binder.clearCallingIdentity();
8566            try {
8567                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8568                if (taskId >= 0) {
8569                    if ((mStackSupervisor.mLockTaskModeTask != null)
8570                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8571                        mStackSupervisor.showLockTaskToast();
8572                        return false;
8573                    }
8574                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8575                }
8576            } finally {
8577                Binder.restoreCallingIdentity(origId);
8578            }
8579        }
8580        return false;
8581    }
8582
8583    @Override
8584    public void moveTaskBackwards(int task) {
8585        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8586                "moveTaskBackwards()");
8587
8588        synchronized(this) {
8589            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8590                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8591                return;
8592            }
8593            final long origId = Binder.clearCallingIdentity();
8594            moveTaskBackwardsLocked(task);
8595            Binder.restoreCallingIdentity(origId);
8596        }
8597    }
8598
8599    private final void moveTaskBackwardsLocked(int task) {
8600        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8601    }
8602
8603    @Override
8604    public IBinder getHomeActivityToken() throws RemoteException {
8605        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8606                "getHomeActivityToken()");
8607        synchronized (this) {
8608            return mStackSupervisor.getHomeActivityToken();
8609        }
8610    }
8611
8612    @Override
8613    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8614            IActivityContainerCallback callback) throws RemoteException {
8615        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8616                "createActivityContainer()");
8617        synchronized (this) {
8618            if (parentActivityToken == null) {
8619                throw new IllegalArgumentException("parent token must not be null");
8620            }
8621            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8622            if (r == null) {
8623                return null;
8624            }
8625            if (callback == null) {
8626                throw new IllegalArgumentException("callback must not be null");
8627            }
8628            return mStackSupervisor.createActivityContainer(r, callback);
8629        }
8630    }
8631
8632    @Override
8633    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8634        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8635                "deleteActivityContainer()");
8636        synchronized (this) {
8637            mStackSupervisor.deleteActivityContainer(container);
8638        }
8639    }
8640
8641    @Override
8642    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8643            throws RemoteException {
8644        synchronized (this) {
8645            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8646            if (stack != null) {
8647                return stack.mActivityContainer;
8648            }
8649            return null;
8650        }
8651    }
8652
8653    @Override
8654    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8655        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8656                "moveTaskToStack()");
8657        if (stackId == HOME_STACK_ID) {
8658            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8659                    new RuntimeException("here").fillInStackTrace());
8660        }
8661        synchronized (this) {
8662            long ident = Binder.clearCallingIdentity();
8663            try {
8664                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8665                        + stackId + " toTop=" + toTop);
8666                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8667            } finally {
8668                Binder.restoreCallingIdentity(ident);
8669            }
8670        }
8671    }
8672
8673    @Override
8674    public void resizeStack(int stackBoxId, Rect bounds) {
8675        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8676                "resizeStackBox()");
8677        long ident = Binder.clearCallingIdentity();
8678        try {
8679            mWindowManager.resizeStack(stackBoxId, bounds);
8680        } finally {
8681            Binder.restoreCallingIdentity(ident);
8682        }
8683    }
8684
8685    @Override
8686    public List<StackInfo> getAllStackInfos() {
8687        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8688                "getAllStackInfos()");
8689        long ident = Binder.clearCallingIdentity();
8690        try {
8691            synchronized (this) {
8692                return mStackSupervisor.getAllStackInfosLocked();
8693            }
8694        } finally {
8695            Binder.restoreCallingIdentity(ident);
8696        }
8697    }
8698
8699    @Override
8700    public StackInfo getStackInfo(int stackId) {
8701        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8702                "getStackInfo()");
8703        long ident = Binder.clearCallingIdentity();
8704        try {
8705            synchronized (this) {
8706                return mStackSupervisor.getStackInfoLocked(stackId);
8707            }
8708        } finally {
8709            Binder.restoreCallingIdentity(ident);
8710        }
8711    }
8712
8713    @Override
8714    public boolean isInHomeStack(int taskId) {
8715        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8716                "getStackInfo()");
8717        long ident = Binder.clearCallingIdentity();
8718        try {
8719            synchronized (this) {
8720                TaskRecord tr = taskForIdLocked(taskId);
8721                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8722            }
8723        } finally {
8724            Binder.restoreCallingIdentity(ident);
8725        }
8726    }
8727
8728    @Override
8729    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8730        synchronized(this) {
8731            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8732        }
8733    }
8734
8735    private boolean isLockTaskAuthorized(String pkg) {
8736        final DevicePolicyManager dpm = (DevicePolicyManager)
8737                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8738        try {
8739            int uid = mContext.getPackageManager().getPackageUid(pkg,
8740                    Binder.getCallingUserHandle().getIdentifier());
8741            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8742        } catch (NameNotFoundException e) {
8743            return false;
8744        }
8745    }
8746
8747    void startLockTaskMode(TaskRecord task) {
8748        final String pkg;
8749        synchronized (this) {
8750            pkg = task.intent.getComponent().getPackageName();
8751        }
8752        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8753        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8754            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8755                    StatusBarManagerInternal.class);
8756            if (statusBarManager != null) {
8757                statusBarManager.showScreenPinningRequest();
8758            }
8759            return;
8760        }
8761        long ident = Binder.clearCallingIdentity();
8762        try {
8763            synchronized (this) {
8764                // Since we lost lock on task, make sure it is still there.
8765                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8766                if (task != null) {
8767                    if (!isSystemInitiated
8768                            && ((mStackSupervisor.getFocusedStack() == null)
8769                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8770                        throw new IllegalArgumentException("Invalid task, not in foreground");
8771                    }
8772                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8773                }
8774            }
8775        } finally {
8776            Binder.restoreCallingIdentity(ident);
8777        }
8778    }
8779
8780    @Override
8781    public void startLockTaskMode(int taskId) {
8782        final TaskRecord task;
8783        long ident = Binder.clearCallingIdentity();
8784        try {
8785            synchronized (this) {
8786                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8787            }
8788        } finally {
8789            Binder.restoreCallingIdentity(ident);
8790        }
8791        if (task != null) {
8792            startLockTaskMode(task);
8793        }
8794    }
8795
8796    @Override
8797    public void startLockTaskMode(IBinder token) {
8798        final TaskRecord task;
8799        long ident = Binder.clearCallingIdentity();
8800        try {
8801            synchronized (this) {
8802                final ActivityRecord r = ActivityRecord.forToken(token);
8803                if (r == null) {
8804                    return;
8805                }
8806                task = r.task;
8807            }
8808        } finally {
8809            Binder.restoreCallingIdentity(ident);
8810        }
8811        if (task != null) {
8812            startLockTaskMode(task);
8813        }
8814    }
8815
8816    @Override
8817    public void startLockTaskModeOnCurrent() throws RemoteException {
8818        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8819                "startLockTaskModeOnCurrent");
8820        long ident = Binder.clearCallingIdentity();
8821        try {
8822            ActivityRecord r = null;
8823            synchronized (this) {
8824                r = mStackSupervisor.topRunningActivityLocked();
8825            }
8826            startLockTaskMode(r.task);
8827        } finally {
8828            Binder.restoreCallingIdentity(ident);
8829        }
8830    }
8831
8832    @Override
8833    public void stopLockTaskMode() {
8834        // Verify that the user matches the package of the intent for the TaskRecord
8835        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8836        // and stopLockTaskMode.
8837        final int callingUid = Binder.getCallingUid();
8838        if (callingUid != Process.SYSTEM_UID) {
8839            try {
8840                String pkg =
8841                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8842                int uid = mContext.getPackageManager().getPackageUid(pkg,
8843                        Binder.getCallingUserHandle().getIdentifier());
8844                if (uid != callingUid) {
8845                    throw new SecurityException("Invalid uid, expected " + uid);
8846                }
8847            } catch (NameNotFoundException e) {
8848                Log.d(TAG, "stopLockTaskMode " + e);
8849                return;
8850            }
8851        }
8852        long ident = Binder.clearCallingIdentity();
8853        try {
8854            Log.d(TAG, "stopLockTaskMode");
8855            // Stop lock task
8856            synchronized (this) {
8857                mStackSupervisor.setLockTaskModeLocked(null, false);
8858            }
8859        } finally {
8860            Binder.restoreCallingIdentity(ident);
8861        }
8862    }
8863
8864    @Override
8865    public void stopLockTaskModeOnCurrent() throws RemoteException {
8866        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8867                "stopLockTaskModeOnCurrent");
8868        long ident = Binder.clearCallingIdentity();
8869        try {
8870            stopLockTaskMode();
8871        } finally {
8872            Binder.restoreCallingIdentity(ident);
8873        }
8874    }
8875
8876    @Override
8877    public boolean isInLockTaskMode() {
8878        synchronized (this) {
8879            return mStackSupervisor.isInLockTaskMode();
8880        }
8881    }
8882
8883    // =========================================================
8884    // CONTENT PROVIDERS
8885    // =========================================================
8886
8887    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8888        List<ProviderInfo> providers = null;
8889        try {
8890            providers = AppGlobals.getPackageManager().
8891                queryContentProviders(app.processName, app.uid,
8892                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8893        } catch (RemoteException ex) {
8894        }
8895        if (DEBUG_MU)
8896            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8897        int userId = app.userId;
8898        if (providers != null) {
8899            int N = providers.size();
8900            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8901            for (int i=0; i<N; i++) {
8902                ProviderInfo cpi =
8903                    (ProviderInfo)providers.get(i);
8904                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8905                        cpi.name, cpi.flags);
8906                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8907                    // This is a singleton provider, but a user besides the
8908                    // default user is asking to initialize a process it runs
8909                    // in...  well, no, it doesn't actually run in this process,
8910                    // it runs in the process of the default user.  Get rid of it.
8911                    providers.remove(i);
8912                    N--;
8913                    i--;
8914                    continue;
8915                }
8916
8917                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8918                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8919                if (cpr == null) {
8920                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8921                    mProviderMap.putProviderByClass(comp, cpr);
8922                }
8923                if (DEBUG_MU)
8924                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8925                app.pubProviders.put(cpi.name, cpr);
8926                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8927                    // Don't add this if it is a platform component that is marked
8928                    // to run in multiple processes, because this is actually
8929                    // part of the framework so doesn't make sense to track as a
8930                    // separate apk in the process.
8931                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8932                            mProcessStats);
8933                }
8934                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8935            }
8936        }
8937        return providers;
8938    }
8939
8940    /**
8941     * Check if {@link ProcessRecord} has a possible chance at accessing the
8942     * given {@link ProviderInfo}. Final permission checking is always done
8943     * in {@link ContentProvider}.
8944     */
8945    private final String checkContentProviderPermissionLocked(
8946            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8947        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8948        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8949        boolean checkedGrants = false;
8950        if (checkUser) {
8951            // Looking for cross-user grants before enforcing the typical cross-users permissions
8952            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8953            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8954                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8955                    return null;
8956                }
8957                checkedGrants = true;
8958            }
8959            userId = handleIncomingUser(callingPid, callingUid, userId,
8960                    false, ALLOW_NON_FULL,
8961                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8962            if (userId != tmpTargetUserId) {
8963                // When we actually went to determine the final targer user ID, this ended
8964                // up different than our initial check for the authority.  This is because
8965                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8966                // SELF.  So we need to re-check the grants again.
8967                checkedGrants = false;
8968            }
8969        }
8970        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8971                cpi.applicationInfo.uid, cpi.exported)
8972                == PackageManager.PERMISSION_GRANTED) {
8973            return null;
8974        }
8975        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8976                cpi.applicationInfo.uid, cpi.exported)
8977                == PackageManager.PERMISSION_GRANTED) {
8978            return null;
8979        }
8980
8981        PathPermission[] pps = cpi.pathPermissions;
8982        if (pps != null) {
8983            int i = pps.length;
8984            while (i > 0) {
8985                i--;
8986                PathPermission pp = pps[i];
8987                String pprperm = pp.getReadPermission();
8988                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8989                        cpi.applicationInfo.uid, cpi.exported)
8990                        == PackageManager.PERMISSION_GRANTED) {
8991                    return null;
8992                }
8993                String ppwperm = pp.getWritePermission();
8994                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8995                        cpi.applicationInfo.uid, cpi.exported)
8996                        == PackageManager.PERMISSION_GRANTED) {
8997                    return null;
8998                }
8999            }
9000        }
9001        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9002            return null;
9003        }
9004
9005        String msg;
9006        if (!cpi.exported) {
9007            msg = "Permission Denial: opening provider " + cpi.name
9008                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9009                    + ", uid=" + callingUid + ") that is not exported from uid "
9010                    + cpi.applicationInfo.uid;
9011        } else {
9012            msg = "Permission Denial: opening provider " + cpi.name
9013                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9014                    + ", uid=" + callingUid + ") requires "
9015                    + cpi.readPermission + " or " + cpi.writePermission;
9016        }
9017        Slog.w(TAG, msg);
9018        return msg;
9019    }
9020
9021    /**
9022     * Returns if the ContentProvider has granted a uri to callingUid
9023     */
9024    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9025        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9026        if (perms != null) {
9027            for (int i=perms.size()-1; i>=0; i--) {
9028                GrantUri grantUri = perms.keyAt(i);
9029                if (grantUri.sourceUserId == userId || !checkUser) {
9030                    if (matchesProvider(grantUri.uri, cpi)) {
9031                        return true;
9032                    }
9033                }
9034            }
9035        }
9036        return false;
9037    }
9038
9039    /**
9040     * Returns true if the uri authority is one of the authorities specified in the provider.
9041     */
9042    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9043        String uriAuth = uri.getAuthority();
9044        String cpiAuth = cpi.authority;
9045        if (cpiAuth.indexOf(';') == -1) {
9046            return cpiAuth.equals(uriAuth);
9047        }
9048        String[] cpiAuths = cpiAuth.split(";");
9049        int length = cpiAuths.length;
9050        for (int i = 0; i < length; i++) {
9051            if (cpiAuths[i].equals(uriAuth)) return true;
9052        }
9053        return false;
9054    }
9055
9056    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9057            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9058        if (r != null) {
9059            for (int i=0; i<r.conProviders.size(); i++) {
9060                ContentProviderConnection conn = r.conProviders.get(i);
9061                if (conn.provider == cpr) {
9062                    if (DEBUG_PROVIDER) Slog.v(TAG,
9063                            "Adding provider requested by "
9064                            + r.processName + " from process "
9065                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9066                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9067                    if (stable) {
9068                        conn.stableCount++;
9069                        conn.numStableIncs++;
9070                    } else {
9071                        conn.unstableCount++;
9072                        conn.numUnstableIncs++;
9073                    }
9074                    return conn;
9075                }
9076            }
9077            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9078            if (stable) {
9079                conn.stableCount = 1;
9080                conn.numStableIncs = 1;
9081            } else {
9082                conn.unstableCount = 1;
9083                conn.numUnstableIncs = 1;
9084            }
9085            cpr.connections.add(conn);
9086            r.conProviders.add(conn);
9087            return conn;
9088        }
9089        cpr.addExternalProcessHandleLocked(externalProcessToken);
9090        return null;
9091    }
9092
9093    boolean decProviderCountLocked(ContentProviderConnection conn,
9094            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9095        if (conn != null) {
9096            cpr = conn.provider;
9097            if (DEBUG_PROVIDER) Slog.v(TAG,
9098                    "Removing provider requested by "
9099                    + conn.client.processName + " from process "
9100                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9101                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9102            if (stable) {
9103                conn.stableCount--;
9104            } else {
9105                conn.unstableCount--;
9106            }
9107            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9108                cpr.connections.remove(conn);
9109                conn.client.conProviders.remove(conn);
9110                return true;
9111            }
9112            return false;
9113        }
9114        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9115        return false;
9116    }
9117
9118    private void checkTime(long startTime, String where) {
9119        long now = SystemClock.elapsedRealtime();
9120        if ((now-startTime) > 1000) {
9121            // If we are taking more than a second, log about it.
9122            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9123        }
9124    }
9125
9126    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9127            String name, IBinder token, boolean stable, int userId) {
9128        ContentProviderRecord cpr;
9129        ContentProviderConnection conn = null;
9130        ProviderInfo cpi = null;
9131
9132        synchronized(this) {
9133            long startTime = SystemClock.elapsedRealtime();
9134
9135            ProcessRecord r = null;
9136            if (caller != null) {
9137                r = getRecordForAppLocked(caller);
9138                if (r == null) {
9139                    throw new SecurityException(
9140                            "Unable to find app for caller " + caller
9141                          + " (pid=" + Binder.getCallingPid()
9142                          + ") when getting content provider " + name);
9143                }
9144            }
9145
9146            boolean checkCrossUser = true;
9147
9148            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9149
9150            // First check if this content provider has been published...
9151            cpr = mProviderMap.getProviderByName(name, userId);
9152            // If that didn't work, check if it exists for user 0 and then
9153            // verify that it's a singleton provider before using it.
9154            if (cpr == null && userId != UserHandle.USER_OWNER) {
9155                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9156                if (cpr != null) {
9157                    cpi = cpr.info;
9158                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9159                            cpi.name, cpi.flags)
9160                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9161                        userId = UserHandle.USER_OWNER;
9162                        checkCrossUser = false;
9163                    } else {
9164                        cpr = null;
9165                        cpi = null;
9166                    }
9167                }
9168            }
9169
9170            boolean providerRunning = cpr != null;
9171            if (providerRunning) {
9172                cpi = cpr.info;
9173                String msg;
9174                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9175                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9176                        != null) {
9177                    throw new SecurityException(msg);
9178                }
9179                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9180
9181                if (r != null && cpr.canRunHere(r)) {
9182                    // This provider has been published or is in the process
9183                    // of being published...  but it is also allowed to run
9184                    // in the caller's process, so don't make a connection
9185                    // and just let the caller instantiate its own instance.
9186                    ContentProviderHolder holder = cpr.newHolder(null);
9187                    // don't give caller the provider object, it needs
9188                    // to make its own.
9189                    holder.provider = null;
9190                    return holder;
9191                }
9192
9193                final long origId = Binder.clearCallingIdentity();
9194
9195                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9196
9197                // In this case the provider instance already exists, so we can
9198                // return it right away.
9199                conn = incProviderCountLocked(r, cpr, token, stable);
9200                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9201                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9202                        // If this is a perceptible app accessing the provider,
9203                        // make sure to count it as being accessed and thus
9204                        // back up on the LRU list.  This is good because
9205                        // content providers are often expensive to start.
9206                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9207                        updateLruProcessLocked(cpr.proc, false, null);
9208                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9209                    }
9210                }
9211
9212                if (cpr.proc != null) {
9213                    if (false) {
9214                        if (cpr.name.flattenToShortString().equals(
9215                                "com.android.providers.calendar/.CalendarProvider2")) {
9216                            Slog.v(TAG, "****************** KILLING "
9217                                + cpr.name.flattenToShortString());
9218                            Process.killProcess(cpr.proc.pid);
9219                        }
9220                    }
9221                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9222                    boolean success = updateOomAdjLocked(cpr.proc);
9223                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9224                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9225                    // NOTE: there is still a race here where a signal could be
9226                    // pending on the process even though we managed to update its
9227                    // adj level.  Not sure what to do about this, but at least
9228                    // the race is now smaller.
9229                    if (!success) {
9230                        // Uh oh...  it looks like the provider's process
9231                        // has been killed on us.  We need to wait for a new
9232                        // process to be started, and make sure its death
9233                        // doesn't kill our process.
9234                        Slog.i(TAG,
9235                                "Existing provider " + cpr.name.flattenToShortString()
9236                                + " is crashing; detaching " + r);
9237                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9238                        checkTime(startTime, "getContentProviderImpl: before appDied");
9239                        appDiedLocked(cpr.proc);
9240                        checkTime(startTime, "getContentProviderImpl: after appDied");
9241                        if (!lastRef) {
9242                            // This wasn't the last ref our process had on
9243                            // the provider...  we have now been killed, bail.
9244                            return null;
9245                        }
9246                        providerRunning = false;
9247                        conn = null;
9248                    }
9249                }
9250
9251                Binder.restoreCallingIdentity(origId);
9252            }
9253
9254            boolean singleton;
9255            if (!providerRunning) {
9256                try {
9257                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9258                    cpi = AppGlobals.getPackageManager().
9259                        resolveContentProvider(name,
9260                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9261                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9262                } catch (RemoteException ex) {
9263                }
9264                if (cpi == null) {
9265                    return null;
9266                }
9267                // If the provider is a singleton AND
9268                // (it's a call within the same user || the provider is a
9269                // privileged app)
9270                // Then allow connecting to the singleton provider
9271                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9272                        cpi.name, cpi.flags)
9273                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9274                if (singleton) {
9275                    userId = UserHandle.USER_OWNER;
9276                }
9277                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9278                checkTime(startTime, "getContentProviderImpl: got app info for user");
9279
9280                String msg;
9281                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9282                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9283                        != null) {
9284                    throw new SecurityException(msg);
9285                }
9286                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9287
9288                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9289                        && !cpi.processName.equals("system")) {
9290                    // If this content provider does not run in the system
9291                    // process, and the system is not yet ready to run other
9292                    // processes, then fail fast instead of hanging.
9293                    throw new IllegalArgumentException(
9294                            "Attempt to launch content provider before system ready");
9295                }
9296
9297                // Make sure that the user who owns this provider is running.  If not,
9298                // we don't want to allow it to run.
9299                if (!isUserRunningLocked(userId, false)) {
9300                    Slog.w(TAG, "Unable to launch app "
9301                            + cpi.applicationInfo.packageName + "/"
9302                            + cpi.applicationInfo.uid + " for provider "
9303                            + name + ": user " + userId + " is stopped");
9304                    return null;
9305                }
9306
9307                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9308                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9309                cpr = mProviderMap.getProviderByClass(comp, userId);
9310                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9311                final boolean firstClass = cpr == null;
9312                if (firstClass) {
9313                    final long ident = Binder.clearCallingIdentity();
9314                    try {
9315                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9316                        ApplicationInfo ai =
9317                            AppGlobals.getPackageManager().
9318                                getApplicationInfo(
9319                                        cpi.applicationInfo.packageName,
9320                                        STOCK_PM_FLAGS, userId);
9321                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9322                        if (ai == null) {
9323                            Slog.w(TAG, "No package info for content provider "
9324                                    + cpi.name);
9325                            return null;
9326                        }
9327                        ai = getAppInfoForUser(ai, userId);
9328                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9329                    } catch (RemoteException ex) {
9330                        // pm is in same process, this will never happen.
9331                    } finally {
9332                        Binder.restoreCallingIdentity(ident);
9333                    }
9334                }
9335
9336                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9337
9338                if (r != null && cpr.canRunHere(r)) {
9339                    // If this is a multiprocess provider, then just return its
9340                    // info and allow the caller to instantiate it.  Only do
9341                    // this if the provider is the same user as the caller's
9342                    // process, or can run as root (so can be in any process).
9343                    return cpr.newHolder(null);
9344                }
9345
9346                if (DEBUG_PROVIDER) {
9347                    RuntimeException e = new RuntimeException("here");
9348                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9349                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9350                }
9351
9352                // This is single process, and our app is now connecting to it.
9353                // See if we are already in the process of launching this
9354                // provider.
9355                final int N = mLaunchingProviders.size();
9356                int i;
9357                for (i=0; i<N; i++) {
9358                    if (mLaunchingProviders.get(i) == cpr) {
9359                        break;
9360                    }
9361                }
9362
9363                // If the provider is not already being launched, then get it
9364                // started.
9365                if (i >= N) {
9366                    final long origId = Binder.clearCallingIdentity();
9367
9368                    try {
9369                        // Content provider is now in use, its package can't be stopped.
9370                        try {
9371                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9372                            AppGlobals.getPackageManager().setPackageStoppedState(
9373                                    cpr.appInfo.packageName, false, userId);
9374                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9375                        } catch (RemoteException e) {
9376                        } catch (IllegalArgumentException e) {
9377                            Slog.w(TAG, "Failed trying to unstop package "
9378                                    + cpr.appInfo.packageName + ": " + e);
9379                        }
9380
9381                        // Use existing process if already started
9382                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9383                        ProcessRecord proc = getProcessRecordLocked(
9384                                cpi.processName, cpr.appInfo.uid, false);
9385                        if (proc != null && proc.thread != null) {
9386                            if (DEBUG_PROVIDER) {
9387                                Slog.d(TAG, "Installing in existing process " + proc);
9388                            }
9389                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9390                            proc.pubProviders.put(cpi.name, cpr);
9391                            try {
9392                                proc.thread.scheduleInstallProvider(cpi);
9393                            } catch (RemoteException e) {
9394                            }
9395                        } else {
9396                            checkTime(startTime, "getContentProviderImpl: before start process");
9397                            proc = startProcessLocked(cpi.processName,
9398                                    cpr.appInfo, false, 0, "content provider",
9399                                    new ComponentName(cpi.applicationInfo.packageName,
9400                                            cpi.name), false, false, false);
9401                            checkTime(startTime, "getContentProviderImpl: after start process");
9402                            if (proc == null) {
9403                                Slog.w(TAG, "Unable to launch app "
9404                                        + cpi.applicationInfo.packageName + "/"
9405                                        + cpi.applicationInfo.uid + " for provider "
9406                                        + name + ": process is bad");
9407                                return null;
9408                            }
9409                        }
9410                        cpr.launchingApp = proc;
9411                        mLaunchingProviders.add(cpr);
9412                    } finally {
9413                        Binder.restoreCallingIdentity(origId);
9414                    }
9415                }
9416
9417                checkTime(startTime, "getContentProviderImpl: updating data structures");
9418
9419                // Make sure the provider is published (the same provider class
9420                // may be published under multiple names).
9421                if (firstClass) {
9422                    mProviderMap.putProviderByClass(comp, cpr);
9423                }
9424
9425                mProviderMap.putProviderByName(name, cpr);
9426                conn = incProviderCountLocked(r, cpr, token, stable);
9427                if (conn != null) {
9428                    conn.waiting = true;
9429                }
9430            }
9431            checkTime(startTime, "getContentProviderImpl: done!");
9432        }
9433
9434        // Wait for the provider to be published...
9435        synchronized (cpr) {
9436            while (cpr.provider == null) {
9437                if (cpr.launchingApp == null) {
9438                    Slog.w(TAG, "Unable to launch app "
9439                            + cpi.applicationInfo.packageName + "/"
9440                            + cpi.applicationInfo.uid + " for provider "
9441                            + name + ": launching app became null");
9442                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9443                            UserHandle.getUserId(cpi.applicationInfo.uid),
9444                            cpi.applicationInfo.packageName,
9445                            cpi.applicationInfo.uid, name);
9446                    return null;
9447                }
9448                try {
9449                    if (DEBUG_MU) {
9450                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9451                                + cpr.launchingApp);
9452                    }
9453                    if (conn != null) {
9454                        conn.waiting = true;
9455                    }
9456                    cpr.wait();
9457                } catch (InterruptedException ex) {
9458                } finally {
9459                    if (conn != null) {
9460                        conn.waiting = false;
9461                    }
9462                }
9463            }
9464        }
9465        return cpr != null ? cpr.newHolder(conn) : null;
9466    }
9467
9468    @Override
9469    public final ContentProviderHolder getContentProvider(
9470            IApplicationThread caller, String name, int userId, boolean stable) {
9471        enforceNotIsolatedCaller("getContentProvider");
9472        if (caller == null) {
9473            String msg = "null IApplicationThread when getting content provider "
9474                    + name;
9475            Slog.w(TAG, msg);
9476            throw new SecurityException(msg);
9477        }
9478        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9479        // with cross-user grant.
9480        return getContentProviderImpl(caller, name, null, stable, userId);
9481    }
9482
9483    public ContentProviderHolder getContentProviderExternal(
9484            String name, int userId, IBinder token) {
9485        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9486            "Do not have permission in call getContentProviderExternal()");
9487        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9488                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9489        return getContentProviderExternalUnchecked(name, token, userId);
9490    }
9491
9492    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9493            IBinder token, int userId) {
9494        return getContentProviderImpl(null, name, token, true, userId);
9495    }
9496
9497    /**
9498     * Drop a content provider from a ProcessRecord's bookkeeping
9499     */
9500    public void removeContentProvider(IBinder connection, boolean stable) {
9501        enforceNotIsolatedCaller("removeContentProvider");
9502        long ident = Binder.clearCallingIdentity();
9503        try {
9504            synchronized (this) {
9505                ContentProviderConnection conn;
9506                try {
9507                    conn = (ContentProviderConnection)connection;
9508                } catch (ClassCastException e) {
9509                    String msg ="removeContentProvider: " + connection
9510                            + " not a ContentProviderConnection";
9511                    Slog.w(TAG, msg);
9512                    throw new IllegalArgumentException(msg);
9513                }
9514                if (conn == null) {
9515                    throw new NullPointerException("connection is null");
9516                }
9517                if (decProviderCountLocked(conn, null, null, stable)) {
9518                    updateOomAdjLocked();
9519                }
9520            }
9521        } finally {
9522            Binder.restoreCallingIdentity(ident);
9523        }
9524    }
9525
9526    public void removeContentProviderExternal(String name, IBinder token) {
9527        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9528            "Do not have permission in call removeContentProviderExternal()");
9529        int userId = UserHandle.getCallingUserId();
9530        long ident = Binder.clearCallingIdentity();
9531        try {
9532            removeContentProviderExternalUnchecked(name, token, userId);
9533        } finally {
9534            Binder.restoreCallingIdentity(ident);
9535        }
9536    }
9537
9538    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9539        synchronized (this) {
9540            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9541            if(cpr == null) {
9542                //remove from mProvidersByClass
9543                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9544                return;
9545            }
9546
9547            //update content provider record entry info
9548            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9549            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9550            if (localCpr.hasExternalProcessHandles()) {
9551                if (localCpr.removeExternalProcessHandleLocked(token)) {
9552                    updateOomAdjLocked();
9553                } else {
9554                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9555                            + " with no external reference for token: "
9556                            + token + ".");
9557                }
9558            } else {
9559                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9560                        + " with no external references.");
9561            }
9562        }
9563    }
9564
9565    public final void publishContentProviders(IApplicationThread caller,
9566            List<ContentProviderHolder> providers) {
9567        if (providers == null) {
9568            return;
9569        }
9570
9571        enforceNotIsolatedCaller("publishContentProviders");
9572        synchronized (this) {
9573            final ProcessRecord r = getRecordForAppLocked(caller);
9574            if (DEBUG_MU)
9575                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9576            if (r == null) {
9577                throw new SecurityException(
9578                        "Unable to find app for caller " + caller
9579                      + " (pid=" + Binder.getCallingPid()
9580                      + ") when publishing content providers");
9581            }
9582
9583            final long origId = Binder.clearCallingIdentity();
9584
9585            final int N = providers.size();
9586            for (int i=0; i<N; i++) {
9587                ContentProviderHolder src = providers.get(i);
9588                if (src == null || src.info == null || src.provider == null) {
9589                    continue;
9590                }
9591                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9592                if (DEBUG_MU)
9593                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9594                if (dst != null) {
9595                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9596                    mProviderMap.putProviderByClass(comp, dst);
9597                    String names[] = dst.info.authority.split(";");
9598                    for (int j = 0; j < names.length; j++) {
9599                        mProviderMap.putProviderByName(names[j], dst);
9600                    }
9601
9602                    int NL = mLaunchingProviders.size();
9603                    int j;
9604                    for (j=0; j<NL; j++) {
9605                        if (mLaunchingProviders.get(j) == dst) {
9606                            mLaunchingProviders.remove(j);
9607                            j--;
9608                            NL--;
9609                        }
9610                    }
9611                    synchronized (dst) {
9612                        dst.provider = src.provider;
9613                        dst.proc = r;
9614                        dst.notifyAll();
9615                    }
9616                    updateOomAdjLocked(r);
9617                }
9618            }
9619
9620            Binder.restoreCallingIdentity(origId);
9621        }
9622    }
9623
9624    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9625        ContentProviderConnection conn;
9626        try {
9627            conn = (ContentProviderConnection)connection;
9628        } catch (ClassCastException e) {
9629            String msg ="refContentProvider: " + connection
9630                    + " not a ContentProviderConnection";
9631            Slog.w(TAG, msg);
9632            throw new IllegalArgumentException(msg);
9633        }
9634        if (conn == null) {
9635            throw new NullPointerException("connection is null");
9636        }
9637
9638        synchronized (this) {
9639            if (stable > 0) {
9640                conn.numStableIncs += stable;
9641            }
9642            stable = conn.stableCount + stable;
9643            if (stable < 0) {
9644                throw new IllegalStateException("stableCount < 0: " + stable);
9645            }
9646
9647            if (unstable > 0) {
9648                conn.numUnstableIncs += unstable;
9649            }
9650            unstable = conn.unstableCount + unstable;
9651            if (unstable < 0) {
9652                throw new IllegalStateException("unstableCount < 0: " + unstable);
9653            }
9654
9655            if ((stable+unstable) <= 0) {
9656                throw new IllegalStateException("ref counts can't go to zero here: stable="
9657                        + stable + " unstable=" + unstable);
9658            }
9659            conn.stableCount = stable;
9660            conn.unstableCount = unstable;
9661            return !conn.dead;
9662        }
9663    }
9664
9665    public void unstableProviderDied(IBinder connection) {
9666        ContentProviderConnection conn;
9667        try {
9668            conn = (ContentProviderConnection)connection;
9669        } catch (ClassCastException e) {
9670            String msg ="refContentProvider: " + connection
9671                    + " not a ContentProviderConnection";
9672            Slog.w(TAG, msg);
9673            throw new IllegalArgumentException(msg);
9674        }
9675        if (conn == null) {
9676            throw new NullPointerException("connection is null");
9677        }
9678
9679        // Safely retrieve the content provider associated with the connection.
9680        IContentProvider provider;
9681        synchronized (this) {
9682            provider = conn.provider.provider;
9683        }
9684
9685        if (provider == null) {
9686            // Um, yeah, we're way ahead of you.
9687            return;
9688        }
9689
9690        // Make sure the caller is being honest with us.
9691        if (provider.asBinder().pingBinder()) {
9692            // Er, no, still looks good to us.
9693            synchronized (this) {
9694                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9695                        + " says " + conn + " died, but we don't agree");
9696                return;
9697            }
9698        }
9699
9700        // Well look at that!  It's dead!
9701        synchronized (this) {
9702            if (conn.provider.provider != provider) {
9703                // But something changed...  good enough.
9704                return;
9705            }
9706
9707            ProcessRecord proc = conn.provider.proc;
9708            if (proc == null || proc.thread == null) {
9709                // Seems like the process is already cleaned up.
9710                return;
9711            }
9712
9713            // As far as we're concerned, this is just like receiving a
9714            // death notification...  just a bit prematurely.
9715            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9716                    + ") early provider death");
9717            final long ident = Binder.clearCallingIdentity();
9718            try {
9719                appDiedLocked(proc);
9720            } finally {
9721                Binder.restoreCallingIdentity(ident);
9722            }
9723        }
9724    }
9725
9726    @Override
9727    public void appNotRespondingViaProvider(IBinder connection) {
9728        enforceCallingPermission(
9729                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9730
9731        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9732        if (conn == null) {
9733            Slog.w(TAG, "ContentProviderConnection is null");
9734            return;
9735        }
9736
9737        final ProcessRecord host = conn.provider.proc;
9738        if (host == null) {
9739            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9740            return;
9741        }
9742
9743        final long token = Binder.clearCallingIdentity();
9744        try {
9745            appNotResponding(host, null, null, false, "ContentProvider not responding");
9746        } finally {
9747            Binder.restoreCallingIdentity(token);
9748        }
9749    }
9750
9751    public final void installSystemProviders() {
9752        List<ProviderInfo> providers;
9753        synchronized (this) {
9754            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9755            providers = generateApplicationProvidersLocked(app);
9756            if (providers != null) {
9757                for (int i=providers.size()-1; i>=0; i--) {
9758                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9759                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9760                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9761                                + ": not system .apk");
9762                        providers.remove(i);
9763                    }
9764                }
9765            }
9766        }
9767        if (providers != null) {
9768            mSystemThread.installSystemProviders(providers);
9769        }
9770
9771        mCoreSettingsObserver = new CoreSettingsObserver(this);
9772
9773        //mUsageStatsService.monitorPackages();
9774    }
9775
9776    /**
9777     * Allows apps to retrieve the MIME type of a URI.
9778     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9779     * users, then it does not need permission to access the ContentProvider.
9780     * Either, it needs cross-user uri grants.
9781     *
9782     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9783     *
9784     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9785     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9786     */
9787    public String getProviderMimeType(Uri uri, int userId) {
9788        enforceNotIsolatedCaller("getProviderMimeType");
9789        final String name = uri.getAuthority();
9790        int callingUid = Binder.getCallingUid();
9791        int callingPid = Binder.getCallingPid();
9792        long ident = 0;
9793        boolean clearedIdentity = false;
9794        userId = unsafeConvertIncomingUser(userId);
9795        if (canClearIdentity(callingPid, callingUid, userId)) {
9796            clearedIdentity = true;
9797            ident = Binder.clearCallingIdentity();
9798        }
9799        ContentProviderHolder holder = null;
9800        try {
9801            holder = getContentProviderExternalUnchecked(name, null, userId);
9802            if (holder != null) {
9803                return holder.provider.getType(uri);
9804            }
9805        } catch (RemoteException e) {
9806            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9807            return null;
9808        } finally {
9809            // We need to clear the identity to call removeContentProviderExternalUnchecked
9810            if (!clearedIdentity) {
9811                ident = Binder.clearCallingIdentity();
9812            }
9813            try {
9814                if (holder != null) {
9815                    removeContentProviderExternalUnchecked(name, null, userId);
9816                }
9817            } finally {
9818                Binder.restoreCallingIdentity(ident);
9819            }
9820        }
9821
9822        return null;
9823    }
9824
9825    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9826        if (UserHandle.getUserId(callingUid) == userId) {
9827            return true;
9828        }
9829        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9830                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9831                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9832                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9833                return true;
9834        }
9835        return false;
9836    }
9837
9838    // =========================================================
9839    // GLOBAL MANAGEMENT
9840    // =========================================================
9841
9842    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9843            boolean isolated, int isolatedUid) {
9844        String proc = customProcess != null ? customProcess : info.processName;
9845        BatteryStatsImpl.Uid.Proc ps = null;
9846        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9847        int uid = info.uid;
9848        if (isolated) {
9849            if (isolatedUid == 0) {
9850                int userId = UserHandle.getUserId(uid);
9851                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9852                while (true) {
9853                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9854                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9855                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9856                    }
9857                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9858                    mNextIsolatedProcessUid++;
9859                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9860                        // No process for this uid, use it.
9861                        break;
9862                    }
9863                    stepsLeft--;
9864                    if (stepsLeft <= 0) {
9865                        return null;
9866                    }
9867                }
9868            } else {
9869                // Special case for startIsolatedProcess (internal only), where
9870                // the uid of the isolated process is specified by the caller.
9871                uid = isolatedUid;
9872            }
9873        }
9874        return new ProcessRecord(stats, info, proc, uid);
9875    }
9876
9877    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9878            String abiOverride) {
9879        ProcessRecord app;
9880        if (!isolated) {
9881            app = getProcessRecordLocked(info.processName, info.uid, true);
9882        } else {
9883            app = null;
9884        }
9885
9886        if (app == null) {
9887            app = newProcessRecordLocked(info, null, isolated, 0);
9888            mProcessNames.put(info.processName, app.uid, app);
9889            if (isolated) {
9890                mIsolatedProcesses.put(app.uid, app);
9891            }
9892            updateLruProcessLocked(app, false, null);
9893            updateOomAdjLocked();
9894        }
9895
9896        // This package really, really can not be stopped.
9897        try {
9898            AppGlobals.getPackageManager().setPackageStoppedState(
9899                    info.packageName, false, UserHandle.getUserId(app.uid));
9900        } catch (RemoteException e) {
9901        } catch (IllegalArgumentException e) {
9902            Slog.w(TAG, "Failed trying to unstop package "
9903                    + info.packageName + ": " + e);
9904        }
9905
9906        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9907                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9908            app.persistent = true;
9909            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9910        }
9911        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9912            mPersistentStartingProcesses.add(app);
9913            startProcessLocked(app, "added application", app.processName, abiOverride,
9914                    null /* entryPoint */, null /* entryPointArgs */);
9915        }
9916
9917        return app;
9918    }
9919
9920    public void unhandledBack() {
9921        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9922                "unhandledBack()");
9923
9924        synchronized(this) {
9925            final long origId = Binder.clearCallingIdentity();
9926            try {
9927                getFocusedStack().unhandledBackLocked();
9928            } finally {
9929                Binder.restoreCallingIdentity(origId);
9930            }
9931        }
9932    }
9933
9934    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9935        enforceNotIsolatedCaller("openContentUri");
9936        final int userId = UserHandle.getCallingUserId();
9937        String name = uri.getAuthority();
9938        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9939        ParcelFileDescriptor pfd = null;
9940        if (cph != null) {
9941            // We record the binder invoker's uid in thread-local storage before
9942            // going to the content provider to open the file.  Later, in the code
9943            // that handles all permissions checks, we look for this uid and use
9944            // that rather than the Activity Manager's own uid.  The effect is that
9945            // we do the check against the caller's permissions even though it looks
9946            // to the content provider like the Activity Manager itself is making
9947            // the request.
9948            Binder token = new Binder();
9949            sCallerIdentity.set(new Identity(
9950                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9951            try {
9952                pfd = cph.provider.openFile(null, uri, "r", null, token);
9953            } catch (FileNotFoundException e) {
9954                // do nothing; pfd will be returned null
9955            } finally {
9956                // Ensure that whatever happens, we clean up the identity state
9957                sCallerIdentity.remove();
9958            }
9959
9960            // We've got the fd now, so we're done with the provider.
9961            removeContentProviderExternalUnchecked(name, null, userId);
9962        } else {
9963            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9964        }
9965        return pfd;
9966    }
9967
9968    // Actually is sleeping or shutting down or whatever else in the future
9969    // is an inactive state.
9970    public boolean isSleepingOrShuttingDown() {
9971        return isSleeping() || mShuttingDown;
9972    }
9973
9974    public boolean isSleeping() {
9975        return mSleeping;
9976    }
9977
9978    void onWakefulnessChanged(int wakefulness) {
9979        synchronized(this) {
9980            mWakefulness = wakefulness;
9981            updateSleepIfNeededLocked();
9982        }
9983    }
9984
9985    void finishRunningVoiceLocked() {
9986        if (mRunningVoice) {
9987            mRunningVoice = false;
9988            updateSleepIfNeededLocked();
9989        }
9990    }
9991
9992    void updateSleepIfNeededLocked() {
9993        if (mSleeping && !shouldSleepLocked()) {
9994            mSleeping = false;
9995            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9996        } else if (!mSleeping && shouldSleepLocked()) {
9997            mSleeping = true;
9998            mStackSupervisor.goingToSleepLocked();
9999
10000            // Initialize the wake times of all processes.
10001            checkExcessivePowerUsageLocked(false);
10002            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10003            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10004            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10005        }
10006    }
10007
10008    private boolean shouldSleepLocked() {
10009        // Resume applications while running a voice interactor.
10010        if (mRunningVoice) {
10011            return false;
10012        }
10013
10014        switch (mWakefulness) {
10015            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10016            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10017                // If we're interactive but applications are already paused then defer
10018                // resuming them until the lock screen is hidden.
10019                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10020            case PowerManagerInternal.WAKEFULNESS_DOZING:
10021                // If we're dozing then pause applications whenever the lock screen is shown.
10022                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10023            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10024            default:
10025                // If we're asleep then pause applications unconditionally.
10026                return true;
10027        }
10028    }
10029
10030    /** Pokes the task persister. */
10031    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10032        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10033            // Never persist the home stack.
10034            return;
10035        }
10036        mTaskPersister.wakeup(task, flush);
10037    }
10038
10039    /** Notifies all listeners when the task stack has changed. */
10040    void notifyTaskStackChangedLocked() {
10041        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10042        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10043        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10044    }
10045
10046    @Override
10047    public boolean shutdown(int timeout) {
10048        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10049                != PackageManager.PERMISSION_GRANTED) {
10050            throw new SecurityException("Requires permission "
10051                    + android.Manifest.permission.SHUTDOWN);
10052        }
10053
10054        boolean timedout = false;
10055
10056        synchronized(this) {
10057            mShuttingDown = true;
10058            updateEventDispatchingLocked();
10059            timedout = mStackSupervisor.shutdownLocked(timeout);
10060        }
10061
10062        mAppOpsService.shutdown();
10063        if (mUsageStatsService != null) {
10064            mUsageStatsService.prepareShutdown();
10065        }
10066        mBatteryStatsService.shutdown();
10067        synchronized (this) {
10068            mProcessStats.shutdownLocked();
10069            notifyTaskPersisterLocked(null, true);
10070        }
10071
10072        return timedout;
10073    }
10074
10075    public final void activitySlept(IBinder token) {
10076        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10077
10078        final long origId = Binder.clearCallingIdentity();
10079
10080        synchronized (this) {
10081            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10082            if (r != null) {
10083                mStackSupervisor.activitySleptLocked(r);
10084            }
10085        }
10086
10087        Binder.restoreCallingIdentity(origId);
10088    }
10089
10090    private String lockScreenShownToString() {
10091        switch (mLockScreenShown) {
10092            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10093            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10094            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10095            default: return "Unknown=" + mLockScreenShown;
10096        }
10097    }
10098
10099    void logLockScreen(String msg) {
10100        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10101                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10102                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10103                + " mSleeping=" + mSleeping);
10104    }
10105
10106    void startRunningVoiceLocked() {
10107        if (!mRunningVoice) {
10108            mRunningVoice = true;
10109            updateSleepIfNeededLocked();
10110        }
10111    }
10112
10113    private void updateEventDispatchingLocked() {
10114        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10115    }
10116
10117    public void setLockScreenShown(boolean shown) {
10118        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10119                != PackageManager.PERMISSION_GRANTED) {
10120            throw new SecurityException("Requires permission "
10121                    + android.Manifest.permission.DEVICE_POWER);
10122        }
10123
10124        synchronized(this) {
10125            long ident = Binder.clearCallingIdentity();
10126            try {
10127                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10128                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10129                updateSleepIfNeededLocked();
10130            } finally {
10131                Binder.restoreCallingIdentity(ident);
10132            }
10133        }
10134    }
10135
10136    @Override
10137    public void stopAppSwitches() {
10138        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10139                != PackageManager.PERMISSION_GRANTED) {
10140            throw new SecurityException("Requires permission "
10141                    + android.Manifest.permission.STOP_APP_SWITCHES);
10142        }
10143
10144        synchronized(this) {
10145            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10146                    + APP_SWITCH_DELAY_TIME;
10147            mDidAppSwitch = false;
10148            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10149            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10150            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10151        }
10152    }
10153
10154    public void resumeAppSwitches() {
10155        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10156                != PackageManager.PERMISSION_GRANTED) {
10157            throw new SecurityException("Requires permission "
10158                    + android.Manifest.permission.STOP_APP_SWITCHES);
10159        }
10160
10161        synchronized(this) {
10162            // Note that we don't execute any pending app switches... we will
10163            // let those wait until either the timeout, or the next start
10164            // activity request.
10165            mAppSwitchesAllowedTime = 0;
10166        }
10167    }
10168
10169    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10170            int callingPid, int callingUid, String name) {
10171        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10172            return true;
10173        }
10174
10175        int perm = checkComponentPermission(
10176                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10177                sourceUid, -1, true);
10178        if (perm == PackageManager.PERMISSION_GRANTED) {
10179            return true;
10180        }
10181
10182        // If the actual IPC caller is different from the logical source, then
10183        // also see if they are allowed to control app switches.
10184        if (callingUid != -1 && callingUid != sourceUid) {
10185            perm = checkComponentPermission(
10186                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10187                    callingUid, -1, true);
10188            if (perm == PackageManager.PERMISSION_GRANTED) {
10189                return true;
10190            }
10191        }
10192
10193        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10194        return false;
10195    }
10196
10197    public void setDebugApp(String packageName, boolean waitForDebugger,
10198            boolean persistent) {
10199        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10200                "setDebugApp()");
10201
10202        long ident = Binder.clearCallingIdentity();
10203        try {
10204            // Note that this is not really thread safe if there are multiple
10205            // callers into it at the same time, but that's not a situation we
10206            // care about.
10207            if (persistent) {
10208                final ContentResolver resolver = mContext.getContentResolver();
10209                Settings.Global.putString(
10210                    resolver, Settings.Global.DEBUG_APP,
10211                    packageName);
10212                Settings.Global.putInt(
10213                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10214                    waitForDebugger ? 1 : 0);
10215            }
10216
10217            synchronized (this) {
10218                if (!persistent) {
10219                    mOrigDebugApp = mDebugApp;
10220                    mOrigWaitForDebugger = mWaitForDebugger;
10221                }
10222                mDebugApp = packageName;
10223                mWaitForDebugger = waitForDebugger;
10224                mDebugTransient = !persistent;
10225                if (packageName != null) {
10226                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10227                            false, UserHandle.USER_ALL, "set debug app");
10228                }
10229            }
10230        } finally {
10231            Binder.restoreCallingIdentity(ident);
10232        }
10233    }
10234
10235    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10236        synchronized (this) {
10237            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10238            if (!isDebuggable) {
10239                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10240                    throw new SecurityException("Process not debuggable: " + app.packageName);
10241                }
10242            }
10243
10244            mOpenGlTraceApp = processName;
10245        }
10246    }
10247
10248    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10249        synchronized (this) {
10250            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10251            if (!isDebuggable) {
10252                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10253                    throw new SecurityException("Process not debuggable: " + app.packageName);
10254                }
10255            }
10256            mProfileApp = processName;
10257            mProfileFile = profilerInfo.profileFile;
10258            if (mProfileFd != null) {
10259                try {
10260                    mProfileFd.close();
10261                } catch (IOException e) {
10262                }
10263                mProfileFd = null;
10264            }
10265            mProfileFd = profilerInfo.profileFd;
10266            mSamplingInterval = profilerInfo.samplingInterval;
10267            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10268            mProfileType = 0;
10269        }
10270    }
10271
10272    @Override
10273    public void setAlwaysFinish(boolean enabled) {
10274        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10275                "setAlwaysFinish()");
10276
10277        Settings.Global.putInt(
10278                mContext.getContentResolver(),
10279                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10280
10281        synchronized (this) {
10282            mAlwaysFinishActivities = enabled;
10283        }
10284    }
10285
10286    @Override
10287    public void setActivityController(IActivityController controller) {
10288        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10289                "setActivityController()");
10290        synchronized (this) {
10291            mController = controller;
10292            Watchdog.getInstance().setActivityController(controller);
10293        }
10294    }
10295
10296    @Override
10297    public void setUserIsMonkey(boolean userIsMonkey) {
10298        synchronized (this) {
10299            synchronized (mPidsSelfLocked) {
10300                final int callingPid = Binder.getCallingPid();
10301                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10302                if (precessRecord == null) {
10303                    throw new SecurityException("Unknown process: " + callingPid);
10304                }
10305                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10306                    throw new SecurityException("Only an instrumentation process "
10307                            + "with a UiAutomation can call setUserIsMonkey");
10308                }
10309            }
10310            mUserIsMonkey = userIsMonkey;
10311        }
10312    }
10313
10314    @Override
10315    public boolean isUserAMonkey() {
10316        synchronized (this) {
10317            // If there is a controller also implies the user is a monkey.
10318            return (mUserIsMonkey || mController != null);
10319        }
10320    }
10321
10322    public void requestBugReport() {
10323        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10324        SystemProperties.set("ctl.start", "bugreport");
10325    }
10326
10327    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10328        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10329    }
10330
10331    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10332        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10333            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10334        }
10335        return KEY_DISPATCHING_TIMEOUT;
10336    }
10337
10338    @Override
10339    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10340        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10341                != PackageManager.PERMISSION_GRANTED) {
10342            throw new SecurityException("Requires permission "
10343                    + android.Manifest.permission.FILTER_EVENTS);
10344        }
10345        ProcessRecord proc;
10346        long timeout;
10347        synchronized (this) {
10348            synchronized (mPidsSelfLocked) {
10349                proc = mPidsSelfLocked.get(pid);
10350            }
10351            timeout = getInputDispatchingTimeoutLocked(proc);
10352        }
10353
10354        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10355            return -1;
10356        }
10357
10358        return timeout;
10359    }
10360
10361    /**
10362     * Handle input dispatching timeouts.
10363     * Returns whether input dispatching should be aborted or not.
10364     */
10365    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10366            final ActivityRecord activity, final ActivityRecord parent,
10367            final boolean aboveSystem, String reason) {
10368        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10369                != PackageManager.PERMISSION_GRANTED) {
10370            throw new SecurityException("Requires permission "
10371                    + android.Manifest.permission.FILTER_EVENTS);
10372        }
10373
10374        final String annotation;
10375        if (reason == null) {
10376            annotation = "Input dispatching timed out";
10377        } else {
10378            annotation = "Input dispatching timed out (" + reason + ")";
10379        }
10380
10381        if (proc != null) {
10382            synchronized (this) {
10383                if (proc.debugging) {
10384                    return false;
10385                }
10386
10387                if (mDidDexOpt) {
10388                    // Give more time since we were dexopting.
10389                    mDidDexOpt = false;
10390                    return false;
10391                }
10392
10393                if (proc.instrumentationClass != null) {
10394                    Bundle info = new Bundle();
10395                    info.putString("shortMsg", "keyDispatchingTimedOut");
10396                    info.putString("longMsg", annotation);
10397                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10398                    return true;
10399                }
10400            }
10401            mHandler.post(new Runnable() {
10402                @Override
10403                public void run() {
10404                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10405                }
10406            });
10407        }
10408
10409        return true;
10410    }
10411
10412    public Bundle getAssistContextExtras(int requestType) {
10413        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10414                UserHandle.getCallingUserId());
10415        if (pae == null) {
10416            return null;
10417        }
10418        synchronized (pae) {
10419            while (!pae.haveResult) {
10420                try {
10421                    pae.wait();
10422                } catch (InterruptedException e) {
10423                }
10424            }
10425            if (pae.result != null) {
10426                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10427            }
10428        }
10429        synchronized (this) {
10430            mPendingAssistExtras.remove(pae);
10431            mHandler.removeCallbacks(pae);
10432        }
10433        return pae.extras;
10434    }
10435
10436    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10437            int userHandle) {
10438        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10439                "getAssistContextExtras()");
10440        PendingAssistExtras pae;
10441        Bundle extras = new Bundle();
10442        synchronized (this) {
10443            ActivityRecord activity = getFocusedStack().mResumedActivity;
10444            if (activity == null) {
10445                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10446                return null;
10447            }
10448            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10449            if (activity.app == null || activity.app.thread == null) {
10450                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10451                return null;
10452            }
10453            if (activity.app.pid == Binder.getCallingPid()) {
10454                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10455                return null;
10456            }
10457            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10458            try {
10459                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10460                        requestType);
10461                mPendingAssistExtras.add(pae);
10462                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10463            } catch (RemoteException e) {
10464                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10465                return null;
10466            }
10467            return pae;
10468        }
10469    }
10470
10471    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10472        PendingAssistExtras pae = (PendingAssistExtras)token;
10473        synchronized (pae) {
10474            pae.result = extras;
10475            pae.haveResult = true;
10476            pae.notifyAll();
10477            if (pae.intent == null) {
10478                // Caller is just waiting for the result.
10479                return;
10480            }
10481        }
10482
10483        // We are now ready to launch the assist activity.
10484        synchronized (this) {
10485            boolean exists = mPendingAssistExtras.remove(pae);
10486            mHandler.removeCallbacks(pae);
10487            if (!exists) {
10488                // Timed out.
10489                return;
10490            }
10491        }
10492        pae.intent.replaceExtras(extras);
10493        if (pae.hint != null) {
10494            pae.intent.putExtra(pae.hint, true);
10495        }
10496        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10497                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10498                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10499        closeSystemDialogs("assist");
10500        try {
10501            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10502        } catch (ActivityNotFoundException e) {
10503            Slog.w(TAG, "No activity to handle assist action.", e);
10504        }
10505    }
10506
10507    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10508        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10509    }
10510
10511    public void registerProcessObserver(IProcessObserver observer) {
10512        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10513                "registerProcessObserver()");
10514        synchronized (this) {
10515            mProcessObservers.register(observer);
10516        }
10517    }
10518
10519    @Override
10520    public void unregisterProcessObserver(IProcessObserver observer) {
10521        synchronized (this) {
10522            mProcessObservers.unregister(observer);
10523        }
10524    }
10525
10526    @Override
10527    public boolean convertFromTranslucent(IBinder token) {
10528        final long origId = Binder.clearCallingIdentity();
10529        try {
10530            synchronized (this) {
10531                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10532                if (r == null) {
10533                    return false;
10534                }
10535                final boolean translucentChanged = r.changeWindowTranslucency(true);
10536                if (translucentChanged) {
10537                    r.task.stack.releaseBackgroundResources();
10538                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10539                }
10540                mWindowManager.setAppFullscreen(token, true);
10541                return translucentChanged;
10542            }
10543        } finally {
10544            Binder.restoreCallingIdentity(origId);
10545        }
10546    }
10547
10548    @Override
10549    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10550        final long origId = Binder.clearCallingIdentity();
10551        try {
10552            synchronized (this) {
10553                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10554                if (r == null) {
10555                    return false;
10556                }
10557                int index = r.task.mActivities.lastIndexOf(r);
10558                if (index > 0) {
10559                    ActivityRecord under = r.task.mActivities.get(index - 1);
10560                    under.returningOptions = options;
10561                }
10562                final boolean translucentChanged = r.changeWindowTranslucency(false);
10563                if (translucentChanged) {
10564                    r.task.stack.convertToTranslucent(r);
10565                }
10566                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10567                mWindowManager.setAppFullscreen(token, false);
10568                return translucentChanged;
10569            }
10570        } finally {
10571            Binder.restoreCallingIdentity(origId);
10572        }
10573    }
10574
10575    @Override
10576    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10577        final long origId = Binder.clearCallingIdentity();
10578        try {
10579            synchronized (this) {
10580                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10581                if (r != null) {
10582                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10583                }
10584            }
10585            return false;
10586        } finally {
10587            Binder.restoreCallingIdentity(origId);
10588        }
10589    }
10590
10591    @Override
10592    public boolean isBackgroundVisibleBehind(IBinder token) {
10593        final long origId = Binder.clearCallingIdentity();
10594        try {
10595            synchronized (this) {
10596                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10597                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10598                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10599                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10600                return visible;
10601            }
10602        } finally {
10603            Binder.restoreCallingIdentity(origId);
10604        }
10605    }
10606
10607    @Override
10608    public ActivityOptions getActivityOptions(IBinder token) {
10609        final long origId = Binder.clearCallingIdentity();
10610        try {
10611            synchronized (this) {
10612                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10613                if (r != null) {
10614                    final ActivityOptions activityOptions = r.pendingOptions;
10615                    r.pendingOptions = null;
10616                    return activityOptions;
10617                }
10618                return null;
10619            }
10620        } finally {
10621            Binder.restoreCallingIdentity(origId);
10622        }
10623    }
10624
10625    @Override
10626    public void setImmersive(IBinder token, boolean immersive) {
10627        synchronized(this) {
10628            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10629            if (r == null) {
10630                throw new IllegalArgumentException();
10631            }
10632            r.immersive = immersive;
10633
10634            // update associated state if we're frontmost
10635            if (r == mFocusedActivity) {
10636                if (DEBUG_IMMERSIVE) {
10637                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10638                }
10639                applyUpdateLockStateLocked(r);
10640            }
10641        }
10642    }
10643
10644    @Override
10645    public boolean isImmersive(IBinder token) {
10646        synchronized (this) {
10647            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10648            if (r == null) {
10649                throw new IllegalArgumentException();
10650            }
10651            return r.immersive;
10652        }
10653    }
10654
10655    public boolean isTopActivityImmersive() {
10656        enforceNotIsolatedCaller("startActivity");
10657        synchronized (this) {
10658            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10659            return (r != null) ? r.immersive : false;
10660        }
10661    }
10662
10663    @Override
10664    public boolean isTopOfTask(IBinder token) {
10665        synchronized (this) {
10666            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10667            if (r == null) {
10668                throw new IllegalArgumentException();
10669            }
10670            return r.task.getTopActivity() == r;
10671        }
10672    }
10673
10674    public final void enterSafeMode() {
10675        synchronized(this) {
10676            // It only makes sense to do this before the system is ready
10677            // and started launching other packages.
10678            if (!mSystemReady) {
10679                try {
10680                    AppGlobals.getPackageManager().enterSafeMode();
10681                } catch (RemoteException e) {
10682                }
10683            }
10684
10685            mSafeMode = true;
10686        }
10687    }
10688
10689    public final void showSafeModeOverlay() {
10690        View v = LayoutInflater.from(mContext).inflate(
10691                com.android.internal.R.layout.safe_mode, null);
10692        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10693        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10694        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10695        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10696        lp.gravity = Gravity.BOTTOM | Gravity.START;
10697        lp.format = v.getBackground().getOpacity();
10698        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10699                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10700        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10701        ((WindowManager)mContext.getSystemService(
10702                Context.WINDOW_SERVICE)).addView(v, lp);
10703    }
10704
10705    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10706        if (!(sender instanceof PendingIntentRecord)) {
10707            return;
10708        }
10709        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10710        synchronized (stats) {
10711            if (mBatteryStatsService.isOnBattery()) {
10712                mBatteryStatsService.enforceCallingPermission();
10713                PendingIntentRecord rec = (PendingIntentRecord)sender;
10714                int MY_UID = Binder.getCallingUid();
10715                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10716                BatteryStatsImpl.Uid.Pkg pkg =
10717                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10718                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10719                pkg.incWakeupsLocked();
10720            }
10721        }
10722    }
10723
10724    public boolean killPids(int[] pids, String pReason, boolean secure) {
10725        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10726            throw new SecurityException("killPids only available to the system");
10727        }
10728        String reason = (pReason == null) ? "Unknown" : pReason;
10729        // XXX Note: don't acquire main activity lock here, because the window
10730        // manager calls in with its locks held.
10731
10732        boolean killed = false;
10733        synchronized (mPidsSelfLocked) {
10734            int[] types = new int[pids.length];
10735            int worstType = 0;
10736            for (int i=0; i<pids.length; i++) {
10737                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10738                if (proc != null) {
10739                    int type = proc.setAdj;
10740                    types[i] = type;
10741                    if (type > worstType) {
10742                        worstType = type;
10743                    }
10744                }
10745            }
10746
10747            // If the worst oom_adj is somewhere in the cached proc LRU range,
10748            // then constrain it so we will kill all cached procs.
10749            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10750                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10751                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10752            }
10753
10754            // If this is not a secure call, don't let it kill processes that
10755            // are important.
10756            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10757                worstType = ProcessList.SERVICE_ADJ;
10758            }
10759
10760            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10761            for (int i=0; i<pids.length; i++) {
10762                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10763                if (proc == null) {
10764                    continue;
10765                }
10766                int adj = proc.setAdj;
10767                if (adj >= worstType && !proc.killedByAm) {
10768                    proc.kill(reason, true);
10769                    killed = true;
10770                }
10771            }
10772        }
10773        return killed;
10774    }
10775
10776    @Override
10777    public void killUid(int uid, String reason) {
10778        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10779            throw new SecurityException("killUid only available to the system");
10780        }
10781        synchronized (this) {
10782            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10783                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10784                    reason != null ? reason : "kill uid");
10785        }
10786    }
10787
10788    @Override
10789    public boolean killProcessesBelowForeground(String reason) {
10790        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10791            throw new SecurityException("killProcessesBelowForeground() only available to system");
10792        }
10793
10794        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10795    }
10796
10797    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10798        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10799            throw new SecurityException("killProcessesBelowAdj() only available to system");
10800        }
10801
10802        boolean killed = false;
10803        synchronized (mPidsSelfLocked) {
10804            final int size = mPidsSelfLocked.size();
10805            for (int i = 0; i < size; i++) {
10806                final int pid = mPidsSelfLocked.keyAt(i);
10807                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10808                if (proc == null) continue;
10809
10810                final int adj = proc.setAdj;
10811                if (adj > belowAdj && !proc.killedByAm) {
10812                    proc.kill(reason, true);
10813                    killed = true;
10814                }
10815            }
10816        }
10817        return killed;
10818    }
10819
10820    @Override
10821    public void hang(final IBinder who, boolean allowRestart) {
10822        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10823                != PackageManager.PERMISSION_GRANTED) {
10824            throw new SecurityException("Requires permission "
10825                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10826        }
10827
10828        final IBinder.DeathRecipient death = new DeathRecipient() {
10829            @Override
10830            public void binderDied() {
10831                synchronized (this) {
10832                    notifyAll();
10833                }
10834            }
10835        };
10836
10837        try {
10838            who.linkToDeath(death, 0);
10839        } catch (RemoteException e) {
10840            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10841            return;
10842        }
10843
10844        synchronized (this) {
10845            Watchdog.getInstance().setAllowRestart(allowRestart);
10846            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10847            synchronized (death) {
10848                while (who.isBinderAlive()) {
10849                    try {
10850                        death.wait();
10851                    } catch (InterruptedException e) {
10852                    }
10853                }
10854            }
10855            Watchdog.getInstance().setAllowRestart(true);
10856        }
10857    }
10858
10859    @Override
10860    public void restart() {
10861        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10862                != PackageManager.PERMISSION_GRANTED) {
10863            throw new SecurityException("Requires permission "
10864                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10865        }
10866
10867        Log.i(TAG, "Sending shutdown broadcast...");
10868
10869        BroadcastReceiver br = new BroadcastReceiver() {
10870            @Override public void onReceive(Context context, Intent intent) {
10871                // Now the broadcast is done, finish up the low-level shutdown.
10872                Log.i(TAG, "Shutting down activity manager...");
10873                shutdown(10000);
10874                Log.i(TAG, "Shutdown complete, restarting!");
10875                Process.killProcess(Process.myPid());
10876                System.exit(10);
10877            }
10878        };
10879
10880        // First send the high-level shut down broadcast.
10881        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10882        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10883        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10884        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10885        mContext.sendOrderedBroadcastAsUser(intent,
10886                UserHandle.ALL, null, br, mHandler, 0, null, null);
10887        */
10888        br.onReceive(mContext, intent);
10889    }
10890
10891    private long getLowRamTimeSinceIdle(long now) {
10892        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10893    }
10894
10895    @Override
10896    public void performIdleMaintenance() {
10897        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10898                != PackageManager.PERMISSION_GRANTED) {
10899            throw new SecurityException("Requires permission "
10900                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10901        }
10902
10903        synchronized (this) {
10904            final long now = SystemClock.uptimeMillis();
10905            final long timeSinceLastIdle = now - mLastIdleTime;
10906            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10907            mLastIdleTime = now;
10908            mLowRamTimeSinceLastIdle = 0;
10909            if (mLowRamStartTime != 0) {
10910                mLowRamStartTime = now;
10911            }
10912
10913            StringBuilder sb = new StringBuilder(128);
10914            sb.append("Idle maintenance over ");
10915            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10916            sb.append(" low RAM for ");
10917            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10918            Slog.i(TAG, sb.toString());
10919
10920            // If at least 1/3 of our time since the last idle period has been spent
10921            // with RAM low, then we want to kill processes.
10922            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10923
10924            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10925                ProcessRecord proc = mLruProcesses.get(i);
10926                if (proc.notCachedSinceIdle) {
10927                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10928                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10929                        if (doKilling && proc.initialIdlePss != 0
10930                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10931                            sb = new StringBuilder(128);
10932                            sb.append("Kill");
10933                            sb.append(proc.processName);
10934                            sb.append(" in idle maint: pss=");
10935                            sb.append(proc.lastPss);
10936                            sb.append(", initialPss=");
10937                            sb.append(proc.initialIdlePss);
10938                            sb.append(", period=");
10939                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10940                            sb.append(", lowRamPeriod=");
10941                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10942                            Slog.wtfQuiet(TAG, sb.toString());
10943                            proc.kill("idle maint (pss " + proc.lastPss
10944                                    + " from " + proc.initialIdlePss + ")", true);
10945                        }
10946                    }
10947                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10948                    proc.notCachedSinceIdle = true;
10949                    proc.initialIdlePss = 0;
10950                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10951                            mTestPssMode, isSleeping(), now);
10952                }
10953            }
10954
10955            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10956            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10957        }
10958    }
10959
10960    private void retrieveSettings() {
10961        final ContentResolver resolver = mContext.getContentResolver();
10962        String debugApp = Settings.Global.getString(
10963            resolver, Settings.Global.DEBUG_APP);
10964        boolean waitForDebugger = Settings.Global.getInt(
10965            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10966        boolean alwaysFinishActivities = Settings.Global.getInt(
10967            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10968        boolean forceRtl = Settings.Global.getInt(
10969                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10970        // Transfer any global setting for forcing RTL layout, into a System Property
10971        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10972
10973        Configuration configuration = new Configuration();
10974        Settings.System.getConfiguration(resolver, configuration);
10975        if (forceRtl) {
10976            // This will take care of setting the correct layout direction flags
10977            configuration.setLayoutDirection(configuration.locale);
10978        }
10979
10980        synchronized (this) {
10981            mDebugApp = mOrigDebugApp = debugApp;
10982            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10983            mAlwaysFinishActivities = alwaysFinishActivities;
10984            // This happens before any activities are started, so we can
10985            // change mConfiguration in-place.
10986            updateConfigurationLocked(configuration, null, false, true);
10987            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10988        }
10989    }
10990
10991    /** Loads resources after the current configuration has been set. */
10992    private void loadResourcesOnSystemReady() {
10993        final Resources res = mContext.getResources();
10994        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10995        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10996        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10997    }
10998
10999    public boolean testIsSystemReady() {
11000        // no need to synchronize(this) just to read & return the value
11001        return mSystemReady;
11002    }
11003
11004    private static File getCalledPreBootReceiversFile() {
11005        File dataDir = Environment.getDataDirectory();
11006        File systemDir = new File(dataDir, "system");
11007        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11008        return fname;
11009    }
11010
11011    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11012        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11013        File file = getCalledPreBootReceiversFile();
11014        FileInputStream fis = null;
11015        try {
11016            fis = new FileInputStream(file);
11017            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11018            int fvers = dis.readInt();
11019            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11020                String vers = dis.readUTF();
11021                String codename = dis.readUTF();
11022                String build = dis.readUTF();
11023                if (android.os.Build.VERSION.RELEASE.equals(vers)
11024                        && android.os.Build.VERSION.CODENAME.equals(codename)
11025                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11026                    int num = dis.readInt();
11027                    while (num > 0) {
11028                        num--;
11029                        String pkg = dis.readUTF();
11030                        String cls = dis.readUTF();
11031                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11032                    }
11033                }
11034            }
11035        } catch (FileNotFoundException e) {
11036        } catch (IOException e) {
11037            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11038        } finally {
11039            if (fis != null) {
11040                try {
11041                    fis.close();
11042                } catch (IOException e) {
11043                }
11044            }
11045        }
11046        return lastDoneReceivers;
11047    }
11048
11049    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11050        File file = getCalledPreBootReceiversFile();
11051        FileOutputStream fos = null;
11052        DataOutputStream dos = null;
11053        try {
11054            fos = new FileOutputStream(file);
11055            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11056            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11057            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11058            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11059            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11060            dos.writeInt(list.size());
11061            for (int i=0; i<list.size(); i++) {
11062                dos.writeUTF(list.get(i).getPackageName());
11063                dos.writeUTF(list.get(i).getClassName());
11064            }
11065        } catch (IOException e) {
11066            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11067            file.delete();
11068        } finally {
11069            FileUtils.sync(fos);
11070            if (dos != null) {
11071                try {
11072                    dos.close();
11073                } catch (IOException e) {
11074                    // TODO Auto-generated catch block
11075                    e.printStackTrace();
11076                }
11077            }
11078        }
11079    }
11080
11081    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11082            ArrayList<ComponentName> doneReceivers, int userId) {
11083        boolean waitingUpdate = false;
11084        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11085        List<ResolveInfo> ris = null;
11086        try {
11087            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11088                    intent, null, 0, userId);
11089        } catch (RemoteException e) {
11090        }
11091        if (ris != null) {
11092            for (int i=ris.size()-1; i>=0; i--) {
11093                if ((ris.get(i).activityInfo.applicationInfo.flags
11094                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11095                    ris.remove(i);
11096                }
11097            }
11098            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11099
11100            // For User 0, load the version number. When delivering to a new user, deliver
11101            // to all receivers.
11102            if (userId == UserHandle.USER_OWNER) {
11103                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11104                for (int i=0; i<ris.size(); i++) {
11105                    ActivityInfo ai = ris.get(i).activityInfo;
11106                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11107                    if (lastDoneReceivers.contains(comp)) {
11108                        // We already did the pre boot receiver for this app with the current
11109                        // platform version, so don't do it again...
11110                        ris.remove(i);
11111                        i--;
11112                        // ...however, do keep it as one that has been done, so we don't
11113                        // forget about it when rewriting the file of last done receivers.
11114                        doneReceivers.add(comp);
11115                    }
11116                }
11117            }
11118
11119            // If primary user, send broadcast to all available users, else just to userId
11120            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11121                    : new int[] { userId };
11122            for (int i = 0; i < ris.size(); i++) {
11123                ActivityInfo ai = ris.get(i).activityInfo;
11124                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11125                doneReceivers.add(comp);
11126                intent.setComponent(comp);
11127                for (int j=0; j<users.length; j++) {
11128                    IIntentReceiver finisher = null;
11129                    // On last receiver and user, set up a completion callback
11130                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11131                        finisher = new IIntentReceiver.Stub() {
11132                            public void performReceive(Intent intent, int resultCode,
11133                                    String data, Bundle extras, boolean ordered,
11134                                    boolean sticky, int sendingUser) {
11135                                // The raw IIntentReceiver interface is called
11136                                // with the AM lock held, so redispatch to
11137                                // execute our code without the lock.
11138                                mHandler.post(onFinishCallback);
11139                            }
11140                        };
11141                    }
11142                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11143                            + " for user " + users[j]);
11144                    broadcastIntentLocked(null, null, intent, null, finisher,
11145                            0, null, null, null, AppOpsManager.OP_NONE,
11146                            true, false, MY_PID, Process.SYSTEM_UID,
11147                            users[j]);
11148                    if (finisher != null) {
11149                        waitingUpdate = true;
11150                    }
11151                }
11152            }
11153        }
11154
11155        return waitingUpdate;
11156    }
11157
11158    public void systemReady(final Runnable goingCallback) {
11159        synchronized(this) {
11160            if (mSystemReady) {
11161                // If we're done calling all the receivers, run the next "boot phase" passed in
11162                // by the SystemServer
11163                if (goingCallback != null) {
11164                    goingCallback.run();
11165                }
11166                return;
11167            }
11168
11169            // Make sure we have the current profile info, since it is needed for
11170            // security checks.
11171            updateCurrentProfileIdsLocked();
11172
11173            if (mRecentTasks == null) {
11174                mRecentTasks = mTaskPersister.restoreTasksLocked();
11175                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11176                if (!mRecentTasks.isEmpty()) {
11177                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11178                }
11179                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11180                mTaskPersister.startPersisting();
11181            }
11182
11183            // Check to see if there are any update receivers to run.
11184            if (!mDidUpdate) {
11185                if (mWaitingUpdate) {
11186                    return;
11187                }
11188                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11189                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11190                    public void run() {
11191                        synchronized (ActivityManagerService.this) {
11192                            mDidUpdate = true;
11193                        }
11194                        writeLastDonePreBootReceivers(doneReceivers);
11195                        showBootMessage(mContext.getText(
11196                                R.string.android_upgrading_complete),
11197                                false);
11198                        systemReady(goingCallback);
11199                    }
11200                }, doneReceivers, UserHandle.USER_OWNER);
11201
11202                if (mWaitingUpdate) {
11203                    return;
11204                }
11205                mDidUpdate = true;
11206            }
11207
11208            mAppOpsService.systemReady();
11209            mSystemReady = true;
11210        }
11211
11212        ArrayList<ProcessRecord> procsToKill = null;
11213        synchronized(mPidsSelfLocked) {
11214            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11215                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11216                if (!isAllowedWhileBooting(proc.info)){
11217                    if (procsToKill == null) {
11218                        procsToKill = new ArrayList<ProcessRecord>();
11219                    }
11220                    procsToKill.add(proc);
11221                }
11222            }
11223        }
11224
11225        synchronized(this) {
11226            if (procsToKill != null) {
11227                for (int i=procsToKill.size()-1; i>=0; i--) {
11228                    ProcessRecord proc = procsToKill.get(i);
11229                    Slog.i(TAG, "Removing system update proc: " + proc);
11230                    removeProcessLocked(proc, true, false, "system update done");
11231                }
11232            }
11233
11234            // Now that we have cleaned up any update processes, we
11235            // are ready to start launching real processes and know that
11236            // we won't trample on them any more.
11237            mProcessesReady = true;
11238        }
11239
11240        Slog.i(TAG, "System now ready");
11241        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11242            SystemClock.uptimeMillis());
11243
11244        synchronized(this) {
11245            // Make sure we have no pre-ready processes sitting around.
11246
11247            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11248                ResolveInfo ri = mContext.getPackageManager()
11249                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11250                                STOCK_PM_FLAGS);
11251                CharSequence errorMsg = null;
11252                if (ri != null) {
11253                    ActivityInfo ai = ri.activityInfo;
11254                    ApplicationInfo app = ai.applicationInfo;
11255                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11256                        mTopAction = Intent.ACTION_FACTORY_TEST;
11257                        mTopData = null;
11258                        mTopComponent = new ComponentName(app.packageName,
11259                                ai.name);
11260                    } else {
11261                        errorMsg = mContext.getResources().getText(
11262                                com.android.internal.R.string.factorytest_not_system);
11263                    }
11264                } else {
11265                    errorMsg = mContext.getResources().getText(
11266                            com.android.internal.R.string.factorytest_no_action);
11267                }
11268                if (errorMsg != null) {
11269                    mTopAction = null;
11270                    mTopData = null;
11271                    mTopComponent = null;
11272                    Message msg = Message.obtain();
11273                    msg.what = SHOW_FACTORY_ERROR_MSG;
11274                    msg.getData().putCharSequence("msg", errorMsg);
11275                    mHandler.sendMessage(msg);
11276                }
11277            }
11278        }
11279
11280        retrieveSettings();
11281        loadResourcesOnSystemReady();
11282
11283        synchronized (this) {
11284            readGrantedUriPermissionsLocked();
11285        }
11286
11287        if (goingCallback != null) goingCallback.run();
11288
11289        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11290                Integer.toString(mCurrentUserId), mCurrentUserId);
11291        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11292                Integer.toString(mCurrentUserId), mCurrentUserId);
11293        mSystemServiceManager.startUser(mCurrentUserId);
11294
11295        synchronized (this) {
11296            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11297                try {
11298                    List apps = AppGlobals.getPackageManager().
11299                        getPersistentApplications(STOCK_PM_FLAGS);
11300                    if (apps != null) {
11301                        int N = apps.size();
11302                        int i;
11303                        for (i=0; i<N; i++) {
11304                            ApplicationInfo info
11305                                = (ApplicationInfo)apps.get(i);
11306                            if (info != null &&
11307                                    !info.packageName.equals("android")) {
11308                                addAppLocked(info, false, null /* ABI override */);
11309                            }
11310                        }
11311                    }
11312                } catch (RemoteException ex) {
11313                    // pm is in same process, this will never happen.
11314                }
11315            }
11316
11317            // Start up initial activity.
11318            mBooting = true;
11319            startHomeActivityLocked(mCurrentUserId);
11320
11321            try {
11322                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11323                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11324                            + " data partition or your device will be unstable.");
11325                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11326                }
11327            } catch (RemoteException e) {
11328            }
11329
11330            if (!Build.isFingerprintConsistent()) {
11331                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11332                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11333            }
11334
11335            long ident = Binder.clearCallingIdentity();
11336            try {
11337                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11338                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11339                        | Intent.FLAG_RECEIVER_FOREGROUND);
11340                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11341                broadcastIntentLocked(null, null, intent,
11342                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11343                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11344                intent = new Intent(Intent.ACTION_USER_STARTING);
11345                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11346                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11347                broadcastIntentLocked(null, null, intent,
11348                        null, new IIntentReceiver.Stub() {
11349                            @Override
11350                            public void performReceive(Intent intent, int resultCode, String data,
11351                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11352                                    throws RemoteException {
11353                            }
11354                        }, 0, null, null,
11355                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11356                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11357            } catch (Throwable t) {
11358                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11359            } finally {
11360                Binder.restoreCallingIdentity(ident);
11361            }
11362            mStackSupervisor.resumeTopActivitiesLocked();
11363            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11364        }
11365    }
11366
11367    private boolean makeAppCrashingLocked(ProcessRecord app,
11368            String shortMsg, String longMsg, String stackTrace) {
11369        app.crashing = true;
11370        app.crashingReport = generateProcessError(app,
11371                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11372        startAppProblemLocked(app);
11373        app.stopFreezingAllLocked();
11374        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11375    }
11376
11377    private void makeAppNotRespondingLocked(ProcessRecord app,
11378            String activity, String shortMsg, String longMsg) {
11379        app.notResponding = true;
11380        app.notRespondingReport = generateProcessError(app,
11381                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11382                activity, shortMsg, longMsg, null);
11383        startAppProblemLocked(app);
11384        app.stopFreezingAllLocked();
11385    }
11386
11387    /**
11388     * Generate a process error record, suitable for attachment to a ProcessRecord.
11389     *
11390     * @param app The ProcessRecord in which the error occurred.
11391     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11392     *                      ActivityManager.AppErrorStateInfo
11393     * @param activity The activity associated with the crash, if known.
11394     * @param shortMsg Short message describing the crash.
11395     * @param longMsg Long message describing the crash.
11396     * @param stackTrace Full crash stack trace, may be null.
11397     *
11398     * @return Returns a fully-formed AppErrorStateInfo record.
11399     */
11400    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11401            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11402        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11403
11404        report.condition = condition;
11405        report.processName = app.processName;
11406        report.pid = app.pid;
11407        report.uid = app.info.uid;
11408        report.tag = activity;
11409        report.shortMsg = shortMsg;
11410        report.longMsg = longMsg;
11411        report.stackTrace = stackTrace;
11412
11413        return report;
11414    }
11415
11416    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11417        synchronized (this) {
11418            app.crashing = false;
11419            app.crashingReport = null;
11420            app.notResponding = false;
11421            app.notRespondingReport = null;
11422            if (app.anrDialog == fromDialog) {
11423                app.anrDialog = null;
11424            }
11425            if (app.waitDialog == fromDialog) {
11426                app.waitDialog = null;
11427            }
11428            if (app.pid > 0 && app.pid != MY_PID) {
11429                handleAppCrashLocked(app, null, null, null);
11430                app.kill("user request after error", true);
11431            }
11432        }
11433    }
11434
11435    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11436            String stackTrace) {
11437        long now = SystemClock.uptimeMillis();
11438
11439        Long crashTime;
11440        if (!app.isolated) {
11441            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11442        } else {
11443            crashTime = null;
11444        }
11445        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11446            // This process loses!
11447            Slog.w(TAG, "Process " + app.info.processName
11448                    + " has crashed too many times: killing!");
11449            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11450                    app.userId, app.info.processName, app.uid);
11451            mStackSupervisor.handleAppCrashLocked(app);
11452            if (!app.persistent) {
11453                // We don't want to start this process again until the user
11454                // explicitly does so...  but for persistent process, we really
11455                // need to keep it running.  If a persistent process is actually
11456                // repeatedly crashing, then badness for everyone.
11457                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11458                        app.info.processName);
11459                if (!app.isolated) {
11460                    // XXX We don't have a way to mark isolated processes
11461                    // as bad, since they don't have a peristent identity.
11462                    mBadProcesses.put(app.info.processName, app.uid,
11463                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11464                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11465                }
11466                app.bad = true;
11467                app.removed = true;
11468                // Don't let services in this process be restarted and potentially
11469                // annoy the user repeatedly.  Unless it is persistent, since those
11470                // processes run critical code.
11471                removeProcessLocked(app, false, false, "crash");
11472                mStackSupervisor.resumeTopActivitiesLocked();
11473                return false;
11474            }
11475            mStackSupervisor.resumeTopActivitiesLocked();
11476        } else {
11477            mStackSupervisor.finishTopRunningActivityLocked(app);
11478        }
11479
11480        // Bump up the crash count of any services currently running in the proc.
11481        for (int i=app.services.size()-1; i>=0; i--) {
11482            // Any services running in the application need to be placed
11483            // back in the pending list.
11484            ServiceRecord sr = app.services.valueAt(i);
11485            sr.crashCount++;
11486        }
11487
11488        // If the crashing process is what we consider to be the "home process" and it has been
11489        // replaced by a third-party app, clear the package preferred activities from packages
11490        // with a home activity running in the process to prevent a repeatedly crashing app
11491        // from blocking the user to manually clear the list.
11492        final ArrayList<ActivityRecord> activities = app.activities;
11493        if (app == mHomeProcess && activities.size() > 0
11494                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11495            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11496                final ActivityRecord r = activities.get(activityNdx);
11497                if (r.isHomeActivity()) {
11498                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11499                    try {
11500                        ActivityThread.getPackageManager()
11501                                .clearPackagePreferredActivities(r.packageName);
11502                    } catch (RemoteException c) {
11503                        // pm is in same process, this will never happen.
11504                    }
11505                }
11506            }
11507        }
11508
11509        if (!app.isolated) {
11510            // XXX Can't keep track of crash times for isolated processes,
11511            // because they don't have a perisistent identity.
11512            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11513        }
11514
11515        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11516        return true;
11517    }
11518
11519    void startAppProblemLocked(ProcessRecord app) {
11520        // If this app is not running under the current user, then we
11521        // can't give it a report button because that would require
11522        // launching the report UI under a different user.
11523        app.errorReportReceiver = null;
11524
11525        for (int userId : mCurrentProfileIds) {
11526            if (app.userId == userId) {
11527                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11528                        mContext, app.info.packageName, app.info.flags);
11529            }
11530        }
11531        skipCurrentReceiverLocked(app);
11532    }
11533
11534    void skipCurrentReceiverLocked(ProcessRecord app) {
11535        for (BroadcastQueue queue : mBroadcastQueues) {
11536            queue.skipCurrentReceiverLocked(app);
11537        }
11538    }
11539
11540    /**
11541     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11542     * The application process will exit immediately after this call returns.
11543     * @param app object of the crashing app, null for the system server
11544     * @param crashInfo describing the exception
11545     */
11546    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11547        ProcessRecord r = findAppProcess(app, "Crash");
11548        final String processName = app == null ? "system_server"
11549                : (r == null ? "unknown" : r.processName);
11550
11551        handleApplicationCrashInner("crash", r, processName, crashInfo);
11552    }
11553
11554    /* Native crash reporting uses this inner version because it needs to be somewhat
11555     * decoupled from the AM-managed cleanup lifecycle
11556     */
11557    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11558            ApplicationErrorReport.CrashInfo crashInfo) {
11559        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11560                UserHandle.getUserId(Binder.getCallingUid()), processName,
11561                r == null ? -1 : r.info.flags,
11562                crashInfo.exceptionClassName,
11563                crashInfo.exceptionMessage,
11564                crashInfo.throwFileName,
11565                crashInfo.throwLineNumber);
11566
11567        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11568
11569        crashApplication(r, crashInfo);
11570    }
11571
11572    public void handleApplicationStrictModeViolation(
11573            IBinder app,
11574            int violationMask,
11575            StrictMode.ViolationInfo info) {
11576        ProcessRecord r = findAppProcess(app, "StrictMode");
11577        if (r == null) {
11578            return;
11579        }
11580
11581        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11582            Integer stackFingerprint = info.hashCode();
11583            boolean logIt = true;
11584            synchronized (mAlreadyLoggedViolatedStacks) {
11585                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11586                    logIt = false;
11587                    // TODO: sub-sample into EventLog for these, with
11588                    // the info.durationMillis?  Then we'd get
11589                    // the relative pain numbers, without logging all
11590                    // the stack traces repeatedly.  We'd want to do
11591                    // likewise in the client code, which also does
11592                    // dup suppression, before the Binder call.
11593                } else {
11594                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11595                        mAlreadyLoggedViolatedStacks.clear();
11596                    }
11597                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11598                }
11599            }
11600            if (logIt) {
11601                logStrictModeViolationToDropBox(r, info);
11602            }
11603        }
11604
11605        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11606            AppErrorResult result = new AppErrorResult();
11607            synchronized (this) {
11608                final long origId = Binder.clearCallingIdentity();
11609
11610                Message msg = Message.obtain();
11611                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11612                HashMap<String, Object> data = new HashMap<String, Object>();
11613                data.put("result", result);
11614                data.put("app", r);
11615                data.put("violationMask", violationMask);
11616                data.put("info", info);
11617                msg.obj = data;
11618                mHandler.sendMessage(msg);
11619
11620                Binder.restoreCallingIdentity(origId);
11621            }
11622            int res = result.get();
11623            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11624        }
11625    }
11626
11627    // Depending on the policy in effect, there could be a bunch of
11628    // these in quick succession so we try to batch these together to
11629    // minimize disk writes, number of dropbox entries, and maximize
11630    // compression, by having more fewer, larger records.
11631    private void logStrictModeViolationToDropBox(
11632            ProcessRecord process,
11633            StrictMode.ViolationInfo info) {
11634        if (info == null) {
11635            return;
11636        }
11637        final boolean isSystemApp = process == null ||
11638                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11639                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11640        final String processName = process == null ? "unknown" : process.processName;
11641        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11642        final DropBoxManager dbox = (DropBoxManager)
11643                mContext.getSystemService(Context.DROPBOX_SERVICE);
11644
11645        // Exit early if the dropbox isn't configured to accept this report type.
11646        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11647
11648        boolean bufferWasEmpty;
11649        boolean needsFlush;
11650        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11651        synchronized (sb) {
11652            bufferWasEmpty = sb.length() == 0;
11653            appendDropBoxProcessHeaders(process, processName, sb);
11654            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11655            sb.append("System-App: ").append(isSystemApp).append("\n");
11656            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11657            if (info.violationNumThisLoop != 0) {
11658                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11659            }
11660            if (info.numAnimationsRunning != 0) {
11661                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11662            }
11663            if (info.broadcastIntentAction != null) {
11664                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11665            }
11666            if (info.durationMillis != -1) {
11667                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11668            }
11669            if (info.numInstances != -1) {
11670                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11671            }
11672            if (info.tags != null) {
11673                for (String tag : info.tags) {
11674                    sb.append("Span-Tag: ").append(tag).append("\n");
11675                }
11676            }
11677            sb.append("\n");
11678            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11679                sb.append(info.crashInfo.stackTrace);
11680            }
11681            sb.append("\n");
11682
11683            // Only buffer up to ~64k.  Various logging bits truncate
11684            // things at 128k.
11685            needsFlush = (sb.length() > 64 * 1024);
11686        }
11687
11688        // Flush immediately if the buffer's grown too large, or this
11689        // is a non-system app.  Non-system apps are isolated with a
11690        // different tag & policy and not batched.
11691        //
11692        // Batching is useful during internal testing with
11693        // StrictMode settings turned up high.  Without batching,
11694        // thousands of separate files could be created on boot.
11695        if (!isSystemApp || needsFlush) {
11696            new Thread("Error dump: " + dropboxTag) {
11697                @Override
11698                public void run() {
11699                    String report;
11700                    synchronized (sb) {
11701                        report = sb.toString();
11702                        sb.delete(0, sb.length());
11703                        sb.trimToSize();
11704                    }
11705                    if (report.length() != 0) {
11706                        dbox.addText(dropboxTag, report);
11707                    }
11708                }
11709            }.start();
11710            return;
11711        }
11712
11713        // System app batching:
11714        if (!bufferWasEmpty) {
11715            // An existing dropbox-writing thread is outstanding, so
11716            // we don't need to start it up.  The existing thread will
11717            // catch the buffer appends we just did.
11718            return;
11719        }
11720
11721        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11722        // (After this point, we shouldn't access AMS internal data structures.)
11723        new Thread("Error dump: " + dropboxTag) {
11724            @Override
11725            public void run() {
11726                // 5 second sleep to let stacks arrive and be batched together
11727                try {
11728                    Thread.sleep(5000);  // 5 seconds
11729                } catch (InterruptedException e) {}
11730
11731                String errorReport;
11732                synchronized (mStrictModeBuffer) {
11733                    errorReport = mStrictModeBuffer.toString();
11734                    if (errorReport.length() == 0) {
11735                        return;
11736                    }
11737                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11738                    mStrictModeBuffer.trimToSize();
11739                }
11740                dbox.addText(dropboxTag, errorReport);
11741            }
11742        }.start();
11743    }
11744
11745    /**
11746     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11747     * @param app object of the crashing app, null for the system server
11748     * @param tag reported by the caller
11749     * @param system whether this wtf is coming from the system
11750     * @param crashInfo describing the context of the error
11751     * @return true if the process should exit immediately (WTF is fatal)
11752     */
11753    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11754            final ApplicationErrorReport.CrashInfo crashInfo) {
11755        final int callingUid = Binder.getCallingUid();
11756        final int callingPid = Binder.getCallingPid();
11757
11758        if (system) {
11759            // If this is coming from the system, we could very well have low-level
11760            // system locks held, so we want to do this all asynchronously.  And we
11761            // never want this to become fatal, so there is that too.
11762            mHandler.post(new Runnable() {
11763                @Override public void run() {
11764                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11765                }
11766            });
11767            return false;
11768        }
11769
11770        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11771                crashInfo);
11772
11773        if (r != null && r.pid != Process.myPid() &&
11774                Settings.Global.getInt(mContext.getContentResolver(),
11775                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11776            crashApplication(r, crashInfo);
11777            return true;
11778        } else {
11779            return false;
11780        }
11781    }
11782
11783    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11784            final ApplicationErrorReport.CrashInfo crashInfo) {
11785        final ProcessRecord r = findAppProcess(app, "WTF");
11786        final String processName = app == null ? "system_server"
11787                : (r == null ? "unknown" : r.processName);
11788
11789        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11790                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11791
11792        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11793
11794        return r;
11795    }
11796
11797    /**
11798     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11799     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11800     */
11801    private ProcessRecord findAppProcess(IBinder app, String reason) {
11802        if (app == null) {
11803            return null;
11804        }
11805
11806        synchronized (this) {
11807            final int NP = mProcessNames.getMap().size();
11808            for (int ip=0; ip<NP; ip++) {
11809                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11810                final int NA = apps.size();
11811                for (int ia=0; ia<NA; ia++) {
11812                    ProcessRecord p = apps.valueAt(ia);
11813                    if (p.thread != null && p.thread.asBinder() == app) {
11814                        return p;
11815                    }
11816                }
11817            }
11818
11819            Slog.w(TAG, "Can't find mystery application for " + reason
11820                    + " from pid=" + Binder.getCallingPid()
11821                    + " uid=" + Binder.getCallingUid() + ": " + app);
11822            return null;
11823        }
11824    }
11825
11826    /**
11827     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11828     * to append various headers to the dropbox log text.
11829     */
11830    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11831            StringBuilder sb) {
11832        // Watchdog thread ends up invoking this function (with
11833        // a null ProcessRecord) to add the stack file to dropbox.
11834        // Do not acquire a lock on this (am) in such cases, as it
11835        // could cause a potential deadlock, if and when watchdog
11836        // is invoked due to unavailability of lock on am and it
11837        // would prevent watchdog from killing system_server.
11838        if (process == null) {
11839            sb.append("Process: ").append(processName).append("\n");
11840            return;
11841        }
11842        // Note: ProcessRecord 'process' is guarded by the service
11843        // instance.  (notably process.pkgList, which could otherwise change
11844        // concurrently during execution of this method)
11845        synchronized (this) {
11846            sb.append("Process: ").append(processName).append("\n");
11847            int flags = process.info.flags;
11848            IPackageManager pm = AppGlobals.getPackageManager();
11849            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11850            for (int ip=0; ip<process.pkgList.size(); ip++) {
11851                String pkg = process.pkgList.keyAt(ip);
11852                sb.append("Package: ").append(pkg);
11853                try {
11854                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11855                    if (pi != null) {
11856                        sb.append(" v").append(pi.versionCode);
11857                        if (pi.versionName != null) {
11858                            sb.append(" (").append(pi.versionName).append(")");
11859                        }
11860                    }
11861                } catch (RemoteException e) {
11862                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11863                }
11864                sb.append("\n");
11865            }
11866        }
11867    }
11868
11869    private static String processClass(ProcessRecord process) {
11870        if (process == null || process.pid == MY_PID) {
11871            return "system_server";
11872        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11873            return "system_app";
11874        } else {
11875            return "data_app";
11876        }
11877    }
11878
11879    /**
11880     * Write a description of an error (crash, WTF, ANR) to the drop box.
11881     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11882     * @param process which caused the error, null means the system server
11883     * @param activity which triggered the error, null if unknown
11884     * @param parent activity related to the error, null if unknown
11885     * @param subject line related to the error, null if absent
11886     * @param report in long form describing the error, null if absent
11887     * @param logFile to include in the report, null if none
11888     * @param crashInfo giving an application stack trace, null if absent
11889     */
11890    public void addErrorToDropBox(String eventType,
11891            ProcessRecord process, String processName, ActivityRecord activity,
11892            ActivityRecord parent, String subject,
11893            final String report, final File logFile,
11894            final ApplicationErrorReport.CrashInfo crashInfo) {
11895        // NOTE -- this must never acquire the ActivityManagerService lock,
11896        // otherwise the watchdog may be prevented from resetting the system.
11897
11898        final String dropboxTag = processClass(process) + "_" + eventType;
11899        final DropBoxManager dbox = (DropBoxManager)
11900                mContext.getSystemService(Context.DROPBOX_SERVICE);
11901
11902        // Exit early if the dropbox isn't configured to accept this report type.
11903        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11904
11905        final StringBuilder sb = new StringBuilder(1024);
11906        appendDropBoxProcessHeaders(process, processName, sb);
11907        if (activity != null) {
11908            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11909        }
11910        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11911            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11912        }
11913        if (parent != null && parent != activity) {
11914            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11915        }
11916        if (subject != null) {
11917            sb.append("Subject: ").append(subject).append("\n");
11918        }
11919        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11920        if (Debug.isDebuggerConnected()) {
11921            sb.append("Debugger: Connected\n");
11922        }
11923        sb.append("\n");
11924
11925        // Do the rest in a worker thread to avoid blocking the caller on I/O
11926        // (After this point, we shouldn't access AMS internal data structures.)
11927        Thread worker = new Thread("Error dump: " + dropboxTag) {
11928            @Override
11929            public void run() {
11930                if (report != null) {
11931                    sb.append(report);
11932                }
11933                if (logFile != null) {
11934                    try {
11935                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11936                                    "\n\n[[TRUNCATED]]"));
11937                    } catch (IOException e) {
11938                        Slog.e(TAG, "Error reading " + logFile, e);
11939                    }
11940                }
11941                if (crashInfo != null && crashInfo.stackTrace != null) {
11942                    sb.append(crashInfo.stackTrace);
11943                }
11944
11945                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11946                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11947                if (lines > 0) {
11948                    sb.append("\n");
11949
11950                    // Merge several logcat streams, and take the last N lines
11951                    InputStreamReader input = null;
11952                    try {
11953                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11954                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11955                                "-b", "crash",
11956                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11957
11958                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11959                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11960                        input = new InputStreamReader(logcat.getInputStream());
11961
11962                        int num;
11963                        char[] buf = new char[8192];
11964                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11965                    } catch (IOException e) {
11966                        Slog.e(TAG, "Error running logcat", e);
11967                    } finally {
11968                        if (input != null) try { input.close(); } catch (IOException e) {}
11969                    }
11970                }
11971
11972                dbox.addText(dropboxTag, sb.toString());
11973            }
11974        };
11975
11976        if (process == null) {
11977            // If process is null, we are being called from some internal code
11978            // and may be about to die -- run this synchronously.
11979            worker.run();
11980        } else {
11981            worker.start();
11982        }
11983    }
11984
11985    /**
11986     * Bring up the "unexpected error" dialog box for a crashing app.
11987     * Deal with edge cases (intercepts from instrumented applications,
11988     * ActivityController, error intent receivers, that sort of thing).
11989     * @param r the application crashing
11990     * @param crashInfo describing the failure
11991     */
11992    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11993        long timeMillis = System.currentTimeMillis();
11994        String shortMsg = crashInfo.exceptionClassName;
11995        String longMsg = crashInfo.exceptionMessage;
11996        String stackTrace = crashInfo.stackTrace;
11997        if (shortMsg != null && longMsg != null) {
11998            longMsg = shortMsg + ": " + longMsg;
11999        } else if (shortMsg != null) {
12000            longMsg = shortMsg;
12001        }
12002
12003        AppErrorResult result = new AppErrorResult();
12004        synchronized (this) {
12005            if (mController != null) {
12006                try {
12007                    String name = r != null ? r.processName : null;
12008                    int pid = r != null ? r.pid : Binder.getCallingPid();
12009                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12010                    if (!mController.appCrashed(name, pid,
12011                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12012                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12013                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12014                            Slog.w(TAG, "Skip killing native crashed app " + name
12015                                    + "(" + pid + ") during testing");
12016                        } else {
12017                            Slog.w(TAG, "Force-killing crashed app " + name
12018                                    + " at watcher's request");
12019                            if (r != null) {
12020                                r.kill("crash", true);
12021                            } else {
12022                                // Huh.
12023                                Process.killProcess(pid);
12024                                Process.killProcessGroup(uid, pid);
12025                            }
12026                        }
12027                        return;
12028                    }
12029                } catch (RemoteException e) {
12030                    mController = null;
12031                    Watchdog.getInstance().setActivityController(null);
12032                }
12033            }
12034
12035            final long origId = Binder.clearCallingIdentity();
12036
12037            // If this process is running instrumentation, finish it.
12038            if (r != null && r.instrumentationClass != null) {
12039                Slog.w(TAG, "Error in app " + r.processName
12040                      + " running instrumentation " + r.instrumentationClass + ":");
12041                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12042                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12043                Bundle info = new Bundle();
12044                info.putString("shortMsg", shortMsg);
12045                info.putString("longMsg", longMsg);
12046                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12047                Binder.restoreCallingIdentity(origId);
12048                return;
12049            }
12050
12051            // Log crash in battery stats.
12052            if (r != null) {
12053                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12054            }
12055
12056            // If we can't identify the process or it's already exceeded its crash quota,
12057            // quit right away without showing a crash dialog.
12058            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12059                Binder.restoreCallingIdentity(origId);
12060                return;
12061            }
12062
12063            Message msg = Message.obtain();
12064            msg.what = SHOW_ERROR_MSG;
12065            HashMap data = new HashMap();
12066            data.put("result", result);
12067            data.put("app", r);
12068            msg.obj = data;
12069            mHandler.sendMessage(msg);
12070
12071            Binder.restoreCallingIdentity(origId);
12072        }
12073
12074        int res = result.get();
12075
12076        Intent appErrorIntent = null;
12077        synchronized (this) {
12078            if (r != null && !r.isolated) {
12079                // XXX Can't keep track of crash time for isolated processes,
12080                // since they don't have a persistent identity.
12081                mProcessCrashTimes.put(r.info.processName, r.uid,
12082                        SystemClock.uptimeMillis());
12083            }
12084            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12085                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12086            }
12087        }
12088
12089        if (appErrorIntent != null) {
12090            try {
12091                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12092            } catch (ActivityNotFoundException e) {
12093                Slog.w(TAG, "bug report receiver dissappeared", e);
12094            }
12095        }
12096    }
12097
12098    Intent createAppErrorIntentLocked(ProcessRecord r,
12099            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12100        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12101        if (report == null) {
12102            return null;
12103        }
12104        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12105        result.setComponent(r.errorReportReceiver);
12106        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12107        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12108        return result;
12109    }
12110
12111    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12112            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12113        if (r.errorReportReceiver == null) {
12114            return null;
12115        }
12116
12117        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12118            return null;
12119        }
12120
12121        ApplicationErrorReport report = new ApplicationErrorReport();
12122        report.packageName = r.info.packageName;
12123        report.installerPackageName = r.errorReportReceiver.getPackageName();
12124        report.processName = r.processName;
12125        report.time = timeMillis;
12126        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12127
12128        if (r.crashing || r.forceCrashReport) {
12129            report.type = ApplicationErrorReport.TYPE_CRASH;
12130            report.crashInfo = crashInfo;
12131        } else if (r.notResponding) {
12132            report.type = ApplicationErrorReport.TYPE_ANR;
12133            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12134
12135            report.anrInfo.activity = r.notRespondingReport.tag;
12136            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12137            report.anrInfo.info = r.notRespondingReport.longMsg;
12138        }
12139
12140        return report;
12141    }
12142
12143    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12144        enforceNotIsolatedCaller("getProcessesInErrorState");
12145        // assume our apps are happy - lazy create the list
12146        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12147
12148        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12149                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12150        int userId = UserHandle.getUserId(Binder.getCallingUid());
12151
12152        synchronized (this) {
12153
12154            // iterate across all processes
12155            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12156                ProcessRecord app = mLruProcesses.get(i);
12157                if (!allUsers && app.userId != userId) {
12158                    continue;
12159                }
12160                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12161                    // This one's in trouble, so we'll generate a report for it
12162                    // crashes are higher priority (in case there's a crash *and* an anr)
12163                    ActivityManager.ProcessErrorStateInfo report = null;
12164                    if (app.crashing) {
12165                        report = app.crashingReport;
12166                    } else if (app.notResponding) {
12167                        report = app.notRespondingReport;
12168                    }
12169
12170                    if (report != null) {
12171                        if (errList == null) {
12172                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12173                        }
12174                        errList.add(report);
12175                    } else {
12176                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12177                                " crashing = " + app.crashing +
12178                                " notResponding = " + app.notResponding);
12179                    }
12180                }
12181            }
12182        }
12183
12184        return errList;
12185    }
12186
12187    static int procStateToImportance(int procState, int memAdj,
12188            ActivityManager.RunningAppProcessInfo currApp) {
12189        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12190        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12191            currApp.lru = memAdj;
12192        } else {
12193            currApp.lru = 0;
12194        }
12195        return imp;
12196    }
12197
12198    private void fillInProcMemInfo(ProcessRecord app,
12199            ActivityManager.RunningAppProcessInfo outInfo) {
12200        outInfo.pid = app.pid;
12201        outInfo.uid = app.info.uid;
12202        if (mHeavyWeightProcess == app) {
12203            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12204        }
12205        if (app.persistent) {
12206            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12207        }
12208        if (app.activities.size() > 0) {
12209            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12210        }
12211        outInfo.lastTrimLevel = app.trimMemoryLevel;
12212        int adj = app.curAdj;
12213        int procState = app.curProcState;
12214        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12215        outInfo.importanceReasonCode = app.adjTypeCode;
12216        outInfo.processState = app.curProcState;
12217    }
12218
12219    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12220        enforceNotIsolatedCaller("getRunningAppProcesses");
12221        // Lazy instantiation of list
12222        List<ActivityManager.RunningAppProcessInfo> runList = null;
12223        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12224                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12225        int userId = UserHandle.getUserId(Binder.getCallingUid());
12226        synchronized (this) {
12227            // Iterate across all processes
12228            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12229                ProcessRecord app = mLruProcesses.get(i);
12230                if (!allUsers && app.userId != userId) {
12231                    continue;
12232                }
12233                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12234                    // Generate process state info for running application
12235                    ActivityManager.RunningAppProcessInfo currApp =
12236                        new ActivityManager.RunningAppProcessInfo(app.processName,
12237                                app.pid, app.getPackageList());
12238                    fillInProcMemInfo(app, currApp);
12239                    if (app.adjSource instanceof ProcessRecord) {
12240                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12241                        currApp.importanceReasonImportance =
12242                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12243                                        app.adjSourceProcState);
12244                    } else if (app.adjSource instanceof ActivityRecord) {
12245                        ActivityRecord r = (ActivityRecord)app.adjSource;
12246                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12247                    }
12248                    if (app.adjTarget instanceof ComponentName) {
12249                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12250                    }
12251                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12252                    //        + " lru=" + currApp.lru);
12253                    if (runList == null) {
12254                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12255                    }
12256                    runList.add(currApp);
12257                }
12258            }
12259        }
12260        return runList;
12261    }
12262
12263    public List<ApplicationInfo> getRunningExternalApplications() {
12264        enforceNotIsolatedCaller("getRunningExternalApplications");
12265        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12266        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12267        if (runningApps != null && runningApps.size() > 0) {
12268            Set<String> extList = new HashSet<String>();
12269            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12270                if (app.pkgList != null) {
12271                    for (String pkg : app.pkgList) {
12272                        extList.add(pkg);
12273                    }
12274                }
12275            }
12276            IPackageManager pm = AppGlobals.getPackageManager();
12277            for (String pkg : extList) {
12278                try {
12279                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12280                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12281                        retList.add(info);
12282                    }
12283                } catch (RemoteException e) {
12284                }
12285            }
12286        }
12287        return retList;
12288    }
12289
12290    @Override
12291    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12292        enforceNotIsolatedCaller("getMyMemoryState");
12293        synchronized (this) {
12294            ProcessRecord proc;
12295            synchronized (mPidsSelfLocked) {
12296                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12297            }
12298            fillInProcMemInfo(proc, outInfo);
12299        }
12300    }
12301
12302    @Override
12303    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12304        if (checkCallingPermission(android.Manifest.permission.DUMP)
12305                != PackageManager.PERMISSION_GRANTED) {
12306            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12307                    + Binder.getCallingPid()
12308                    + ", uid=" + Binder.getCallingUid()
12309                    + " without permission "
12310                    + android.Manifest.permission.DUMP);
12311            return;
12312        }
12313
12314        boolean dumpAll = false;
12315        boolean dumpClient = false;
12316        String dumpPackage = null;
12317
12318        int opti = 0;
12319        while (opti < args.length) {
12320            String opt = args[opti];
12321            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12322                break;
12323            }
12324            opti++;
12325            if ("-a".equals(opt)) {
12326                dumpAll = true;
12327            } else if ("-c".equals(opt)) {
12328                dumpClient = true;
12329            } else if ("-h".equals(opt)) {
12330                pw.println("Activity manager dump options:");
12331                pw.println("  [-a] [-c] [-h] [cmd] ...");
12332                pw.println("  cmd may be one of:");
12333                pw.println("    a[ctivities]: activity stack state");
12334                pw.println("    r[recents]: recent activities state");
12335                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12336                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12337                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12338                pw.println("    o[om]: out of memory management");
12339                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12340                pw.println("    provider [COMP_SPEC]: provider client-side state");
12341                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12342                pw.println("    service [COMP_SPEC]: service client-side state");
12343                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12344                pw.println("    all: dump all activities");
12345                pw.println("    top: dump the top activity");
12346                pw.println("    write: write all pending state to storage");
12347                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12348                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12349                pw.println("    a partial substring in a component name, a");
12350                pw.println("    hex object identifier.");
12351                pw.println("  -a: include all available server state.");
12352                pw.println("  -c: include client state.");
12353                return;
12354            } else {
12355                pw.println("Unknown argument: " + opt + "; use -h for help");
12356            }
12357        }
12358
12359        long origId = Binder.clearCallingIdentity();
12360        boolean more = false;
12361        // Is the caller requesting to dump a particular piece of data?
12362        if (opti < args.length) {
12363            String cmd = args[opti];
12364            opti++;
12365            if ("activities".equals(cmd) || "a".equals(cmd)) {
12366                synchronized (this) {
12367                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12368                }
12369            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12370                synchronized (this) {
12371                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12372                }
12373            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12374                String[] newArgs;
12375                String name;
12376                if (opti >= args.length) {
12377                    name = null;
12378                    newArgs = EMPTY_STRING_ARRAY;
12379                } else {
12380                    name = args[opti];
12381                    opti++;
12382                    newArgs = new String[args.length - opti];
12383                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12384                            args.length - opti);
12385                }
12386                synchronized (this) {
12387                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12388                }
12389            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12390                String[] newArgs;
12391                String name;
12392                if (opti >= args.length) {
12393                    name = null;
12394                    newArgs = EMPTY_STRING_ARRAY;
12395                } else {
12396                    name = args[opti];
12397                    opti++;
12398                    newArgs = new String[args.length - opti];
12399                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12400                            args.length - opti);
12401                }
12402                synchronized (this) {
12403                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12404                }
12405            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12406                String[] newArgs;
12407                String name;
12408                if (opti >= args.length) {
12409                    name = null;
12410                    newArgs = EMPTY_STRING_ARRAY;
12411                } else {
12412                    name = args[opti];
12413                    opti++;
12414                    newArgs = new String[args.length - opti];
12415                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12416                            args.length - opti);
12417                }
12418                synchronized (this) {
12419                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12420                }
12421            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12422                synchronized (this) {
12423                    dumpOomLocked(fd, pw, args, opti, true);
12424                }
12425            } else if ("provider".equals(cmd)) {
12426                String[] newArgs;
12427                String name;
12428                if (opti >= args.length) {
12429                    name = null;
12430                    newArgs = EMPTY_STRING_ARRAY;
12431                } else {
12432                    name = args[opti];
12433                    opti++;
12434                    newArgs = new String[args.length - opti];
12435                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12436                }
12437                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12438                    pw.println("No providers match: " + name);
12439                    pw.println("Use -h for help.");
12440                }
12441            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12442                synchronized (this) {
12443                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12444                }
12445            } else if ("service".equals(cmd)) {
12446                String[] newArgs;
12447                String name;
12448                if (opti >= args.length) {
12449                    name = null;
12450                    newArgs = EMPTY_STRING_ARRAY;
12451                } else {
12452                    name = args[opti];
12453                    opti++;
12454                    newArgs = new String[args.length - opti];
12455                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12456                            args.length - opti);
12457                }
12458                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12459                    pw.println("No services match: " + name);
12460                    pw.println("Use -h for help.");
12461                }
12462            } else if ("package".equals(cmd)) {
12463                String[] newArgs;
12464                if (opti >= args.length) {
12465                    pw.println("package: no package name specified");
12466                    pw.println("Use -h for help.");
12467                } else {
12468                    dumpPackage = args[opti];
12469                    opti++;
12470                    newArgs = new String[args.length - opti];
12471                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12472                            args.length - opti);
12473                    args = newArgs;
12474                    opti = 0;
12475                    more = true;
12476                }
12477            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12478                synchronized (this) {
12479                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12480                }
12481            } else if ("write".equals(cmd)) {
12482                mTaskPersister.flush();
12483                pw.println("All tasks persisted.");
12484                return;
12485            } else {
12486                // Dumping a single activity?
12487                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12488                    pw.println("Bad activity command, or no activities match: " + cmd);
12489                    pw.println("Use -h for help.");
12490                }
12491            }
12492            if (!more) {
12493                Binder.restoreCallingIdentity(origId);
12494                return;
12495            }
12496        }
12497
12498        // No piece of data specified, dump everything.
12499        synchronized (this) {
12500            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12501            pw.println();
12502            if (dumpAll) {
12503                pw.println("-------------------------------------------------------------------------------");
12504            }
12505            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12506            pw.println();
12507            if (dumpAll) {
12508                pw.println("-------------------------------------------------------------------------------");
12509            }
12510            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12511            pw.println();
12512            if (dumpAll) {
12513                pw.println("-------------------------------------------------------------------------------");
12514            }
12515            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12516            pw.println();
12517            if (dumpAll) {
12518                pw.println("-------------------------------------------------------------------------------");
12519            }
12520            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12521            pw.println();
12522            if (dumpAll) {
12523                pw.println("-------------------------------------------------------------------------------");
12524            }
12525            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12526            pw.println();
12527            if (dumpAll) {
12528                pw.println("-------------------------------------------------------------------------------");
12529            }
12530            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12531        }
12532        Binder.restoreCallingIdentity(origId);
12533    }
12534
12535    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12536            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12537        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12538
12539        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12540                dumpPackage);
12541        boolean needSep = printedAnything;
12542
12543        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12544                dumpPackage, needSep, "  mFocusedActivity: ");
12545        if (printed) {
12546            printedAnything = true;
12547            needSep = false;
12548        }
12549
12550        if (dumpPackage == null) {
12551            if (needSep) {
12552                pw.println();
12553            }
12554            needSep = true;
12555            printedAnything = true;
12556            mStackSupervisor.dump(pw, "  ");
12557        }
12558
12559        if (!printedAnything) {
12560            pw.println("  (nothing)");
12561        }
12562    }
12563
12564    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12565            int opti, boolean dumpAll, String dumpPackage) {
12566        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12567
12568        boolean printedAnything = false;
12569
12570        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12571            boolean printedHeader = false;
12572
12573            final int N = mRecentTasks.size();
12574            for (int i=0; i<N; i++) {
12575                TaskRecord tr = mRecentTasks.get(i);
12576                if (dumpPackage != null) {
12577                    if (tr.realActivity == null ||
12578                            !dumpPackage.equals(tr.realActivity)) {
12579                        continue;
12580                    }
12581                }
12582                if (!printedHeader) {
12583                    pw.println("  Recent tasks:");
12584                    printedHeader = true;
12585                    printedAnything = true;
12586                }
12587                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12588                        pw.println(tr);
12589                if (dumpAll) {
12590                    mRecentTasks.get(i).dump(pw, "    ");
12591                }
12592            }
12593        }
12594
12595        if (!printedAnything) {
12596            pw.println("  (nothing)");
12597        }
12598    }
12599
12600    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12601            int opti, boolean dumpAll, String dumpPackage) {
12602        boolean needSep = false;
12603        boolean printedAnything = false;
12604        int numPers = 0;
12605
12606        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12607
12608        if (dumpAll) {
12609            final int NP = mProcessNames.getMap().size();
12610            for (int ip=0; ip<NP; ip++) {
12611                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12612                final int NA = procs.size();
12613                for (int ia=0; ia<NA; ia++) {
12614                    ProcessRecord r = procs.valueAt(ia);
12615                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12616                        continue;
12617                    }
12618                    if (!needSep) {
12619                        pw.println("  All known processes:");
12620                        needSep = true;
12621                        printedAnything = true;
12622                    }
12623                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12624                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12625                        pw.print(" "); pw.println(r);
12626                    r.dump(pw, "    ");
12627                    if (r.persistent) {
12628                        numPers++;
12629                    }
12630                }
12631            }
12632        }
12633
12634        if (mIsolatedProcesses.size() > 0) {
12635            boolean printed = false;
12636            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12637                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12638                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12639                    continue;
12640                }
12641                if (!printed) {
12642                    if (needSep) {
12643                        pw.println();
12644                    }
12645                    pw.println("  Isolated process list (sorted by uid):");
12646                    printedAnything = true;
12647                    printed = true;
12648                    needSep = true;
12649                }
12650                pw.println(String.format("%sIsolated #%2d: %s",
12651                        "    ", i, r.toString()));
12652            }
12653        }
12654
12655        if (mLruProcesses.size() > 0) {
12656            if (needSep) {
12657                pw.println();
12658            }
12659            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12660                    pw.print(" total, non-act at ");
12661                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12662                    pw.print(", non-svc at ");
12663                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12664                    pw.println("):");
12665            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12666            needSep = true;
12667            printedAnything = true;
12668        }
12669
12670        if (dumpAll || dumpPackage != null) {
12671            synchronized (mPidsSelfLocked) {
12672                boolean printed = false;
12673                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12674                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12675                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12676                        continue;
12677                    }
12678                    if (!printed) {
12679                        if (needSep) pw.println();
12680                        needSep = true;
12681                        pw.println("  PID mappings:");
12682                        printed = true;
12683                        printedAnything = true;
12684                    }
12685                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12686                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12687                }
12688            }
12689        }
12690
12691        if (mForegroundProcesses.size() > 0) {
12692            synchronized (mPidsSelfLocked) {
12693                boolean printed = false;
12694                for (int i=0; i<mForegroundProcesses.size(); i++) {
12695                    ProcessRecord r = mPidsSelfLocked.get(
12696                            mForegroundProcesses.valueAt(i).pid);
12697                    if (dumpPackage != null && (r == null
12698                            || !r.pkgList.containsKey(dumpPackage))) {
12699                        continue;
12700                    }
12701                    if (!printed) {
12702                        if (needSep) pw.println();
12703                        needSep = true;
12704                        pw.println("  Foreground Processes:");
12705                        printed = true;
12706                        printedAnything = true;
12707                    }
12708                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12709                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12710                }
12711            }
12712        }
12713
12714        if (mPersistentStartingProcesses.size() > 0) {
12715            if (needSep) pw.println();
12716            needSep = true;
12717            printedAnything = true;
12718            pw.println("  Persisent processes that are starting:");
12719            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12720                    "Starting Norm", "Restarting PERS", dumpPackage);
12721        }
12722
12723        if (mRemovedProcesses.size() > 0) {
12724            if (needSep) pw.println();
12725            needSep = true;
12726            printedAnything = true;
12727            pw.println("  Processes that are being removed:");
12728            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12729                    "Removed Norm", "Removed PERS", dumpPackage);
12730        }
12731
12732        if (mProcessesOnHold.size() > 0) {
12733            if (needSep) pw.println();
12734            needSep = true;
12735            printedAnything = true;
12736            pw.println("  Processes that are on old until the system is ready:");
12737            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12738                    "OnHold Norm", "OnHold PERS", dumpPackage);
12739        }
12740
12741        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12742
12743        if (mProcessCrashTimes.getMap().size() > 0) {
12744            boolean printed = false;
12745            long now = SystemClock.uptimeMillis();
12746            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12747            final int NP = pmap.size();
12748            for (int ip=0; ip<NP; ip++) {
12749                String pname = pmap.keyAt(ip);
12750                SparseArray<Long> uids = pmap.valueAt(ip);
12751                final int N = uids.size();
12752                for (int i=0; i<N; i++) {
12753                    int puid = uids.keyAt(i);
12754                    ProcessRecord r = mProcessNames.get(pname, puid);
12755                    if (dumpPackage != null && (r == null
12756                            || !r.pkgList.containsKey(dumpPackage))) {
12757                        continue;
12758                    }
12759                    if (!printed) {
12760                        if (needSep) pw.println();
12761                        needSep = true;
12762                        pw.println("  Time since processes crashed:");
12763                        printed = true;
12764                        printedAnything = true;
12765                    }
12766                    pw.print("    Process "); pw.print(pname);
12767                            pw.print(" uid "); pw.print(puid);
12768                            pw.print(": last crashed ");
12769                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12770                            pw.println(" ago");
12771                }
12772            }
12773        }
12774
12775        if (mBadProcesses.getMap().size() > 0) {
12776            boolean printed = false;
12777            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12778            final int NP = pmap.size();
12779            for (int ip=0; ip<NP; ip++) {
12780                String pname = pmap.keyAt(ip);
12781                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12782                final int N = uids.size();
12783                for (int i=0; i<N; i++) {
12784                    int puid = uids.keyAt(i);
12785                    ProcessRecord r = mProcessNames.get(pname, puid);
12786                    if (dumpPackage != null && (r == null
12787                            || !r.pkgList.containsKey(dumpPackage))) {
12788                        continue;
12789                    }
12790                    if (!printed) {
12791                        if (needSep) pw.println();
12792                        needSep = true;
12793                        pw.println("  Bad processes:");
12794                        printedAnything = true;
12795                    }
12796                    BadProcessInfo info = uids.valueAt(i);
12797                    pw.print("    Bad process "); pw.print(pname);
12798                            pw.print(" uid "); pw.print(puid);
12799                            pw.print(": crashed at time "); pw.println(info.time);
12800                    if (info.shortMsg != null) {
12801                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12802                    }
12803                    if (info.longMsg != null) {
12804                        pw.print("      Long msg: "); pw.println(info.longMsg);
12805                    }
12806                    if (info.stack != null) {
12807                        pw.println("      Stack:");
12808                        int lastPos = 0;
12809                        for (int pos=0; pos<info.stack.length(); pos++) {
12810                            if (info.stack.charAt(pos) == '\n') {
12811                                pw.print("        ");
12812                                pw.write(info.stack, lastPos, pos-lastPos);
12813                                pw.println();
12814                                lastPos = pos+1;
12815                            }
12816                        }
12817                        if (lastPos < info.stack.length()) {
12818                            pw.print("        ");
12819                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12820                            pw.println();
12821                        }
12822                    }
12823                }
12824            }
12825        }
12826
12827        if (dumpPackage == null) {
12828            pw.println();
12829            needSep = false;
12830            pw.println("  mStartedUsers:");
12831            for (int i=0; i<mStartedUsers.size(); i++) {
12832                UserStartedState uss = mStartedUsers.valueAt(i);
12833                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12834                        pw.print(": "); uss.dump("", pw);
12835            }
12836            pw.print("  mStartedUserArray: [");
12837            for (int i=0; i<mStartedUserArray.length; i++) {
12838                if (i > 0) pw.print(", ");
12839                pw.print(mStartedUserArray[i]);
12840            }
12841            pw.println("]");
12842            pw.print("  mUserLru: [");
12843            for (int i=0; i<mUserLru.size(); i++) {
12844                if (i > 0) pw.print(", ");
12845                pw.print(mUserLru.get(i));
12846            }
12847            pw.println("]");
12848            if (dumpAll) {
12849                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12850            }
12851            synchronized (mUserProfileGroupIdsSelfLocked) {
12852                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12853                    pw.println("  mUserProfileGroupIds:");
12854                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12855                        pw.print("    User #");
12856                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12857                        pw.print(" -> profile #");
12858                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12859                    }
12860                }
12861            }
12862        }
12863        if (mHomeProcess != null && (dumpPackage == null
12864                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12865            if (needSep) {
12866                pw.println();
12867                needSep = false;
12868            }
12869            pw.println("  mHomeProcess: " + mHomeProcess);
12870        }
12871        if (mPreviousProcess != null && (dumpPackage == null
12872                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12873            if (needSep) {
12874                pw.println();
12875                needSep = false;
12876            }
12877            pw.println("  mPreviousProcess: " + mPreviousProcess);
12878        }
12879        if (dumpAll) {
12880            StringBuilder sb = new StringBuilder(128);
12881            sb.append("  mPreviousProcessVisibleTime: ");
12882            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12883            pw.println(sb);
12884        }
12885        if (mHeavyWeightProcess != null && (dumpPackage == null
12886                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12887            if (needSep) {
12888                pw.println();
12889                needSep = false;
12890            }
12891            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12892        }
12893        if (dumpPackage == null) {
12894            pw.println("  mConfiguration: " + mConfiguration);
12895        }
12896        if (dumpAll) {
12897            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12898            if (mCompatModePackages.getPackages().size() > 0) {
12899                boolean printed = false;
12900                for (Map.Entry<String, Integer> entry
12901                        : mCompatModePackages.getPackages().entrySet()) {
12902                    String pkg = entry.getKey();
12903                    int mode = entry.getValue();
12904                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12905                        continue;
12906                    }
12907                    if (!printed) {
12908                        pw.println("  mScreenCompatPackages:");
12909                        printed = true;
12910                    }
12911                    pw.print("    "); pw.print(pkg); pw.print(": ");
12912                            pw.print(mode); pw.println();
12913                }
12914            }
12915        }
12916        if (dumpPackage == null) {
12917            pw.println("  mWakefulness="
12918                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12919            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12920                    + lockScreenShownToString());
12921            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12922                    + " mTestPssMode=" + mTestPssMode);
12923        }
12924        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12925                || mOrigWaitForDebugger) {
12926            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12927                    || dumpPackage.equals(mOrigDebugApp)) {
12928                if (needSep) {
12929                    pw.println();
12930                    needSep = false;
12931                }
12932                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12933                        + " mDebugTransient=" + mDebugTransient
12934                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12935            }
12936        }
12937        if (mOpenGlTraceApp != null) {
12938            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12939                if (needSep) {
12940                    pw.println();
12941                    needSep = false;
12942                }
12943                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12944            }
12945        }
12946        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12947                || mProfileFd != null) {
12948            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12949                if (needSep) {
12950                    pw.println();
12951                    needSep = false;
12952                }
12953                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12954                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12955                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12956                        + mAutoStopProfiler);
12957                pw.println("  mProfileType=" + mProfileType);
12958            }
12959        }
12960        if (dumpPackage == null) {
12961            if (mAlwaysFinishActivities || mController != null) {
12962                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12963                        + " mController=" + mController);
12964            }
12965            if (dumpAll) {
12966                pw.println("  Total persistent processes: " + numPers);
12967                pw.println("  mProcessesReady=" + mProcessesReady
12968                        + " mSystemReady=" + mSystemReady
12969                        + " mBooted=" + mBooted
12970                        + " mFactoryTest=" + mFactoryTest);
12971                pw.println("  mBooting=" + mBooting
12972                        + " mCallFinishBooting=" + mCallFinishBooting
12973                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12974                pw.print("  mLastPowerCheckRealtime=");
12975                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12976                        pw.println("");
12977                pw.print("  mLastPowerCheckUptime=");
12978                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12979                        pw.println("");
12980                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12981                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12982                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12983                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12984                        + " (" + mLruProcesses.size() + " total)"
12985                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12986                        + " mNumServiceProcs=" + mNumServiceProcs
12987                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12988                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12989                        + " mLastMemoryLevel" + mLastMemoryLevel
12990                        + " mLastNumProcesses" + mLastNumProcesses);
12991                long now = SystemClock.uptimeMillis();
12992                pw.print("  mLastIdleTime=");
12993                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12994                        pw.print(" mLowRamSinceLastIdle=");
12995                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12996                        pw.println();
12997            }
12998        }
12999
13000        if (!printedAnything) {
13001            pw.println("  (nothing)");
13002        }
13003    }
13004
13005    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13006            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13007        if (mProcessesToGc.size() > 0) {
13008            boolean printed = false;
13009            long now = SystemClock.uptimeMillis();
13010            for (int i=0; i<mProcessesToGc.size(); i++) {
13011                ProcessRecord proc = mProcessesToGc.get(i);
13012                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13013                    continue;
13014                }
13015                if (!printed) {
13016                    if (needSep) pw.println();
13017                    needSep = true;
13018                    pw.println("  Processes that are waiting to GC:");
13019                    printed = true;
13020                }
13021                pw.print("    Process "); pw.println(proc);
13022                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13023                        pw.print(", last gced=");
13024                        pw.print(now-proc.lastRequestedGc);
13025                        pw.print(" ms ago, last lowMem=");
13026                        pw.print(now-proc.lastLowMemory);
13027                        pw.println(" ms ago");
13028
13029            }
13030        }
13031        return needSep;
13032    }
13033
13034    void printOomLevel(PrintWriter pw, String name, int adj) {
13035        pw.print("    ");
13036        if (adj >= 0) {
13037            pw.print(' ');
13038            if (adj < 10) pw.print(' ');
13039        } else {
13040            if (adj > -10) pw.print(' ');
13041        }
13042        pw.print(adj);
13043        pw.print(": ");
13044        pw.print(name);
13045        pw.print(" (");
13046        pw.print(mProcessList.getMemLevel(adj)/1024);
13047        pw.println(" kB)");
13048    }
13049
13050    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13051            int opti, boolean dumpAll) {
13052        boolean needSep = false;
13053
13054        if (mLruProcesses.size() > 0) {
13055            if (needSep) pw.println();
13056            needSep = true;
13057            pw.println("  OOM levels:");
13058            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13059            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13060            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13061            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13062            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13063            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13064            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13065            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13066            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13067            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13068            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13069            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13070            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13071            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13072
13073            if (needSep) pw.println();
13074            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13075                    pw.print(" total, non-act at ");
13076                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13077                    pw.print(", non-svc at ");
13078                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13079                    pw.println("):");
13080            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13081            needSep = true;
13082        }
13083
13084        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13085
13086        pw.println();
13087        pw.println("  mHomeProcess: " + mHomeProcess);
13088        pw.println("  mPreviousProcess: " + mPreviousProcess);
13089        if (mHeavyWeightProcess != null) {
13090            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13091        }
13092
13093        return true;
13094    }
13095
13096    /**
13097     * There are three ways to call this:
13098     *  - no provider specified: dump all the providers
13099     *  - a flattened component name that matched an existing provider was specified as the
13100     *    first arg: dump that one provider
13101     *  - the first arg isn't the flattened component name of an existing provider:
13102     *    dump all providers whose component contains the first arg as a substring
13103     */
13104    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13105            int opti, boolean dumpAll) {
13106        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13107    }
13108
13109    static class ItemMatcher {
13110        ArrayList<ComponentName> components;
13111        ArrayList<String> strings;
13112        ArrayList<Integer> objects;
13113        boolean all;
13114
13115        ItemMatcher() {
13116            all = true;
13117        }
13118
13119        void build(String name) {
13120            ComponentName componentName = ComponentName.unflattenFromString(name);
13121            if (componentName != null) {
13122                if (components == null) {
13123                    components = new ArrayList<ComponentName>();
13124                }
13125                components.add(componentName);
13126                all = false;
13127            } else {
13128                int objectId = 0;
13129                // Not a '/' separated full component name; maybe an object ID?
13130                try {
13131                    objectId = Integer.parseInt(name, 16);
13132                    if (objects == null) {
13133                        objects = new ArrayList<Integer>();
13134                    }
13135                    objects.add(objectId);
13136                    all = false;
13137                } catch (RuntimeException e) {
13138                    // Not an integer; just do string match.
13139                    if (strings == null) {
13140                        strings = new ArrayList<String>();
13141                    }
13142                    strings.add(name);
13143                    all = false;
13144                }
13145            }
13146        }
13147
13148        int build(String[] args, int opti) {
13149            for (; opti<args.length; opti++) {
13150                String name = args[opti];
13151                if ("--".equals(name)) {
13152                    return opti+1;
13153                }
13154                build(name);
13155            }
13156            return opti;
13157        }
13158
13159        boolean match(Object object, ComponentName comp) {
13160            if (all) {
13161                return true;
13162            }
13163            if (components != null) {
13164                for (int i=0; i<components.size(); i++) {
13165                    if (components.get(i).equals(comp)) {
13166                        return true;
13167                    }
13168                }
13169            }
13170            if (objects != null) {
13171                for (int i=0; i<objects.size(); i++) {
13172                    if (System.identityHashCode(object) == objects.get(i)) {
13173                        return true;
13174                    }
13175                }
13176            }
13177            if (strings != null) {
13178                String flat = comp.flattenToString();
13179                for (int i=0; i<strings.size(); i++) {
13180                    if (flat.contains(strings.get(i))) {
13181                        return true;
13182                    }
13183                }
13184            }
13185            return false;
13186        }
13187    }
13188
13189    /**
13190     * There are three things that cmd can be:
13191     *  - a flattened component name that matches an existing activity
13192     *  - the cmd arg isn't the flattened component name of an existing activity:
13193     *    dump all activity whose component contains the cmd as a substring
13194     *  - A hex number of the ActivityRecord object instance.
13195     */
13196    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13197            int opti, boolean dumpAll) {
13198        ArrayList<ActivityRecord> activities;
13199
13200        synchronized (this) {
13201            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13202        }
13203
13204        if (activities.size() <= 0) {
13205            return false;
13206        }
13207
13208        String[] newArgs = new String[args.length - opti];
13209        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13210
13211        TaskRecord lastTask = null;
13212        boolean needSep = false;
13213        for (int i=activities.size()-1; i>=0; i--) {
13214            ActivityRecord r = activities.get(i);
13215            if (needSep) {
13216                pw.println();
13217            }
13218            needSep = true;
13219            synchronized (this) {
13220                if (lastTask != r.task) {
13221                    lastTask = r.task;
13222                    pw.print("TASK "); pw.print(lastTask.affinity);
13223                            pw.print(" id="); pw.println(lastTask.taskId);
13224                    if (dumpAll) {
13225                        lastTask.dump(pw, "  ");
13226                    }
13227                }
13228            }
13229            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13230        }
13231        return true;
13232    }
13233
13234    /**
13235     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13236     * there is a thread associated with the activity.
13237     */
13238    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13239            final ActivityRecord r, String[] args, boolean dumpAll) {
13240        String innerPrefix = prefix + "  ";
13241        synchronized (this) {
13242            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13243                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13244                    pw.print(" pid=");
13245                    if (r.app != null) pw.println(r.app.pid);
13246                    else pw.println("(not running)");
13247            if (dumpAll) {
13248                r.dump(pw, innerPrefix);
13249            }
13250        }
13251        if (r.app != null && r.app.thread != null) {
13252            // flush anything that is already in the PrintWriter since the thread is going
13253            // to write to the file descriptor directly
13254            pw.flush();
13255            try {
13256                TransferPipe tp = new TransferPipe();
13257                try {
13258                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13259                            r.appToken, innerPrefix, args);
13260                    tp.go(fd);
13261                } finally {
13262                    tp.kill();
13263                }
13264            } catch (IOException e) {
13265                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13266            } catch (RemoteException e) {
13267                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13268            }
13269        }
13270    }
13271
13272    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13273            int opti, boolean dumpAll, String dumpPackage) {
13274        boolean needSep = false;
13275        boolean onlyHistory = false;
13276        boolean printedAnything = false;
13277
13278        if ("history".equals(dumpPackage)) {
13279            if (opti < args.length && "-s".equals(args[opti])) {
13280                dumpAll = false;
13281            }
13282            onlyHistory = true;
13283            dumpPackage = null;
13284        }
13285
13286        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13287        if (!onlyHistory && dumpAll) {
13288            if (mRegisteredReceivers.size() > 0) {
13289                boolean printed = false;
13290                Iterator it = mRegisteredReceivers.values().iterator();
13291                while (it.hasNext()) {
13292                    ReceiverList r = (ReceiverList)it.next();
13293                    if (dumpPackage != null && (r.app == null ||
13294                            !dumpPackage.equals(r.app.info.packageName))) {
13295                        continue;
13296                    }
13297                    if (!printed) {
13298                        pw.println("  Registered Receivers:");
13299                        needSep = true;
13300                        printed = true;
13301                        printedAnything = true;
13302                    }
13303                    pw.print("  * "); pw.println(r);
13304                    r.dump(pw, "    ");
13305                }
13306            }
13307
13308            if (mReceiverResolver.dump(pw, needSep ?
13309                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13310                    "    ", dumpPackage, false, false)) {
13311                needSep = true;
13312                printedAnything = true;
13313            }
13314        }
13315
13316        for (BroadcastQueue q : mBroadcastQueues) {
13317            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13318            printedAnything |= needSep;
13319        }
13320
13321        needSep = true;
13322
13323        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13324            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13325                if (needSep) {
13326                    pw.println();
13327                }
13328                needSep = true;
13329                printedAnything = true;
13330                pw.print("  Sticky broadcasts for user ");
13331                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13332                StringBuilder sb = new StringBuilder(128);
13333                for (Map.Entry<String, ArrayList<Intent>> ent
13334                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13335                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13336                    if (dumpAll) {
13337                        pw.println(":");
13338                        ArrayList<Intent> intents = ent.getValue();
13339                        final int N = intents.size();
13340                        for (int i=0; i<N; i++) {
13341                            sb.setLength(0);
13342                            sb.append("    Intent: ");
13343                            intents.get(i).toShortString(sb, false, true, false, false);
13344                            pw.println(sb.toString());
13345                            Bundle bundle = intents.get(i).getExtras();
13346                            if (bundle != null) {
13347                                pw.print("      ");
13348                                pw.println(bundle.toString());
13349                            }
13350                        }
13351                    } else {
13352                        pw.println("");
13353                    }
13354                }
13355            }
13356        }
13357
13358        if (!onlyHistory && dumpAll) {
13359            pw.println();
13360            for (BroadcastQueue queue : mBroadcastQueues) {
13361                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13362                        + queue.mBroadcastsScheduled);
13363            }
13364            pw.println("  mHandler:");
13365            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13366            needSep = true;
13367            printedAnything = true;
13368        }
13369
13370        if (!printedAnything) {
13371            pw.println("  (nothing)");
13372        }
13373    }
13374
13375    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13376            int opti, boolean dumpAll, String dumpPackage) {
13377        boolean needSep;
13378        boolean printedAnything = false;
13379
13380        ItemMatcher matcher = new ItemMatcher();
13381        matcher.build(args, opti);
13382
13383        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13384
13385        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13386        printedAnything |= needSep;
13387
13388        if (mLaunchingProviders.size() > 0) {
13389            boolean printed = false;
13390            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13391                ContentProviderRecord r = mLaunchingProviders.get(i);
13392                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13393                    continue;
13394                }
13395                if (!printed) {
13396                    if (needSep) pw.println();
13397                    needSep = true;
13398                    pw.println("  Launching content providers:");
13399                    printed = true;
13400                    printedAnything = true;
13401                }
13402                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13403                        pw.println(r);
13404            }
13405        }
13406
13407        if (mGrantedUriPermissions.size() > 0) {
13408            boolean printed = false;
13409            int dumpUid = -2;
13410            if (dumpPackage != null) {
13411                try {
13412                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13413                } catch (NameNotFoundException e) {
13414                    dumpUid = -1;
13415                }
13416            }
13417            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13418                int uid = mGrantedUriPermissions.keyAt(i);
13419                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13420                    continue;
13421                }
13422                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13423                if (!printed) {
13424                    if (needSep) pw.println();
13425                    needSep = true;
13426                    pw.println("  Granted Uri Permissions:");
13427                    printed = true;
13428                    printedAnything = true;
13429                }
13430                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13431                for (UriPermission perm : perms.values()) {
13432                    pw.print("    "); pw.println(perm);
13433                    if (dumpAll) {
13434                        perm.dump(pw, "      ");
13435                    }
13436                }
13437            }
13438        }
13439
13440        if (!printedAnything) {
13441            pw.println("  (nothing)");
13442        }
13443    }
13444
13445    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13446            int opti, boolean dumpAll, String dumpPackage) {
13447        boolean printed = false;
13448
13449        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13450
13451        if (mIntentSenderRecords.size() > 0) {
13452            Iterator<WeakReference<PendingIntentRecord>> it
13453                    = mIntentSenderRecords.values().iterator();
13454            while (it.hasNext()) {
13455                WeakReference<PendingIntentRecord> ref = it.next();
13456                PendingIntentRecord rec = ref != null ? ref.get(): null;
13457                if (dumpPackage != null && (rec == null
13458                        || !dumpPackage.equals(rec.key.packageName))) {
13459                    continue;
13460                }
13461                printed = true;
13462                if (rec != null) {
13463                    pw.print("  * "); pw.println(rec);
13464                    if (dumpAll) {
13465                        rec.dump(pw, "    ");
13466                    }
13467                } else {
13468                    pw.print("  * "); pw.println(ref);
13469                }
13470            }
13471        }
13472
13473        if (!printed) {
13474            pw.println("  (nothing)");
13475        }
13476    }
13477
13478    private static final int dumpProcessList(PrintWriter pw,
13479            ActivityManagerService service, List list,
13480            String prefix, String normalLabel, String persistentLabel,
13481            String dumpPackage) {
13482        int numPers = 0;
13483        final int N = list.size()-1;
13484        for (int i=N; i>=0; i--) {
13485            ProcessRecord r = (ProcessRecord)list.get(i);
13486            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13487                continue;
13488            }
13489            pw.println(String.format("%s%s #%2d: %s",
13490                    prefix, (r.persistent ? persistentLabel : normalLabel),
13491                    i, r.toString()));
13492            if (r.persistent) {
13493                numPers++;
13494            }
13495        }
13496        return numPers;
13497    }
13498
13499    private static final boolean dumpProcessOomList(PrintWriter pw,
13500            ActivityManagerService service, List<ProcessRecord> origList,
13501            String prefix, String normalLabel, String persistentLabel,
13502            boolean inclDetails, String dumpPackage) {
13503
13504        ArrayList<Pair<ProcessRecord, Integer>> list
13505                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13506        for (int i=0; i<origList.size(); i++) {
13507            ProcessRecord r = origList.get(i);
13508            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13509                continue;
13510            }
13511            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13512        }
13513
13514        if (list.size() <= 0) {
13515            return false;
13516        }
13517
13518        Comparator<Pair<ProcessRecord, Integer>> comparator
13519                = new Comparator<Pair<ProcessRecord, Integer>>() {
13520            @Override
13521            public int compare(Pair<ProcessRecord, Integer> object1,
13522                    Pair<ProcessRecord, Integer> object2) {
13523                if (object1.first.setAdj != object2.first.setAdj) {
13524                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13525                }
13526                if (object1.second.intValue() != object2.second.intValue()) {
13527                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13528                }
13529                return 0;
13530            }
13531        };
13532
13533        Collections.sort(list, comparator);
13534
13535        final long curRealtime = SystemClock.elapsedRealtime();
13536        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13537        final long curUptime = SystemClock.uptimeMillis();
13538        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13539
13540        for (int i=list.size()-1; i>=0; i--) {
13541            ProcessRecord r = list.get(i).first;
13542            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13543            char schedGroup;
13544            switch (r.setSchedGroup) {
13545                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13546                    schedGroup = 'B';
13547                    break;
13548                case Process.THREAD_GROUP_DEFAULT:
13549                    schedGroup = 'F';
13550                    break;
13551                default:
13552                    schedGroup = '?';
13553                    break;
13554            }
13555            char foreground;
13556            if (r.foregroundActivities) {
13557                foreground = 'A';
13558            } else if (r.foregroundServices) {
13559                foreground = 'S';
13560            } else {
13561                foreground = ' ';
13562            }
13563            String procState = ProcessList.makeProcStateString(r.curProcState);
13564            pw.print(prefix);
13565            pw.print(r.persistent ? persistentLabel : normalLabel);
13566            pw.print(" #");
13567            int num = (origList.size()-1)-list.get(i).second;
13568            if (num < 10) pw.print(' ');
13569            pw.print(num);
13570            pw.print(": ");
13571            pw.print(oomAdj);
13572            pw.print(' ');
13573            pw.print(schedGroup);
13574            pw.print('/');
13575            pw.print(foreground);
13576            pw.print('/');
13577            pw.print(procState);
13578            pw.print(" trm:");
13579            if (r.trimMemoryLevel < 10) pw.print(' ');
13580            pw.print(r.trimMemoryLevel);
13581            pw.print(' ');
13582            pw.print(r.toShortString());
13583            pw.print(" (");
13584            pw.print(r.adjType);
13585            pw.println(')');
13586            if (r.adjSource != null || r.adjTarget != null) {
13587                pw.print(prefix);
13588                pw.print("    ");
13589                if (r.adjTarget instanceof ComponentName) {
13590                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13591                } else if (r.adjTarget != null) {
13592                    pw.print(r.adjTarget.toString());
13593                } else {
13594                    pw.print("{null}");
13595                }
13596                pw.print("<=");
13597                if (r.adjSource instanceof ProcessRecord) {
13598                    pw.print("Proc{");
13599                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13600                    pw.println("}");
13601                } else if (r.adjSource != null) {
13602                    pw.println(r.adjSource.toString());
13603                } else {
13604                    pw.println("{null}");
13605                }
13606            }
13607            if (inclDetails) {
13608                pw.print(prefix);
13609                pw.print("    ");
13610                pw.print("oom: max="); pw.print(r.maxAdj);
13611                pw.print(" curRaw="); pw.print(r.curRawAdj);
13612                pw.print(" setRaw="); pw.print(r.setRawAdj);
13613                pw.print(" cur="); pw.print(r.curAdj);
13614                pw.print(" set="); pw.println(r.setAdj);
13615                pw.print(prefix);
13616                pw.print("    ");
13617                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13618                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13619                pw.print(" lastPss="); pw.print(r.lastPss);
13620                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13621                pw.print(prefix);
13622                pw.print("    ");
13623                pw.print("cached="); pw.print(r.cached);
13624                pw.print(" empty="); pw.print(r.empty);
13625                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13626
13627                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13628                    if (r.lastWakeTime != 0) {
13629                        long wtime;
13630                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13631                        synchronized (stats) {
13632                            wtime = stats.getProcessWakeTime(r.info.uid,
13633                                    r.pid, curRealtime);
13634                        }
13635                        long timeUsed = wtime - r.lastWakeTime;
13636                        pw.print(prefix);
13637                        pw.print("    ");
13638                        pw.print("keep awake over ");
13639                        TimeUtils.formatDuration(realtimeSince, pw);
13640                        pw.print(" used ");
13641                        TimeUtils.formatDuration(timeUsed, pw);
13642                        pw.print(" (");
13643                        pw.print((timeUsed*100)/realtimeSince);
13644                        pw.println("%)");
13645                    }
13646                    if (r.lastCpuTime != 0) {
13647                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13648                        pw.print(prefix);
13649                        pw.print("    ");
13650                        pw.print("run cpu over ");
13651                        TimeUtils.formatDuration(uptimeSince, pw);
13652                        pw.print(" used ");
13653                        TimeUtils.formatDuration(timeUsed, pw);
13654                        pw.print(" (");
13655                        pw.print((timeUsed*100)/uptimeSince);
13656                        pw.println("%)");
13657                    }
13658                }
13659            }
13660        }
13661        return true;
13662    }
13663
13664    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13665            String[] args) {
13666        ArrayList<ProcessRecord> procs;
13667        synchronized (this) {
13668            if (args != null && args.length > start
13669                    && args[start].charAt(0) != '-') {
13670                procs = new ArrayList<ProcessRecord>();
13671                int pid = -1;
13672                try {
13673                    pid = Integer.parseInt(args[start]);
13674                } catch (NumberFormatException e) {
13675                }
13676                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13677                    ProcessRecord proc = mLruProcesses.get(i);
13678                    if (proc.pid == pid) {
13679                        procs.add(proc);
13680                    } else if (allPkgs && proc.pkgList != null
13681                            && proc.pkgList.containsKey(args[start])) {
13682                        procs.add(proc);
13683                    } else if (proc.processName.equals(args[start])) {
13684                        procs.add(proc);
13685                    }
13686                }
13687                if (procs.size() <= 0) {
13688                    return null;
13689                }
13690            } else {
13691                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13692            }
13693        }
13694        return procs;
13695    }
13696
13697    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13698            PrintWriter pw, String[] args) {
13699        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13700        if (procs == null) {
13701            pw.println("No process found for: " + args[0]);
13702            return;
13703        }
13704
13705        long uptime = SystemClock.uptimeMillis();
13706        long realtime = SystemClock.elapsedRealtime();
13707        pw.println("Applications Graphics Acceleration Info:");
13708        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13709
13710        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13711            ProcessRecord r = procs.get(i);
13712            if (r.thread != null) {
13713                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13714                pw.flush();
13715                try {
13716                    TransferPipe tp = new TransferPipe();
13717                    try {
13718                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13719                        tp.go(fd);
13720                    } finally {
13721                        tp.kill();
13722                    }
13723                } catch (IOException e) {
13724                    pw.println("Failure while dumping the app: " + r);
13725                    pw.flush();
13726                } catch (RemoteException e) {
13727                    pw.println("Got a RemoteException while dumping the app " + r);
13728                    pw.flush();
13729                }
13730            }
13731        }
13732    }
13733
13734    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13735        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13736        if (procs == null) {
13737            pw.println("No process found for: " + args[0]);
13738            return;
13739        }
13740
13741        pw.println("Applications Database Info:");
13742
13743        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13744            ProcessRecord r = procs.get(i);
13745            if (r.thread != null) {
13746                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13747                pw.flush();
13748                try {
13749                    TransferPipe tp = new TransferPipe();
13750                    try {
13751                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13752                        tp.go(fd);
13753                    } finally {
13754                        tp.kill();
13755                    }
13756                } catch (IOException e) {
13757                    pw.println("Failure while dumping the app: " + r);
13758                    pw.flush();
13759                } catch (RemoteException e) {
13760                    pw.println("Got a RemoteException while dumping the app " + r);
13761                    pw.flush();
13762                }
13763            }
13764        }
13765    }
13766
13767    final static class MemItem {
13768        final boolean isProc;
13769        final String label;
13770        final String shortLabel;
13771        final long pss;
13772        final int id;
13773        final boolean hasActivities;
13774        ArrayList<MemItem> subitems;
13775
13776        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13777                boolean _hasActivities) {
13778            isProc = true;
13779            label = _label;
13780            shortLabel = _shortLabel;
13781            pss = _pss;
13782            id = _id;
13783            hasActivities = _hasActivities;
13784        }
13785
13786        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13787            isProc = false;
13788            label = _label;
13789            shortLabel = _shortLabel;
13790            pss = _pss;
13791            id = _id;
13792            hasActivities = false;
13793        }
13794    }
13795
13796    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13797            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13798        if (sort && !isCompact) {
13799            Collections.sort(items, new Comparator<MemItem>() {
13800                @Override
13801                public int compare(MemItem lhs, MemItem rhs) {
13802                    if (lhs.pss < rhs.pss) {
13803                        return 1;
13804                    } else if (lhs.pss > rhs.pss) {
13805                        return -1;
13806                    }
13807                    return 0;
13808                }
13809            });
13810        }
13811
13812        for (int i=0; i<items.size(); i++) {
13813            MemItem mi = items.get(i);
13814            if (!isCompact) {
13815                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13816            } else if (mi.isProc) {
13817                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13818                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13819                pw.println(mi.hasActivities ? ",a" : ",e");
13820            } else {
13821                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13822                pw.println(mi.pss);
13823            }
13824            if (mi.subitems != null) {
13825                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13826                        true, isCompact);
13827            }
13828        }
13829    }
13830
13831    // These are in KB.
13832    static final long[] DUMP_MEM_BUCKETS = new long[] {
13833        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13834        120*1024, 160*1024, 200*1024,
13835        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13836        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13837    };
13838
13839    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13840            boolean stackLike) {
13841        int start = label.lastIndexOf('.');
13842        if (start >= 0) start++;
13843        else start = 0;
13844        int end = label.length();
13845        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13846            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13847                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13848                out.append(bucket);
13849                out.append(stackLike ? "MB." : "MB ");
13850                out.append(label, start, end);
13851                return;
13852            }
13853        }
13854        out.append(memKB/1024);
13855        out.append(stackLike ? "MB." : "MB ");
13856        out.append(label, start, end);
13857    }
13858
13859    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13860            ProcessList.NATIVE_ADJ,
13861            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13862            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13863            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13864            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13865            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13866            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13867    };
13868    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13869            "Native",
13870            "System", "Persistent", "Persistent Service", "Foreground",
13871            "Visible", "Perceptible",
13872            "Heavy Weight", "Backup",
13873            "A Services", "Home",
13874            "Previous", "B Services", "Cached"
13875    };
13876    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13877            "native",
13878            "sys", "pers", "persvc", "fore",
13879            "vis", "percept",
13880            "heavy", "backup",
13881            "servicea", "home",
13882            "prev", "serviceb", "cached"
13883    };
13884
13885    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13886            long realtime, boolean isCheckinRequest, boolean isCompact) {
13887        if (isCheckinRequest || isCompact) {
13888            // short checkin version
13889            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13890        } else {
13891            pw.println("Applications Memory Usage (kB):");
13892            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13893        }
13894    }
13895
13896    private static final int KSM_SHARED = 0;
13897    private static final int KSM_SHARING = 1;
13898    private static final int KSM_UNSHARED = 2;
13899    private static final int KSM_VOLATILE = 3;
13900
13901    private final long[] getKsmInfo() {
13902        long[] longOut = new long[4];
13903        final int[] SINGLE_LONG_FORMAT = new int[] {
13904            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13905        };
13906        long[] longTmp = new long[1];
13907        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13908                SINGLE_LONG_FORMAT, null, longTmp, null);
13909        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13910        longTmp[0] = 0;
13911        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13912                SINGLE_LONG_FORMAT, null, longTmp, null);
13913        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13914        longTmp[0] = 0;
13915        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13916                SINGLE_LONG_FORMAT, null, longTmp, null);
13917        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13918        longTmp[0] = 0;
13919        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13920                SINGLE_LONG_FORMAT, null, longTmp, null);
13921        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13922        return longOut;
13923    }
13924
13925    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13926            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13927        boolean dumpDetails = false;
13928        boolean dumpFullDetails = false;
13929        boolean dumpDalvik = false;
13930        boolean oomOnly = false;
13931        boolean isCompact = false;
13932        boolean localOnly = false;
13933        boolean packages = false;
13934
13935        int opti = 0;
13936        while (opti < args.length) {
13937            String opt = args[opti];
13938            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13939                break;
13940            }
13941            opti++;
13942            if ("-a".equals(opt)) {
13943                dumpDetails = true;
13944                dumpFullDetails = true;
13945                dumpDalvik = true;
13946            } else if ("-d".equals(opt)) {
13947                dumpDalvik = true;
13948            } else if ("-c".equals(opt)) {
13949                isCompact = true;
13950            } else if ("--oom".equals(opt)) {
13951                oomOnly = true;
13952            } else if ("--local".equals(opt)) {
13953                localOnly = true;
13954            } else if ("--package".equals(opt)) {
13955                packages = true;
13956            } else if ("-h".equals(opt)) {
13957                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13958                pw.println("  -a: include all available information for each process.");
13959                pw.println("  -d: include dalvik details when dumping process details.");
13960                pw.println("  -c: dump in a compact machine-parseable representation.");
13961                pw.println("  --oom: only show processes organized by oom adj.");
13962                pw.println("  --local: only collect details locally, don't call process.");
13963                pw.println("  --package: interpret process arg as package, dumping all");
13964                pw.println("             processes that have loaded that package.");
13965                pw.println("If [process] is specified it can be the name or ");
13966                pw.println("pid of a specific process to dump.");
13967                return;
13968            } else {
13969                pw.println("Unknown argument: " + opt + "; use -h for help");
13970            }
13971        }
13972
13973        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13974        long uptime = SystemClock.uptimeMillis();
13975        long realtime = SystemClock.elapsedRealtime();
13976        final long[] tmpLong = new long[1];
13977
13978        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13979        if (procs == null) {
13980            // No Java processes.  Maybe they want to print a native process.
13981            if (args != null && args.length > opti
13982                    && args[opti].charAt(0) != '-') {
13983                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13984                        = new ArrayList<ProcessCpuTracker.Stats>();
13985                updateCpuStatsNow();
13986                int findPid = -1;
13987                try {
13988                    findPid = Integer.parseInt(args[opti]);
13989                } catch (NumberFormatException e) {
13990                }
13991                synchronized (mProcessCpuTracker) {
13992                    final int N = mProcessCpuTracker.countStats();
13993                    for (int i=0; i<N; i++) {
13994                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13995                        if (st.pid == findPid || (st.baseName != null
13996                                && st.baseName.equals(args[opti]))) {
13997                            nativeProcs.add(st);
13998                        }
13999                    }
14000                }
14001                if (nativeProcs.size() > 0) {
14002                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14003                            isCompact);
14004                    Debug.MemoryInfo mi = null;
14005                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14006                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14007                        final int pid = r.pid;
14008                        if (!isCheckinRequest && dumpDetails) {
14009                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14010                        }
14011                        if (mi == null) {
14012                            mi = new Debug.MemoryInfo();
14013                        }
14014                        if (dumpDetails || (!brief && !oomOnly)) {
14015                            Debug.getMemoryInfo(pid, mi);
14016                        } else {
14017                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14018                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14019                        }
14020                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14021                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14022                        if (isCheckinRequest) {
14023                            pw.println();
14024                        }
14025                    }
14026                    return;
14027                }
14028            }
14029            pw.println("No process found for: " + args[opti]);
14030            return;
14031        }
14032
14033        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14034            dumpDetails = true;
14035        }
14036
14037        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14038
14039        String[] innerArgs = new String[args.length-opti];
14040        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14041
14042        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14043        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14044        long nativePss = 0;
14045        long dalvikPss = 0;
14046        long otherPss = 0;
14047        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14048
14049        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14050        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14051                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14052
14053        long totalPss = 0;
14054        long cachedPss = 0;
14055
14056        Debug.MemoryInfo mi = null;
14057        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14058            final ProcessRecord r = procs.get(i);
14059            final IApplicationThread thread;
14060            final int pid;
14061            final int oomAdj;
14062            final boolean hasActivities;
14063            synchronized (this) {
14064                thread = r.thread;
14065                pid = r.pid;
14066                oomAdj = r.getSetAdjWithServices();
14067                hasActivities = r.activities.size() > 0;
14068            }
14069            if (thread != null) {
14070                if (!isCheckinRequest && dumpDetails) {
14071                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14072                }
14073                if (mi == null) {
14074                    mi = new Debug.MemoryInfo();
14075                }
14076                if (dumpDetails || (!brief && !oomOnly)) {
14077                    Debug.getMemoryInfo(pid, mi);
14078                } else {
14079                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14080                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14081                }
14082                if (dumpDetails) {
14083                    if (localOnly) {
14084                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14085                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14086                        if (isCheckinRequest) {
14087                            pw.println();
14088                        }
14089                    } else {
14090                        try {
14091                            pw.flush();
14092                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14093                                    dumpDalvik, innerArgs);
14094                        } catch (RemoteException e) {
14095                            if (!isCheckinRequest) {
14096                                pw.println("Got RemoteException!");
14097                                pw.flush();
14098                            }
14099                        }
14100                    }
14101                }
14102
14103                final long myTotalPss = mi.getTotalPss();
14104                final long myTotalUss = mi.getTotalUss();
14105
14106                synchronized (this) {
14107                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14108                        // Record this for posterity if the process has been stable.
14109                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14110                    }
14111                }
14112
14113                if (!isCheckinRequest && mi != null) {
14114                    totalPss += myTotalPss;
14115                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14116                            (hasActivities ? " / activities)" : ")"),
14117                            r.processName, myTotalPss, pid, hasActivities);
14118                    procMems.add(pssItem);
14119                    procMemsMap.put(pid, pssItem);
14120
14121                    nativePss += mi.nativePss;
14122                    dalvikPss += mi.dalvikPss;
14123                    otherPss += mi.otherPss;
14124                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14125                        long mem = mi.getOtherPss(j);
14126                        miscPss[j] += mem;
14127                        otherPss -= mem;
14128                    }
14129
14130                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14131                        cachedPss += myTotalPss;
14132                    }
14133
14134                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14135                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14136                                || oomIndex == (oomPss.length-1)) {
14137                            oomPss[oomIndex] += myTotalPss;
14138                            if (oomProcs[oomIndex] == null) {
14139                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14140                            }
14141                            oomProcs[oomIndex].add(pssItem);
14142                            break;
14143                        }
14144                    }
14145                }
14146            }
14147        }
14148
14149        long nativeProcTotalPss = 0;
14150
14151        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14152            // If we are showing aggregations, also look for native processes to
14153            // include so that our aggregations are more accurate.
14154            updateCpuStatsNow();
14155            mi = null;
14156            synchronized (mProcessCpuTracker) {
14157                final int N = mProcessCpuTracker.countStats();
14158                for (int i=0; i<N; i++) {
14159                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14160                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14161                        if (mi == null) {
14162                            mi = new Debug.MemoryInfo();
14163                        }
14164                        if (!brief && !oomOnly) {
14165                            Debug.getMemoryInfo(st.pid, mi);
14166                        } else {
14167                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14168                            mi.nativePrivateDirty = (int)tmpLong[0];
14169                        }
14170
14171                        final long myTotalPss = mi.getTotalPss();
14172                        totalPss += myTotalPss;
14173                        nativeProcTotalPss += myTotalPss;
14174
14175                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14176                                st.name, myTotalPss, st.pid, false);
14177                        procMems.add(pssItem);
14178
14179                        nativePss += mi.nativePss;
14180                        dalvikPss += mi.dalvikPss;
14181                        otherPss += mi.otherPss;
14182                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14183                            long mem = mi.getOtherPss(j);
14184                            miscPss[j] += mem;
14185                            otherPss -= mem;
14186                        }
14187                        oomPss[0] += myTotalPss;
14188                        if (oomProcs[0] == null) {
14189                            oomProcs[0] = new ArrayList<MemItem>();
14190                        }
14191                        oomProcs[0].add(pssItem);
14192                    }
14193                }
14194            }
14195
14196            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14197
14198            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14199            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14200            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14201            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14202                String label = Debug.MemoryInfo.getOtherLabel(j);
14203                catMems.add(new MemItem(label, label, miscPss[j], j));
14204            }
14205
14206            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14207            for (int j=0; j<oomPss.length; j++) {
14208                if (oomPss[j] != 0) {
14209                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14210                            : DUMP_MEM_OOM_LABEL[j];
14211                    MemItem item = new MemItem(label, label, oomPss[j],
14212                            DUMP_MEM_OOM_ADJ[j]);
14213                    item.subitems = oomProcs[j];
14214                    oomMems.add(item);
14215                }
14216            }
14217
14218            if (!brief && !oomOnly && !isCompact) {
14219                pw.println();
14220                pw.println("Total PSS by process:");
14221                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14222                pw.println();
14223            }
14224            if (!isCompact) {
14225                pw.println("Total PSS by OOM adjustment:");
14226            }
14227            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14228            if (!brief && !oomOnly) {
14229                PrintWriter out = categoryPw != null ? categoryPw : pw;
14230                if (!isCompact) {
14231                    out.println();
14232                    out.println("Total PSS by category:");
14233                }
14234                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14235            }
14236            if (!isCompact) {
14237                pw.println();
14238            }
14239            MemInfoReader memInfo = new MemInfoReader();
14240            memInfo.readMemInfo();
14241            if (nativeProcTotalPss > 0) {
14242                synchronized (this) {
14243                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14244                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14245                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14246                }
14247            }
14248            if (!brief) {
14249                if (!isCompact) {
14250                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14251                    pw.print(" kB (status ");
14252                    switch (mLastMemoryLevel) {
14253                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14254                            pw.println("normal)");
14255                            break;
14256                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14257                            pw.println("moderate)");
14258                            break;
14259                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14260                            pw.println("low)");
14261                            break;
14262                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14263                            pw.println("critical)");
14264                            break;
14265                        default:
14266                            pw.print(mLastMemoryLevel);
14267                            pw.println(")");
14268                            break;
14269                    }
14270                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14271                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14272                            pw.print(cachedPss); pw.print(" cached pss + ");
14273                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14274                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14275                } else {
14276                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14277                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14278                            + memInfo.getFreeSizeKb()); pw.print(",");
14279                    pw.println(totalPss - cachedPss);
14280                }
14281            }
14282            if (!isCompact) {
14283                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14284                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14285                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14286                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14287                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14288                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14289                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14290            }
14291            if (!brief) {
14292                if (memInfo.getZramTotalSizeKb() != 0) {
14293                    if (!isCompact) {
14294                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14295                                pw.print(" kB physical used for ");
14296                                pw.print(memInfo.getSwapTotalSizeKb()
14297                                        - memInfo.getSwapFreeSizeKb());
14298                                pw.print(" kB in swap (");
14299                                pw.print(memInfo.getSwapTotalSizeKb());
14300                                pw.println(" kB total swap)");
14301                    } else {
14302                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14303                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14304                                pw.println(memInfo.getSwapFreeSizeKb());
14305                    }
14306                }
14307                final long[] ksm = getKsmInfo();
14308                if (!isCompact) {
14309                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14310                            || ksm[KSM_VOLATILE] != 0) {
14311                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14312                                pw.print(" kB saved from shared ");
14313                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14314                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14315                                pw.print(" kB unshared; ");
14316                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14317                    }
14318                    pw.print("   Tuning: ");
14319                    pw.print(ActivityManager.staticGetMemoryClass());
14320                    pw.print(" (large ");
14321                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14322                    pw.print("), oom ");
14323                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14324                    pw.print(" kB");
14325                    pw.print(", restore limit ");
14326                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14327                    pw.print(" kB");
14328                    if (ActivityManager.isLowRamDeviceStatic()) {
14329                        pw.print(" (low-ram)");
14330                    }
14331                    if (ActivityManager.isHighEndGfx()) {
14332                        pw.print(" (high-end-gfx)");
14333                    }
14334                    pw.println();
14335                } else {
14336                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14337                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14338                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14339                    pw.print("tuning,");
14340                    pw.print(ActivityManager.staticGetMemoryClass());
14341                    pw.print(',');
14342                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14343                    pw.print(',');
14344                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14345                    if (ActivityManager.isLowRamDeviceStatic()) {
14346                        pw.print(",low-ram");
14347                    }
14348                    if (ActivityManager.isHighEndGfx()) {
14349                        pw.print(",high-end-gfx");
14350                    }
14351                    pw.println();
14352                }
14353            }
14354        }
14355    }
14356
14357    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14358            long memtrack, String name) {
14359        sb.append("  ");
14360        sb.append(ProcessList.makeOomAdjString(oomAdj));
14361        sb.append(' ');
14362        sb.append(ProcessList.makeProcStateString(procState));
14363        sb.append(' ');
14364        ProcessList.appendRamKb(sb, pss);
14365        sb.append(" kB: ");
14366        sb.append(name);
14367        if (memtrack > 0) {
14368            sb.append(" (");
14369            sb.append(memtrack);
14370            sb.append(" kB memtrack)");
14371        }
14372    }
14373
14374    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14375        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14376        sb.append(" (pid ");
14377        sb.append(mi.pid);
14378        sb.append(") ");
14379        sb.append(mi.adjType);
14380        sb.append('\n');
14381        if (mi.adjReason != null) {
14382            sb.append("                      ");
14383            sb.append(mi.adjReason);
14384            sb.append('\n');
14385        }
14386    }
14387
14388    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14389        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14390        for (int i=0, N=memInfos.size(); i<N; i++) {
14391            ProcessMemInfo mi = memInfos.get(i);
14392            infoMap.put(mi.pid, mi);
14393        }
14394        updateCpuStatsNow();
14395        long[] memtrackTmp = new long[1];
14396        synchronized (mProcessCpuTracker) {
14397            final int N = mProcessCpuTracker.countStats();
14398            for (int i=0; i<N; i++) {
14399                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14400                if (st.vsize > 0) {
14401                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14402                    if (pss > 0) {
14403                        if (infoMap.indexOfKey(st.pid) < 0) {
14404                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14405                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14406                            mi.pss = pss;
14407                            mi.memtrack = memtrackTmp[0];
14408                            memInfos.add(mi);
14409                        }
14410                    }
14411                }
14412            }
14413        }
14414
14415        long totalPss = 0;
14416        long totalMemtrack = 0;
14417        for (int i=0, N=memInfos.size(); i<N; i++) {
14418            ProcessMemInfo mi = memInfos.get(i);
14419            if (mi.pss == 0) {
14420                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14421                mi.memtrack = memtrackTmp[0];
14422            }
14423            totalPss += mi.pss;
14424            totalMemtrack += mi.memtrack;
14425        }
14426        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14427            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14428                if (lhs.oomAdj != rhs.oomAdj) {
14429                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14430                }
14431                if (lhs.pss != rhs.pss) {
14432                    return lhs.pss < rhs.pss ? 1 : -1;
14433                }
14434                return 0;
14435            }
14436        });
14437
14438        StringBuilder tag = new StringBuilder(128);
14439        StringBuilder stack = new StringBuilder(128);
14440        tag.append("Low on memory -- ");
14441        appendMemBucket(tag, totalPss, "total", false);
14442        appendMemBucket(stack, totalPss, "total", true);
14443
14444        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14445        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14446        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14447
14448        boolean firstLine = true;
14449        int lastOomAdj = Integer.MIN_VALUE;
14450        long extraNativeRam = 0;
14451        long extraNativeMemtrack = 0;
14452        long cachedPss = 0;
14453        for (int i=0, N=memInfos.size(); i<N; i++) {
14454            ProcessMemInfo mi = memInfos.get(i);
14455
14456            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14457                cachedPss += mi.pss;
14458            }
14459
14460            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14461                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14462                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14463                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14464                if (lastOomAdj != mi.oomAdj) {
14465                    lastOomAdj = mi.oomAdj;
14466                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14467                        tag.append(" / ");
14468                    }
14469                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14470                        if (firstLine) {
14471                            stack.append(":");
14472                            firstLine = false;
14473                        }
14474                        stack.append("\n\t at ");
14475                    } else {
14476                        stack.append("$");
14477                    }
14478                } else {
14479                    tag.append(" ");
14480                    stack.append("$");
14481                }
14482                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14483                    appendMemBucket(tag, mi.pss, mi.name, false);
14484                }
14485                appendMemBucket(stack, mi.pss, mi.name, true);
14486                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14487                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14488                    stack.append("(");
14489                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14490                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14491                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14492                            stack.append(":");
14493                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14494                        }
14495                    }
14496                    stack.append(")");
14497                }
14498            }
14499
14500            appendMemInfo(fullNativeBuilder, mi);
14501            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14502                // The short form only has native processes that are >= 512K.
14503                if (mi.pss >= 512) {
14504                    appendMemInfo(shortNativeBuilder, mi);
14505                } else {
14506                    extraNativeRam += mi.pss;
14507                    extraNativeMemtrack += mi.memtrack;
14508                }
14509            } else {
14510                // Short form has all other details, but if we have collected RAM
14511                // from smaller native processes let's dump a summary of that.
14512                if (extraNativeRam > 0) {
14513                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14514                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14515                    shortNativeBuilder.append('\n');
14516                    extraNativeRam = 0;
14517                }
14518                appendMemInfo(fullJavaBuilder, mi);
14519            }
14520        }
14521
14522        fullJavaBuilder.append("           ");
14523        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14524        fullJavaBuilder.append(" kB: TOTAL");
14525        if (totalMemtrack > 0) {
14526            fullJavaBuilder.append(" (");
14527            fullJavaBuilder.append(totalMemtrack);
14528            fullJavaBuilder.append(" kB memtrack)");
14529        } else {
14530        }
14531        fullJavaBuilder.append("\n");
14532
14533        MemInfoReader memInfo = new MemInfoReader();
14534        memInfo.readMemInfo();
14535        final long[] infos = memInfo.getRawInfo();
14536
14537        StringBuilder memInfoBuilder = new StringBuilder(1024);
14538        Debug.getMemInfo(infos);
14539        memInfoBuilder.append("  MemInfo: ");
14540        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14541        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14542        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14543        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14544        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14545        memInfoBuilder.append("           ");
14546        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14547        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14548        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14549        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14550        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14551            memInfoBuilder.append("  ZRAM: ");
14552            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14553            memInfoBuilder.append(" kB RAM, ");
14554            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14555            memInfoBuilder.append(" kB swap total, ");
14556            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14557            memInfoBuilder.append(" kB swap free\n");
14558        }
14559        final long[] ksm = getKsmInfo();
14560        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14561                || ksm[KSM_VOLATILE] != 0) {
14562            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14563            memInfoBuilder.append(" kB saved from shared ");
14564            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14565            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14566            memInfoBuilder.append(" kB unshared; ");
14567            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14568        }
14569        memInfoBuilder.append("  Free RAM: ");
14570        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14571                + memInfo.getFreeSizeKb());
14572        memInfoBuilder.append(" kB\n");
14573        memInfoBuilder.append("  Used RAM: ");
14574        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14575        memInfoBuilder.append(" kB\n");
14576        memInfoBuilder.append("  Lost RAM: ");
14577        memInfoBuilder.append(memInfo.getTotalSizeKb()
14578                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14579                - memInfo.getKernelUsedSizeKb());
14580        memInfoBuilder.append(" kB\n");
14581        Slog.i(TAG, "Low on memory:");
14582        Slog.i(TAG, shortNativeBuilder.toString());
14583        Slog.i(TAG, fullJavaBuilder.toString());
14584        Slog.i(TAG, memInfoBuilder.toString());
14585
14586        StringBuilder dropBuilder = new StringBuilder(1024);
14587        /*
14588        StringWriter oomSw = new StringWriter();
14589        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14590        StringWriter catSw = new StringWriter();
14591        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14592        String[] emptyArgs = new String[] { };
14593        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14594        oomPw.flush();
14595        String oomString = oomSw.toString();
14596        */
14597        dropBuilder.append("Low on memory:");
14598        dropBuilder.append(stack);
14599        dropBuilder.append('\n');
14600        dropBuilder.append(fullNativeBuilder);
14601        dropBuilder.append(fullJavaBuilder);
14602        dropBuilder.append('\n');
14603        dropBuilder.append(memInfoBuilder);
14604        dropBuilder.append('\n');
14605        /*
14606        dropBuilder.append(oomString);
14607        dropBuilder.append('\n');
14608        */
14609        StringWriter catSw = new StringWriter();
14610        synchronized (ActivityManagerService.this) {
14611            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14612            String[] emptyArgs = new String[] { };
14613            catPw.println();
14614            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14615            catPw.println();
14616            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14617                    false, false, null);
14618            catPw.println();
14619            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14620            catPw.flush();
14621        }
14622        dropBuilder.append(catSw.toString());
14623        addErrorToDropBox("lowmem", null, "system_server", null,
14624                null, tag.toString(), dropBuilder.toString(), null, null);
14625        //Slog.i(TAG, "Sent to dropbox:");
14626        //Slog.i(TAG, dropBuilder.toString());
14627        synchronized (ActivityManagerService.this) {
14628            long now = SystemClock.uptimeMillis();
14629            if (mLastMemUsageReportTime < now) {
14630                mLastMemUsageReportTime = now;
14631            }
14632        }
14633    }
14634
14635    /**
14636     * Searches array of arguments for the specified string
14637     * @param args array of argument strings
14638     * @param value value to search for
14639     * @return true if the value is contained in the array
14640     */
14641    private static boolean scanArgs(String[] args, String value) {
14642        if (args != null) {
14643            for (String arg : args) {
14644                if (value.equals(arg)) {
14645                    return true;
14646                }
14647            }
14648        }
14649        return false;
14650    }
14651
14652    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14653            ContentProviderRecord cpr, boolean always) {
14654        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14655
14656        if (!inLaunching || always) {
14657            synchronized (cpr) {
14658                cpr.launchingApp = null;
14659                cpr.notifyAll();
14660            }
14661            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14662            String names[] = cpr.info.authority.split(";");
14663            for (int j = 0; j < names.length; j++) {
14664                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14665            }
14666        }
14667
14668        for (int i=0; i<cpr.connections.size(); i++) {
14669            ContentProviderConnection conn = cpr.connections.get(i);
14670            if (conn.waiting) {
14671                // If this connection is waiting for the provider, then we don't
14672                // need to mess with its process unless we are always removing
14673                // or for some reason the provider is not currently launching.
14674                if (inLaunching && !always) {
14675                    continue;
14676                }
14677            }
14678            ProcessRecord capp = conn.client;
14679            conn.dead = true;
14680            if (conn.stableCount > 0) {
14681                if (!capp.persistent && capp.thread != null
14682                        && capp.pid != 0
14683                        && capp.pid != MY_PID) {
14684                    capp.kill("depends on provider "
14685                            + cpr.name.flattenToShortString()
14686                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14687                }
14688            } else if (capp.thread != null && conn.provider.provider != null) {
14689                try {
14690                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14691                } catch (RemoteException e) {
14692                }
14693                // In the protocol here, we don't expect the client to correctly
14694                // clean up this connection, we'll just remove it.
14695                cpr.connections.remove(i);
14696                conn.client.conProviders.remove(conn);
14697            }
14698        }
14699
14700        if (inLaunching && always) {
14701            mLaunchingProviders.remove(cpr);
14702        }
14703        return inLaunching;
14704    }
14705
14706    /**
14707     * Main code for cleaning up a process when it has gone away.  This is
14708     * called both as a result of the process dying, or directly when stopping
14709     * a process when running in single process mode.
14710     *
14711     * @return Returns true if the given process has been restarted, so the
14712     * app that was passed in must remain on the process lists.
14713     */
14714    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14715            boolean restarting, boolean allowRestart, int index) {
14716        if (index >= 0) {
14717            removeLruProcessLocked(app);
14718            ProcessList.remove(app.pid);
14719        }
14720
14721        mProcessesToGc.remove(app);
14722        mPendingPssProcesses.remove(app);
14723
14724        // Dismiss any open dialogs.
14725        if (app.crashDialog != null && !app.forceCrashReport) {
14726            app.crashDialog.dismiss();
14727            app.crashDialog = null;
14728        }
14729        if (app.anrDialog != null) {
14730            app.anrDialog.dismiss();
14731            app.anrDialog = null;
14732        }
14733        if (app.waitDialog != null) {
14734            app.waitDialog.dismiss();
14735            app.waitDialog = null;
14736        }
14737
14738        app.crashing = false;
14739        app.notResponding = false;
14740
14741        app.resetPackageList(mProcessStats);
14742        app.unlinkDeathRecipient();
14743        app.makeInactive(mProcessStats);
14744        app.waitingToKill = null;
14745        app.forcingToForeground = null;
14746        updateProcessForegroundLocked(app, false, false);
14747        app.foregroundActivities = false;
14748        app.hasShownUi = false;
14749        app.treatLikeActivity = false;
14750        app.hasAboveClient = false;
14751        app.hasClientActivities = false;
14752
14753        mServices.killServicesLocked(app, allowRestart);
14754
14755        boolean restart = false;
14756
14757        // Remove published content providers.
14758        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14759            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14760            final boolean always = app.bad || !allowRestart;
14761            if (removeDyingProviderLocked(app, cpr, always) || always) {
14762                // We left the provider in the launching list, need to
14763                // restart it.
14764                restart = true;
14765            }
14766
14767            cpr.provider = null;
14768            cpr.proc = null;
14769        }
14770        app.pubProviders.clear();
14771
14772        // Take care of any launching providers waiting for this process.
14773        if (checkAppInLaunchingProvidersLocked(app, false)) {
14774            restart = true;
14775        }
14776
14777        // Unregister from connected content providers.
14778        if (!app.conProviders.isEmpty()) {
14779            for (int i=0; i<app.conProviders.size(); i++) {
14780                ContentProviderConnection conn = app.conProviders.get(i);
14781                conn.provider.connections.remove(conn);
14782            }
14783            app.conProviders.clear();
14784        }
14785
14786        // At this point there may be remaining entries in mLaunchingProviders
14787        // where we were the only one waiting, so they are no longer of use.
14788        // Look for these and clean up if found.
14789        // XXX Commented out for now.  Trying to figure out a way to reproduce
14790        // the actual situation to identify what is actually going on.
14791        if (false) {
14792            for (int i=0; i<mLaunchingProviders.size(); i++) {
14793                ContentProviderRecord cpr = (ContentProviderRecord)
14794                        mLaunchingProviders.get(i);
14795                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14796                    synchronized (cpr) {
14797                        cpr.launchingApp = null;
14798                        cpr.notifyAll();
14799                    }
14800                }
14801            }
14802        }
14803
14804        skipCurrentReceiverLocked(app);
14805
14806        // Unregister any receivers.
14807        for (int i=app.receivers.size()-1; i>=0; i--) {
14808            removeReceiverLocked(app.receivers.valueAt(i));
14809        }
14810        app.receivers.clear();
14811
14812        // If the app is undergoing backup, tell the backup manager about it
14813        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14814            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14815                    + mBackupTarget.appInfo + " died during backup");
14816            try {
14817                IBackupManager bm = IBackupManager.Stub.asInterface(
14818                        ServiceManager.getService(Context.BACKUP_SERVICE));
14819                bm.agentDisconnected(app.info.packageName);
14820            } catch (RemoteException e) {
14821                // can't happen; backup manager is local
14822            }
14823        }
14824
14825        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14826            ProcessChangeItem item = mPendingProcessChanges.get(i);
14827            if (item.pid == app.pid) {
14828                mPendingProcessChanges.remove(i);
14829                mAvailProcessChanges.add(item);
14830            }
14831        }
14832        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14833
14834        // If the caller is restarting this app, then leave it in its
14835        // current lists and let the caller take care of it.
14836        if (restarting) {
14837            return false;
14838        }
14839
14840        if (!app.persistent || app.isolated) {
14841            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14842                    "Removing non-persistent process during cleanup: " + app);
14843            mProcessNames.remove(app.processName, app.uid);
14844            mIsolatedProcesses.remove(app.uid);
14845            if (mHeavyWeightProcess == app) {
14846                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14847                        mHeavyWeightProcess.userId, 0));
14848                mHeavyWeightProcess = null;
14849            }
14850        } else if (!app.removed) {
14851            // This app is persistent, so we need to keep its record around.
14852            // If it is not already on the pending app list, add it there
14853            // and start a new process for it.
14854            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14855                mPersistentStartingProcesses.add(app);
14856                restart = true;
14857            }
14858        }
14859        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14860                "Clean-up removing on hold: " + app);
14861        mProcessesOnHold.remove(app);
14862
14863        if (app == mHomeProcess) {
14864            mHomeProcess = null;
14865        }
14866        if (app == mPreviousProcess) {
14867            mPreviousProcess = null;
14868        }
14869
14870        if (restart && !app.isolated) {
14871            // We have components that still need to be running in the
14872            // process, so re-launch it.
14873            if (index < 0) {
14874                ProcessList.remove(app.pid);
14875            }
14876            mProcessNames.put(app.processName, app.uid, app);
14877            startProcessLocked(app, "restart", app.processName);
14878            return true;
14879        } else if (app.pid > 0 && app.pid != MY_PID) {
14880            // Goodbye!
14881            boolean removed;
14882            synchronized (mPidsSelfLocked) {
14883                mPidsSelfLocked.remove(app.pid);
14884                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14885            }
14886            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14887            if (app.isolated) {
14888                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14889            }
14890            app.setPid(0);
14891        }
14892        return false;
14893    }
14894
14895    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14896        // Look through the content providers we are waiting to have launched,
14897        // and if any run in this process then either schedule a restart of
14898        // the process or kill the client waiting for it if this process has
14899        // gone bad.
14900        int NL = mLaunchingProviders.size();
14901        boolean restart = false;
14902        for (int i=0; i<NL; i++) {
14903            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14904            if (cpr.launchingApp == app) {
14905                if (!alwaysBad && !app.bad) {
14906                    restart = true;
14907                } else {
14908                    removeDyingProviderLocked(app, cpr, true);
14909                    // cpr should have been removed from mLaunchingProviders
14910                    NL = mLaunchingProviders.size();
14911                    i--;
14912                }
14913            }
14914        }
14915        return restart;
14916    }
14917
14918    // =========================================================
14919    // SERVICES
14920    // =========================================================
14921
14922    @Override
14923    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14924            int flags) {
14925        enforceNotIsolatedCaller("getServices");
14926        synchronized (this) {
14927            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14928        }
14929    }
14930
14931    @Override
14932    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14933        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14934        synchronized (this) {
14935            return mServices.getRunningServiceControlPanelLocked(name);
14936        }
14937    }
14938
14939    @Override
14940    public ComponentName startService(IApplicationThread caller, Intent service,
14941            String resolvedType, int userId) {
14942        enforceNotIsolatedCaller("startService");
14943        // Refuse possible leaked file descriptors
14944        if (service != null && service.hasFileDescriptors() == true) {
14945            throw new IllegalArgumentException("File descriptors passed in Intent");
14946        }
14947
14948        if (DEBUG_SERVICE)
14949            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14950        synchronized(this) {
14951            final int callingPid = Binder.getCallingPid();
14952            final int callingUid = Binder.getCallingUid();
14953            final long origId = Binder.clearCallingIdentity();
14954            ComponentName res = mServices.startServiceLocked(caller, service,
14955                    resolvedType, callingPid, callingUid, userId);
14956            Binder.restoreCallingIdentity(origId);
14957            return res;
14958        }
14959    }
14960
14961    ComponentName startServiceInPackage(int uid,
14962            Intent service, String resolvedType, int userId) {
14963        synchronized(this) {
14964            if (DEBUG_SERVICE)
14965                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14966            final long origId = Binder.clearCallingIdentity();
14967            ComponentName res = mServices.startServiceLocked(null, service,
14968                    resolvedType, -1, uid, userId);
14969            Binder.restoreCallingIdentity(origId);
14970            return res;
14971        }
14972    }
14973
14974    @Override
14975    public int stopService(IApplicationThread caller, Intent service,
14976            String resolvedType, int userId) {
14977        enforceNotIsolatedCaller("stopService");
14978        // Refuse possible leaked file descriptors
14979        if (service != null && service.hasFileDescriptors() == true) {
14980            throw new IllegalArgumentException("File descriptors passed in Intent");
14981        }
14982
14983        synchronized(this) {
14984            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14985        }
14986    }
14987
14988    @Override
14989    public IBinder peekService(Intent service, String resolvedType) {
14990        enforceNotIsolatedCaller("peekService");
14991        // Refuse possible leaked file descriptors
14992        if (service != null && service.hasFileDescriptors() == true) {
14993            throw new IllegalArgumentException("File descriptors passed in Intent");
14994        }
14995        synchronized(this) {
14996            return mServices.peekServiceLocked(service, resolvedType);
14997        }
14998    }
14999
15000    @Override
15001    public boolean stopServiceToken(ComponentName className, IBinder token,
15002            int startId) {
15003        synchronized(this) {
15004            return mServices.stopServiceTokenLocked(className, token, startId);
15005        }
15006    }
15007
15008    @Override
15009    public void setServiceForeground(ComponentName className, IBinder token,
15010            int id, Notification notification, boolean removeNotification) {
15011        synchronized(this) {
15012            mServices.setServiceForegroundLocked(className, token, id, notification,
15013                    removeNotification);
15014        }
15015    }
15016
15017    @Override
15018    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15019            boolean requireFull, String name, String callerPackage) {
15020        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15021                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15022    }
15023
15024    int unsafeConvertIncomingUser(int userId) {
15025        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15026                ? mCurrentUserId : userId;
15027    }
15028
15029    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15030            int allowMode, String name, String callerPackage) {
15031        final int callingUserId = UserHandle.getUserId(callingUid);
15032        if (callingUserId == userId) {
15033            return userId;
15034        }
15035
15036        // Note that we may be accessing mCurrentUserId outside of a lock...
15037        // shouldn't be a big deal, if this is being called outside
15038        // of a locked context there is intrinsically a race with
15039        // the value the caller will receive and someone else changing it.
15040        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15041        // we will switch to the calling user if access to the current user fails.
15042        int targetUserId = unsafeConvertIncomingUser(userId);
15043
15044        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15045            final boolean allow;
15046            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15047                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15048                // If the caller has this permission, they always pass go.  And collect $200.
15049                allow = true;
15050            } else if (allowMode == ALLOW_FULL_ONLY) {
15051                // We require full access, sucks to be you.
15052                allow = false;
15053            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15054                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15055                // If the caller does not have either permission, they are always doomed.
15056                allow = false;
15057            } else if (allowMode == ALLOW_NON_FULL) {
15058                // We are blanket allowing non-full access, you lucky caller!
15059                allow = true;
15060            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15061                // We may or may not allow this depending on whether the two users are
15062                // in the same profile.
15063                synchronized (mUserProfileGroupIdsSelfLocked) {
15064                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15065                            UserInfo.NO_PROFILE_GROUP_ID);
15066                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15067                            UserInfo.NO_PROFILE_GROUP_ID);
15068                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15069                            && callingProfile == targetProfile;
15070                }
15071            } else {
15072                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15073            }
15074            if (!allow) {
15075                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15076                    // In this case, they would like to just execute as their
15077                    // owner user instead of failing.
15078                    targetUserId = callingUserId;
15079                } else {
15080                    StringBuilder builder = new StringBuilder(128);
15081                    builder.append("Permission Denial: ");
15082                    builder.append(name);
15083                    if (callerPackage != null) {
15084                        builder.append(" from ");
15085                        builder.append(callerPackage);
15086                    }
15087                    builder.append(" asks to run as user ");
15088                    builder.append(userId);
15089                    builder.append(" but is calling from user ");
15090                    builder.append(UserHandle.getUserId(callingUid));
15091                    builder.append("; this requires ");
15092                    builder.append(INTERACT_ACROSS_USERS_FULL);
15093                    if (allowMode != ALLOW_FULL_ONLY) {
15094                        builder.append(" or ");
15095                        builder.append(INTERACT_ACROSS_USERS);
15096                    }
15097                    String msg = builder.toString();
15098                    Slog.w(TAG, msg);
15099                    throw new SecurityException(msg);
15100                }
15101            }
15102        }
15103        if (!allowAll && targetUserId < 0) {
15104            throw new IllegalArgumentException(
15105                    "Call does not support special user #" + targetUserId);
15106        }
15107        // Check shell permission
15108        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15109            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15110                    targetUserId)) {
15111                throw new SecurityException("Shell does not have permission to access user "
15112                        + targetUserId + "\n " + Debug.getCallers(3));
15113            }
15114        }
15115        return targetUserId;
15116    }
15117
15118    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15119            String className, int flags) {
15120        boolean result = false;
15121        // For apps that don't have pre-defined UIDs, check for permission
15122        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15123            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15124                if (ActivityManager.checkUidPermission(
15125                        INTERACT_ACROSS_USERS,
15126                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15127                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15128                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15129                            + " requests FLAG_SINGLE_USER, but app does not hold "
15130                            + INTERACT_ACROSS_USERS;
15131                    Slog.w(TAG, msg);
15132                    throw new SecurityException(msg);
15133                }
15134                // Permission passed
15135                result = true;
15136            }
15137        } else if ("system".equals(componentProcessName)) {
15138            result = true;
15139        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15140            // Phone app and persistent apps are allowed to export singleuser providers.
15141            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15142                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15143        }
15144        if (DEBUG_MU) {
15145            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15146                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15147        }
15148        return result;
15149    }
15150
15151    /**
15152     * Checks to see if the caller is in the same app as the singleton
15153     * component, or the component is in a special app. It allows special apps
15154     * to export singleton components but prevents exporting singleton
15155     * components for regular apps.
15156     */
15157    boolean isValidSingletonCall(int callingUid, int componentUid) {
15158        int componentAppId = UserHandle.getAppId(componentUid);
15159        return UserHandle.isSameApp(callingUid, componentUid)
15160                || componentAppId == Process.SYSTEM_UID
15161                || componentAppId == Process.PHONE_UID
15162                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15163                        == PackageManager.PERMISSION_GRANTED;
15164    }
15165
15166    public int bindService(IApplicationThread caller, IBinder token,
15167            Intent service, String resolvedType,
15168            IServiceConnection connection, int flags, int userId) {
15169        enforceNotIsolatedCaller("bindService");
15170
15171        // Refuse possible leaked file descriptors
15172        if (service != null && service.hasFileDescriptors() == true) {
15173            throw new IllegalArgumentException("File descriptors passed in Intent");
15174        }
15175
15176        synchronized(this) {
15177            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15178                    connection, flags, userId);
15179        }
15180    }
15181
15182    public boolean unbindService(IServiceConnection connection) {
15183        synchronized (this) {
15184            return mServices.unbindServiceLocked(connection);
15185        }
15186    }
15187
15188    public void publishService(IBinder token, Intent intent, IBinder service) {
15189        // Refuse possible leaked file descriptors
15190        if (intent != null && intent.hasFileDescriptors() == true) {
15191            throw new IllegalArgumentException("File descriptors passed in Intent");
15192        }
15193
15194        synchronized(this) {
15195            if (!(token instanceof ServiceRecord)) {
15196                throw new IllegalArgumentException("Invalid service token");
15197            }
15198            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15199        }
15200    }
15201
15202    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15203        // Refuse possible leaked file descriptors
15204        if (intent != null && intent.hasFileDescriptors() == true) {
15205            throw new IllegalArgumentException("File descriptors passed in Intent");
15206        }
15207
15208        synchronized(this) {
15209            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15210        }
15211    }
15212
15213    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15214        synchronized(this) {
15215            if (!(token instanceof ServiceRecord)) {
15216                throw new IllegalArgumentException("Invalid service token");
15217            }
15218            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15219        }
15220    }
15221
15222    // =========================================================
15223    // BACKUP AND RESTORE
15224    // =========================================================
15225
15226    // Cause the target app to be launched if necessary and its backup agent
15227    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15228    // activity manager to announce its creation.
15229    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15230        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15231        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15232
15233        synchronized(this) {
15234            // !!! TODO: currently no check here that we're already bound
15235            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15236            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15237            synchronized (stats) {
15238                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15239            }
15240
15241            // Backup agent is now in use, its package can't be stopped.
15242            try {
15243                AppGlobals.getPackageManager().setPackageStoppedState(
15244                        app.packageName, false, UserHandle.getUserId(app.uid));
15245            } catch (RemoteException e) {
15246            } catch (IllegalArgumentException e) {
15247                Slog.w(TAG, "Failed trying to unstop package "
15248                        + app.packageName + ": " + e);
15249            }
15250
15251            BackupRecord r = new BackupRecord(ss, app, backupMode);
15252            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15253                    ? new ComponentName(app.packageName, app.backupAgentName)
15254                    : new ComponentName("android", "FullBackupAgent");
15255            // startProcessLocked() returns existing proc's record if it's already running
15256            ProcessRecord proc = startProcessLocked(app.processName, app,
15257                    false, 0, "backup", hostingName, false, false, false);
15258            if (proc == null) {
15259                Slog.e(TAG, "Unable to start backup agent process " + r);
15260                return false;
15261            }
15262
15263            r.app = proc;
15264            mBackupTarget = r;
15265            mBackupAppName = app.packageName;
15266
15267            // Try not to kill the process during backup
15268            updateOomAdjLocked(proc);
15269
15270            // If the process is already attached, schedule the creation of the backup agent now.
15271            // If it is not yet live, this will be done when it attaches to the framework.
15272            if (proc.thread != null) {
15273                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15274                try {
15275                    proc.thread.scheduleCreateBackupAgent(app,
15276                            compatibilityInfoForPackageLocked(app), backupMode);
15277                } catch (RemoteException e) {
15278                    // Will time out on the backup manager side
15279                }
15280            } else {
15281                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15282            }
15283            // Invariants: at this point, the target app process exists and the application
15284            // is either already running or in the process of coming up.  mBackupTarget and
15285            // mBackupAppName describe the app, so that when it binds back to the AM we
15286            // know that it's scheduled for a backup-agent operation.
15287        }
15288
15289        return true;
15290    }
15291
15292    @Override
15293    public void clearPendingBackup() {
15294        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15295        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15296
15297        synchronized (this) {
15298            mBackupTarget = null;
15299            mBackupAppName = null;
15300        }
15301    }
15302
15303    // A backup agent has just come up
15304    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15305        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15306                + " = " + agent);
15307
15308        synchronized(this) {
15309            if (!agentPackageName.equals(mBackupAppName)) {
15310                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15311                return;
15312            }
15313        }
15314
15315        long oldIdent = Binder.clearCallingIdentity();
15316        try {
15317            IBackupManager bm = IBackupManager.Stub.asInterface(
15318                    ServiceManager.getService(Context.BACKUP_SERVICE));
15319            bm.agentConnected(agentPackageName, agent);
15320        } catch (RemoteException e) {
15321            // can't happen; the backup manager service is local
15322        } catch (Exception e) {
15323            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15324            e.printStackTrace();
15325        } finally {
15326            Binder.restoreCallingIdentity(oldIdent);
15327        }
15328    }
15329
15330    // done with this agent
15331    public void unbindBackupAgent(ApplicationInfo appInfo) {
15332        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15333        if (appInfo == null) {
15334            Slog.w(TAG, "unbind backup agent for null app");
15335            return;
15336        }
15337
15338        synchronized(this) {
15339            try {
15340                if (mBackupAppName == null) {
15341                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15342                    return;
15343                }
15344
15345                if (!mBackupAppName.equals(appInfo.packageName)) {
15346                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15347                    return;
15348                }
15349
15350                // Not backing this app up any more; reset its OOM adjustment
15351                final ProcessRecord proc = mBackupTarget.app;
15352                updateOomAdjLocked(proc);
15353
15354                // If the app crashed during backup, 'thread' will be null here
15355                if (proc.thread != null) {
15356                    try {
15357                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15358                                compatibilityInfoForPackageLocked(appInfo));
15359                    } catch (Exception e) {
15360                        Slog.e(TAG, "Exception when unbinding backup agent:");
15361                        e.printStackTrace();
15362                    }
15363                }
15364            } finally {
15365                mBackupTarget = null;
15366                mBackupAppName = null;
15367            }
15368        }
15369    }
15370    // =========================================================
15371    // BROADCASTS
15372    // =========================================================
15373
15374    private final List getStickiesLocked(String action, IntentFilter filter,
15375            List cur, int userId) {
15376        final ContentResolver resolver = mContext.getContentResolver();
15377        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15378        if (stickies == null) {
15379            return cur;
15380        }
15381        final ArrayList<Intent> list = stickies.get(action);
15382        if (list == null) {
15383            return cur;
15384        }
15385        int N = list.size();
15386        for (int i=0; i<N; i++) {
15387            Intent intent = list.get(i);
15388            if (filter.match(resolver, intent, true, TAG) >= 0) {
15389                if (cur == null) {
15390                    cur = new ArrayList<Intent>();
15391                }
15392                cur.add(intent);
15393            }
15394        }
15395        return cur;
15396    }
15397
15398    boolean isPendingBroadcastProcessLocked(int pid) {
15399        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15400                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15401    }
15402
15403    void skipPendingBroadcastLocked(int pid) {
15404            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15405            for (BroadcastQueue queue : mBroadcastQueues) {
15406                queue.skipPendingBroadcastLocked(pid);
15407            }
15408    }
15409
15410    // The app just attached; send any pending broadcasts that it should receive
15411    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15412        boolean didSomething = false;
15413        for (BroadcastQueue queue : mBroadcastQueues) {
15414            didSomething |= queue.sendPendingBroadcastsLocked(app);
15415        }
15416        return didSomething;
15417    }
15418
15419    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15420            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15421        enforceNotIsolatedCaller("registerReceiver");
15422        int callingUid;
15423        int callingPid;
15424        synchronized(this) {
15425            ProcessRecord callerApp = null;
15426            if (caller != null) {
15427                callerApp = getRecordForAppLocked(caller);
15428                if (callerApp == null) {
15429                    throw new SecurityException(
15430                            "Unable to find app for caller " + caller
15431                            + " (pid=" + Binder.getCallingPid()
15432                            + ") when registering receiver " + receiver);
15433                }
15434                if (callerApp.info.uid != Process.SYSTEM_UID &&
15435                        !callerApp.pkgList.containsKey(callerPackage) &&
15436                        !"android".equals(callerPackage)) {
15437                    throw new SecurityException("Given caller package " + callerPackage
15438                            + " is not running in process " + callerApp);
15439                }
15440                callingUid = callerApp.info.uid;
15441                callingPid = callerApp.pid;
15442            } else {
15443                callerPackage = null;
15444                callingUid = Binder.getCallingUid();
15445                callingPid = Binder.getCallingPid();
15446            }
15447
15448            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15449                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15450
15451            List allSticky = null;
15452
15453            // Look for any matching sticky broadcasts...
15454            Iterator actions = filter.actionsIterator();
15455            if (actions != null) {
15456                while (actions.hasNext()) {
15457                    String action = (String)actions.next();
15458                    allSticky = getStickiesLocked(action, filter, allSticky,
15459                            UserHandle.USER_ALL);
15460                    allSticky = getStickiesLocked(action, filter, allSticky,
15461                            UserHandle.getUserId(callingUid));
15462                }
15463            } else {
15464                allSticky = getStickiesLocked(null, filter, allSticky,
15465                        UserHandle.USER_ALL);
15466                allSticky = getStickiesLocked(null, filter, allSticky,
15467                        UserHandle.getUserId(callingUid));
15468            }
15469
15470            // The first sticky in the list is returned directly back to
15471            // the client.
15472            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15473
15474            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15475                    + ": " + sticky);
15476
15477            if (receiver == null) {
15478                return sticky;
15479            }
15480
15481            ReceiverList rl
15482                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15483            if (rl == null) {
15484                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15485                        userId, receiver);
15486                if (rl.app != null) {
15487                    rl.app.receivers.add(rl);
15488                } else {
15489                    try {
15490                        receiver.asBinder().linkToDeath(rl, 0);
15491                    } catch (RemoteException e) {
15492                        return sticky;
15493                    }
15494                    rl.linkedToDeath = true;
15495                }
15496                mRegisteredReceivers.put(receiver.asBinder(), rl);
15497            } else if (rl.uid != callingUid) {
15498                throw new IllegalArgumentException(
15499                        "Receiver requested to register for uid " + callingUid
15500                        + " was previously registered for uid " + rl.uid);
15501            } else if (rl.pid != callingPid) {
15502                throw new IllegalArgumentException(
15503                        "Receiver requested to register for pid " + callingPid
15504                        + " was previously registered for pid " + rl.pid);
15505            } else if (rl.userId != userId) {
15506                throw new IllegalArgumentException(
15507                        "Receiver requested to register for user " + userId
15508                        + " was previously registered for user " + rl.userId);
15509            }
15510            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15511                    permission, callingUid, userId);
15512            rl.add(bf);
15513            if (!bf.debugCheck()) {
15514                Slog.w(TAG, "==> For Dynamic broadast");
15515            }
15516            mReceiverResolver.addFilter(bf);
15517
15518            // Enqueue broadcasts for all existing stickies that match
15519            // this filter.
15520            if (allSticky != null) {
15521                ArrayList receivers = new ArrayList();
15522                receivers.add(bf);
15523
15524                int N = allSticky.size();
15525                for (int i=0; i<N; i++) {
15526                    Intent intent = (Intent)allSticky.get(i);
15527                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15528                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15529                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15530                            null, null, false, true, true, -1);
15531                    queue.enqueueParallelBroadcastLocked(r);
15532                    queue.scheduleBroadcastsLocked();
15533                }
15534            }
15535
15536            return sticky;
15537        }
15538    }
15539
15540    public void unregisterReceiver(IIntentReceiver receiver) {
15541        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15542
15543        final long origId = Binder.clearCallingIdentity();
15544        try {
15545            boolean doTrim = false;
15546
15547            synchronized(this) {
15548                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15549                if (rl != null) {
15550                    if (rl.curBroadcast != null) {
15551                        BroadcastRecord r = rl.curBroadcast;
15552                        final boolean doNext = finishReceiverLocked(
15553                                receiver.asBinder(), r.resultCode, r.resultData,
15554                                r.resultExtras, r.resultAbort);
15555                        if (doNext) {
15556                            doTrim = true;
15557                            r.queue.processNextBroadcast(false);
15558                        }
15559                    }
15560
15561                    if (rl.app != null) {
15562                        rl.app.receivers.remove(rl);
15563                    }
15564                    removeReceiverLocked(rl);
15565                    if (rl.linkedToDeath) {
15566                        rl.linkedToDeath = false;
15567                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15568                    }
15569                }
15570            }
15571
15572            // If we actually concluded any broadcasts, we might now be able
15573            // to trim the recipients' apps from our working set
15574            if (doTrim) {
15575                trimApplications();
15576                return;
15577            }
15578
15579        } finally {
15580            Binder.restoreCallingIdentity(origId);
15581        }
15582    }
15583
15584    void removeReceiverLocked(ReceiverList rl) {
15585        mRegisteredReceivers.remove(rl.receiver.asBinder());
15586        int N = rl.size();
15587        for (int i=0; i<N; i++) {
15588            mReceiverResolver.removeFilter(rl.get(i));
15589        }
15590    }
15591
15592    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15593        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15594            ProcessRecord r = mLruProcesses.get(i);
15595            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15596                try {
15597                    r.thread.dispatchPackageBroadcast(cmd, packages);
15598                } catch (RemoteException ex) {
15599                }
15600            }
15601        }
15602    }
15603
15604    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15605            int callingUid, int[] users) {
15606        List<ResolveInfo> receivers = null;
15607        try {
15608            HashSet<ComponentName> singleUserReceivers = null;
15609            boolean scannedFirstReceivers = false;
15610            for (int user : users) {
15611                // Skip users that have Shell restrictions
15612                if (callingUid == Process.SHELL_UID
15613                        && getUserManagerLocked().hasUserRestriction(
15614                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15615                    continue;
15616                }
15617                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15618                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15619                if (user != 0 && newReceivers != null) {
15620                    // If this is not the primary user, we need to check for
15621                    // any receivers that should be filtered out.
15622                    for (int i=0; i<newReceivers.size(); i++) {
15623                        ResolveInfo ri = newReceivers.get(i);
15624                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15625                            newReceivers.remove(i);
15626                            i--;
15627                        }
15628                    }
15629                }
15630                if (newReceivers != null && newReceivers.size() == 0) {
15631                    newReceivers = null;
15632                }
15633                if (receivers == null) {
15634                    receivers = newReceivers;
15635                } else if (newReceivers != null) {
15636                    // We need to concatenate the additional receivers
15637                    // found with what we have do far.  This would be easy,
15638                    // but we also need to de-dup any receivers that are
15639                    // singleUser.
15640                    if (!scannedFirstReceivers) {
15641                        // Collect any single user receivers we had already retrieved.
15642                        scannedFirstReceivers = true;
15643                        for (int i=0; i<receivers.size(); i++) {
15644                            ResolveInfo ri = receivers.get(i);
15645                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15646                                ComponentName cn = new ComponentName(
15647                                        ri.activityInfo.packageName, ri.activityInfo.name);
15648                                if (singleUserReceivers == null) {
15649                                    singleUserReceivers = new HashSet<ComponentName>();
15650                                }
15651                                singleUserReceivers.add(cn);
15652                            }
15653                        }
15654                    }
15655                    // Add the new results to the existing results, tracking
15656                    // and de-dupping single user receivers.
15657                    for (int i=0; i<newReceivers.size(); i++) {
15658                        ResolveInfo ri = newReceivers.get(i);
15659                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15660                            ComponentName cn = new ComponentName(
15661                                    ri.activityInfo.packageName, ri.activityInfo.name);
15662                            if (singleUserReceivers == null) {
15663                                singleUserReceivers = new HashSet<ComponentName>();
15664                            }
15665                            if (!singleUserReceivers.contains(cn)) {
15666                                singleUserReceivers.add(cn);
15667                                receivers.add(ri);
15668                            }
15669                        } else {
15670                            receivers.add(ri);
15671                        }
15672                    }
15673                }
15674            }
15675        } catch (RemoteException ex) {
15676            // pm is in same process, this will never happen.
15677        }
15678        return receivers;
15679    }
15680
15681    private final int broadcastIntentLocked(ProcessRecord callerApp,
15682            String callerPackage, Intent intent, String resolvedType,
15683            IIntentReceiver resultTo, int resultCode, String resultData,
15684            Bundle map, String requiredPermission, int appOp,
15685            boolean ordered, boolean sticky, int callingPid, int callingUid,
15686            int userId) {
15687        intent = new Intent(intent);
15688
15689        // By default broadcasts do not go to stopped apps.
15690        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15691
15692        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15693            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15694            + " ordered=" + ordered + " userid=" + userId);
15695        if ((resultTo != null) && !ordered) {
15696            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15697        }
15698
15699        userId = handleIncomingUser(callingPid, callingUid, userId,
15700                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15701
15702        // Make sure that the user who is receiving this broadcast is running.
15703        // If not, we will just skip it. Make an exception for shutdown broadcasts
15704        // and upgrade steps.
15705
15706        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15707            if ((callingUid != Process.SYSTEM_UID
15708                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15709                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15710                Slog.w(TAG, "Skipping broadcast of " + intent
15711                        + ": user " + userId + " is stopped");
15712                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15713            }
15714        }
15715
15716        /*
15717         * Prevent non-system code (defined here to be non-persistent
15718         * processes) from sending protected broadcasts.
15719         */
15720        int callingAppId = UserHandle.getAppId(callingUid);
15721        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15722            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15723            || callingAppId == Process.NFC_UID || callingUid == 0) {
15724            // Always okay.
15725        } else if (callerApp == null || !callerApp.persistent) {
15726            try {
15727                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15728                        intent.getAction())) {
15729                    String msg = "Permission Denial: not allowed to send broadcast "
15730                            + intent.getAction() + " from pid="
15731                            + callingPid + ", uid=" + callingUid;
15732                    Slog.w(TAG, msg);
15733                    throw new SecurityException(msg);
15734                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15735                    // Special case for compatibility: we don't want apps to send this,
15736                    // but historically it has not been protected and apps may be using it
15737                    // to poke their own app widget.  So, instead of making it protected,
15738                    // just limit it to the caller.
15739                    if (callerApp == null) {
15740                        String msg = "Permission Denial: not allowed to send broadcast "
15741                                + intent.getAction() + " from unknown caller.";
15742                        Slog.w(TAG, msg);
15743                        throw new SecurityException(msg);
15744                    } else if (intent.getComponent() != null) {
15745                        // They are good enough to send to an explicit component...  verify
15746                        // it is being sent to the calling app.
15747                        if (!intent.getComponent().getPackageName().equals(
15748                                callerApp.info.packageName)) {
15749                            String msg = "Permission Denial: not allowed to send broadcast "
15750                                    + intent.getAction() + " to "
15751                                    + intent.getComponent().getPackageName() + " from "
15752                                    + callerApp.info.packageName;
15753                            Slog.w(TAG, msg);
15754                            throw new SecurityException(msg);
15755                        }
15756                    } else {
15757                        // Limit broadcast to their own package.
15758                        intent.setPackage(callerApp.info.packageName);
15759                    }
15760                }
15761            } catch (RemoteException e) {
15762                Slog.w(TAG, "Remote exception", e);
15763                return ActivityManager.BROADCAST_SUCCESS;
15764            }
15765        }
15766
15767        final String action = intent.getAction();
15768        if (action != null) {
15769            switch (action) {
15770                case Intent.ACTION_UID_REMOVED:
15771                case Intent.ACTION_PACKAGE_REMOVED:
15772                case Intent.ACTION_PACKAGE_CHANGED:
15773                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15774                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15775                    // Handle special intents: if this broadcast is from the package
15776                    // manager about a package being removed, we need to remove all of
15777                    // its activities from the history stack.
15778                    if (checkComponentPermission(
15779                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15780                            callingPid, callingUid, -1, true)
15781                            != PackageManager.PERMISSION_GRANTED) {
15782                        String msg = "Permission Denial: " + intent.getAction()
15783                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15784                                + ", uid=" + callingUid + ")"
15785                                + " requires "
15786                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15787                        Slog.w(TAG, msg);
15788                        throw new SecurityException(msg);
15789                    }
15790                    switch (action) {
15791                        case Intent.ACTION_UID_REMOVED:
15792                            final Bundle intentExtras = intent.getExtras();
15793                            final int uid = intentExtras != null
15794                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15795                            if (uid >= 0) {
15796                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15797                                synchronized (bs) {
15798                                    bs.removeUidStatsLocked(uid);
15799                                }
15800                                mAppOpsService.uidRemoved(uid);
15801                            }
15802                            break;
15803                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15804                            // If resources are unavailable just force stop all those packages
15805                            // and flush the attribute cache as well.
15806                            String list[] =
15807                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15808                            if (list != null && list.length > 0) {
15809                                for (int i = 0; i < list.length; i++) {
15810                                    forceStopPackageLocked(list[i], -1, false, true, true,
15811                                            false, false, userId, "storage unmount");
15812                                }
15813                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15814                                sendPackageBroadcastLocked(
15815                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15816                                        userId);
15817                            }
15818                            break;
15819                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15820                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15821                            break;
15822                        case Intent.ACTION_PACKAGE_REMOVED:
15823                        case Intent.ACTION_PACKAGE_CHANGED:
15824                            Uri data = intent.getData();
15825                            String ssp;
15826                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15827                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15828                                boolean fullUninstall = removed &&
15829                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15830                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15831                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15832                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15833                                            false, true, true, false, fullUninstall, userId,
15834                                            removed ? "pkg removed" : "pkg changed");
15835                                }
15836                                if (removed) {
15837                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15838                                            new String[] {ssp}, userId);
15839                                    if (fullUninstall) {
15840                                        mAppOpsService.packageRemoved(
15841                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15842
15843                                        // Remove all permissions granted from/to this package
15844                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15845
15846                                        removeTasksByPackageNameLocked(ssp, userId);
15847                                    }
15848                                } else {
15849                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15850                                    if (userId == UserHandle.USER_OWNER) {
15851                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15852                                    }
15853                                }
15854                            }
15855                            break;
15856                    }
15857                    break;
15858                case Intent.ACTION_PACKAGE_ADDED:
15859                    // Special case for adding a package: by default turn on compatibility mode.
15860                    Uri data = intent.getData();
15861                    String ssp;
15862                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15863                        final boolean replacing =
15864                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15865                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15866
15867                        if (replacing) {
15868                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15869                        }
15870                        if (userId == UserHandle.USER_OWNER) {
15871                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15872                        }
15873                    }
15874                    break;
15875                case Intent.ACTION_TIMEZONE_CHANGED:
15876                    // If this is the time zone changed action, queue up a message that will reset
15877                    // the timezone of all currently running processes. This message will get
15878                    // queued up before the broadcast happens.
15879                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15880                    break;
15881                case Intent.ACTION_TIME_CHANGED:
15882                    // If the user set the time, let all running processes know.
15883                    final int is24Hour =
15884                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15885                                    : 0;
15886                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15887                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15888                    synchronized (stats) {
15889                        stats.noteCurrentTimeChangedLocked();
15890                    }
15891                    break;
15892                case Intent.ACTION_CLEAR_DNS_CACHE:
15893                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15894                    break;
15895                case Proxy.PROXY_CHANGE_ACTION:
15896                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15897                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15898                    break;
15899            }
15900        }
15901
15902        // Add to the sticky list if requested.
15903        if (sticky) {
15904            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15905                    callingPid, callingUid)
15906                    != PackageManager.PERMISSION_GRANTED) {
15907                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15908                        + callingPid + ", uid=" + callingUid
15909                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15910                Slog.w(TAG, msg);
15911                throw new SecurityException(msg);
15912            }
15913            if (requiredPermission != null) {
15914                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15915                        + " and enforce permission " + requiredPermission);
15916                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15917            }
15918            if (intent.getComponent() != null) {
15919                throw new SecurityException(
15920                        "Sticky broadcasts can't target a specific component");
15921            }
15922            // We use userId directly here, since the "all" target is maintained
15923            // as a separate set of sticky broadcasts.
15924            if (userId != UserHandle.USER_ALL) {
15925                // But first, if this is not a broadcast to all users, then
15926                // make sure it doesn't conflict with an existing broadcast to
15927                // all users.
15928                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15929                        UserHandle.USER_ALL);
15930                if (stickies != null) {
15931                    ArrayList<Intent> list = stickies.get(intent.getAction());
15932                    if (list != null) {
15933                        int N = list.size();
15934                        int i;
15935                        for (i=0; i<N; i++) {
15936                            if (intent.filterEquals(list.get(i))) {
15937                                throw new IllegalArgumentException(
15938                                        "Sticky broadcast " + intent + " for user "
15939                                        + userId + " conflicts with existing global broadcast");
15940                            }
15941                        }
15942                    }
15943                }
15944            }
15945            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15946            if (stickies == null) {
15947                stickies = new ArrayMap<String, ArrayList<Intent>>();
15948                mStickyBroadcasts.put(userId, stickies);
15949            }
15950            ArrayList<Intent> list = stickies.get(intent.getAction());
15951            if (list == null) {
15952                list = new ArrayList<Intent>();
15953                stickies.put(intent.getAction(), list);
15954            }
15955            int N = list.size();
15956            int i;
15957            for (i=0; i<N; i++) {
15958                if (intent.filterEquals(list.get(i))) {
15959                    // This sticky already exists, replace it.
15960                    list.set(i, new Intent(intent));
15961                    break;
15962                }
15963            }
15964            if (i >= N) {
15965                list.add(new Intent(intent));
15966            }
15967        }
15968
15969        int[] users;
15970        if (userId == UserHandle.USER_ALL) {
15971            // Caller wants broadcast to go to all started users.
15972            users = mStartedUserArray;
15973        } else {
15974            // Caller wants broadcast to go to one specific user.
15975            users = new int[] {userId};
15976        }
15977
15978        // Figure out who all will receive this broadcast.
15979        List receivers = null;
15980        List<BroadcastFilter> registeredReceivers = null;
15981        // Need to resolve the intent to interested receivers...
15982        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15983                 == 0) {
15984            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15985        }
15986        if (intent.getComponent() == null) {
15987            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15988                // Query one target user at a time, excluding shell-restricted users
15989                UserManagerService ums = getUserManagerLocked();
15990                for (int i = 0; i < users.length; i++) {
15991                    if (ums.hasUserRestriction(
15992                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15993                        continue;
15994                    }
15995                    List<BroadcastFilter> registeredReceiversForUser =
15996                            mReceiverResolver.queryIntent(intent,
15997                                    resolvedType, false, users[i]);
15998                    if (registeredReceivers == null) {
15999                        registeredReceivers = registeredReceiversForUser;
16000                    } else if (registeredReceiversForUser != null) {
16001                        registeredReceivers.addAll(registeredReceiversForUser);
16002                    }
16003                }
16004            } else {
16005                registeredReceivers = mReceiverResolver.queryIntent(intent,
16006                        resolvedType, false, userId);
16007            }
16008        }
16009
16010        final boolean replacePending =
16011                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16012
16013        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16014                + " replacePending=" + replacePending);
16015
16016        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16017        if (!ordered && NR > 0) {
16018            // If we are not serializing this broadcast, then send the
16019            // registered receivers separately so they don't wait for the
16020            // components to be launched.
16021            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16022            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16023                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16024                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16025                    ordered, sticky, false, userId);
16026            if (DEBUG_BROADCAST) Slog.v(
16027                    TAG, "Enqueueing parallel broadcast " + r);
16028            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16029            if (!replaced) {
16030                queue.enqueueParallelBroadcastLocked(r);
16031                queue.scheduleBroadcastsLocked();
16032            }
16033            registeredReceivers = null;
16034            NR = 0;
16035        }
16036
16037        // Merge into one list.
16038        int ir = 0;
16039        if (receivers != null) {
16040            // A special case for PACKAGE_ADDED: do not allow the package
16041            // being added to see this broadcast.  This prevents them from
16042            // using this as a back door to get run as soon as they are
16043            // installed.  Maybe in the future we want to have a special install
16044            // broadcast or such for apps, but we'd like to deliberately make
16045            // this decision.
16046            String skipPackages[] = null;
16047            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16048                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16049                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16050                Uri data = intent.getData();
16051                if (data != null) {
16052                    String pkgName = data.getSchemeSpecificPart();
16053                    if (pkgName != null) {
16054                        skipPackages = new String[] { pkgName };
16055                    }
16056                }
16057            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16058                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16059            }
16060            if (skipPackages != null && (skipPackages.length > 0)) {
16061                for (String skipPackage : skipPackages) {
16062                    if (skipPackage != null) {
16063                        int NT = receivers.size();
16064                        for (int it=0; it<NT; it++) {
16065                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16066                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16067                                receivers.remove(it);
16068                                it--;
16069                                NT--;
16070                            }
16071                        }
16072                    }
16073                }
16074            }
16075
16076            int NT = receivers != null ? receivers.size() : 0;
16077            int it = 0;
16078            ResolveInfo curt = null;
16079            BroadcastFilter curr = null;
16080            while (it < NT && ir < NR) {
16081                if (curt == null) {
16082                    curt = (ResolveInfo)receivers.get(it);
16083                }
16084                if (curr == null) {
16085                    curr = registeredReceivers.get(ir);
16086                }
16087                if (curr.getPriority() >= curt.priority) {
16088                    // Insert this broadcast record into the final list.
16089                    receivers.add(it, curr);
16090                    ir++;
16091                    curr = null;
16092                    it++;
16093                    NT++;
16094                } else {
16095                    // Skip to the next ResolveInfo in the final list.
16096                    it++;
16097                    curt = null;
16098                }
16099            }
16100        }
16101        while (ir < NR) {
16102            if (receivers == null) {
16103                receivers = new ArrayList();
16104            }
16105            receivers.add(registeredReceivers.get(ir));
16106            ir++;
16107        }
16108
16109        if ((receivers != null && receivers.size() > 0)
16110                || resultTo != null) {
16111            BroadcastQueue queue = broadcastQueueForIntent(intent);
16112            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16113                    callerPackage, callingPid, callingUid, resolvedType,
16114                    requiredPermission, appOp, receivers, resultTo, resultCode,
16115                    resultData, map, ordered, sticky, false, userId);
16116            if (DEBUG_BROADCAST) Slog.v(
16117                    TAG, "Enqueueing ordered broadcast " + r
16118                    + ": prev had " + queue.mOrderedBroadcasts.size());
16119            if (DEBUG_BROADCAST) {
16120                int seq = r.intent.getIntExtra("seq", -1);
16121                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16122            }
16123            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16124            if (!replaced) {
16125                queue.enqueueOrderedBroadcastLocked(r);
16126                queue.scheduleBroadcastsLocked();
16127            }
16128        }
16129
16130        return ActivityManager.BROADCAST_SUCCESS;
16131    }
16132
16133    final Intent verifyBroadcastLocked(Intent intent) {
16134        // Refuse possible leaked file descriptors
16135        if (intent != null && intent.hasFileDescriptors() == true) {
16136            throw new IllegalArgumentException("File descriptors passed in Intent");
16137        }
16138
16139        int flags = intent.getFlags();
16140
16141        if (!mProcessesReady) {
16142            // if the caller really truly claims to know what they're doing, go
16143            // ahead and allow the broadcast without launching any receivers
16144            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16145                intent = new Intent(intent);
16146                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16147            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16148                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16149                        + " before boot completion");
16150                throw new IllegalStateException("Cannot broadcast before boot completed");
16151            }
16152        }
16153
16154        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16155            throw new IllegalArgumentException(
16156                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16157        }
16158
16159        return intent;
16160    }
16161
16162    public final int broadcastIntent(IApplicationThread caller,
16163            Intent intent, String resolvedType, IIntentReceiver resultTo,
16164            int resultCode, String resultData, Bundle map,
16165            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16166        enforceNotIsolatedCaller("broadcastIntent");
16167        synchronized(this) {
16168            intent = verifyBroadcastLocked(intent);
16169
16170            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16171            final int callingPid = Binder.getCallingPid();
16172            final int callingUid = Binder.getCallingUid();
16173            final long origId = Binder.clearCallingIdentity();
16174            int res = broadcastIntentLocked(callerApp,
16175                    callerApp != null ? callerApp.info.packageName : null,
16176                    intent, resolvedType, resultTo,
16177                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16178                    callingPid, callingUid, userId);
16179            Binder.restoreCallingIdentity(origId);
16180            return res;
16181        }
16182    }
16183
16184    int broadcastIntentInPackage(String packageName, int uid,
16185            Intent intent, String resolvedType, IIntentReceiver resultTo,
16186            int resultCode, String resultData, Bundle map,
16187            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16188        synchronized(this) {
16189            intent = verifyBroadcastLocked(intent);
16190
16191            final long origId = Binder.clearCallingIdentity();
16192            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16193                    resultTo, resultCode, resultData, map, requiredPermission,
16194                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16195            Binder.restoreCallingIdentity(origId);
16196            return res;
16197        }
16198    }
16199
16200    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16201        // Refuse possible leaked file descriptors
16202        if (intent != null && intent.hasFileDescriptors() == true) {
16203            throw new IllegalArgumentException("File descriptors passed in Intent");
16204        }
16205
16206        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16207                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16208
16209        synchronized(this) {
16210            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16211                    != PackageManager.PERMISSION_GRANTED) {
16212                String msg = "Permission Denial: unbroadcastIntent() from pid="
16213                        + Binder.getCallingPid()
16214                        + ", uid=" + Binder.getCallingUid()
16215                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16216                Slog.w(TAG, msg);
16217                throw new SecurityException(msg);
16218            }
16219            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16220            if (stickies != null) {
16221                ArrayList<Intent> list = stickies.get(intent.getAction());
16222                if (list != null) {
16223                    int N = list.size();
16224                    int i;
16225                    for (i=0; i<N; i++) {
16226                        if (intent.filterEquals(list.get(i))) {
16227                            list.remove(i);
16228                            break;
16229                        }
16230                    }
16231                    if (list.size() <= 0) {
16232                        stickies.remove(intent.getAction());
16233                    }
16234                }
16235                if (stickies.size() <= 0) {
16236                    mStickyBroadcasts.remove(userId);
16237                }
16238            }
16239        }
16240    }
16241
16242    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16243            String resultData, Bundle resultExtras, boolean resultAbort) {
16244        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16245        if (r == null) {
16246            Slog.w(TAG, "finishReceiver called but not found on queue");
16247            return false;
16248        }
16249
16250        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16251    }
16252
16253    void backgroundServicesFinishedLocked(int userId) {
16254        for (BroadcastQueue queue : mBroadcastQueues) {
16255            queue.backgroundServicesFinishedLocked(userId);
16256        }
16257    }
16258
16259    public void finishReceiver(IBinder who, int resultCode, String resultData,
16260            Bundle resultExtras, boolean resultAbort) {
16261        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16262
16263        // Refuse possible leaked file descriptors
16264        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16265            throw new IllegalArgumentException("File descriptors passed in Bundle");
16266        }
16267
16268        final long origId = Binder.clearCallingIdentity();
16269        try {
16270            boolean doNext = false;
16271            BroadcastRecord r;
16272
16273            synchronized(this) {
16274                r = broadcastRecordForReceiverLocked(who);
16275                if (r != null) {
16276                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16277                        resultData, resultExtras, resultAbort, true);
16278                }
16279            }
16280
16281            if (doNext) {
16282                r.queue.processNextBroadcast(false);
16283            }
16284            trimApplications();
16285        } finally {
16286            Binder.restoreCallingIdentity(origId);
16287        }
16288    }
16289
16290    // =========================================================
16291    // INSTRUMENTATION
16292    // =========================================================
16293
16294    public boolean startInstrumentation(ComponentName className,
16295            String profileFile, int flags, Bundle arguments,
16296            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16297            int userId, String abiOverride) {
16298        enforceNotIsolatedCaller("startInstrumentation");
16299        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16300                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16301        // Refuse possible leaked file descriptors
16302        if (arguments != null && arguments.hasFileDescriptors()) {
16303            throw new IllegalArgumentException("File descriptors passed in Bundle");
16304        }
16305
16306        synchronized(this) {
16307            InstrumentationInfo ii = null;
16308            ApplicationInfo ai = null;
16309            try {
16310                ii = mContext.getPackageManager().getInstrumentationInfo(
16311                    className, STOCK_PM_FLAGS);
16312                ai = AppGlobals.getPackageManager().getApplicationInfo(
16313                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16314            } catch (PackageManager.NameNotFoundException e) {
16315            } catch (RemoteException e) {
16316            }
16317            if (ii == null) {
16318                reportStartInstrumentationFailure(watcher, className,
16319                        "Unable to find instrumentation info for: " + className);
16320                return false;
16321            }
16322            if (ai == null) {
16323                reportStartInstrumentationFailure(watcher, className,
16324                        "Unable to find instrumentation target package: " + ii.targetPackage);
16325                return false;
16326            }
16327
16328            int match = mContext.getPackageManager().checkSignatures(
16329                    ii.targetPackage, ii.packageName);
16330            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16331                String msg = "Permission Denial: starting instrumentation "
16332                        + className + " from pid="
16333                        + Binder.getCallingPid()
16334                        + ", uid=" + Binder.getCallingPid()
16335                        + " not allowed because package " + ii.packageName
16336                        + " does not have a signature matching the target "
16337                        + ii.targetPackage;
16338                reportStartInstrumentationFailure(watcher, className, msg);
16339                throw new SecurityException(msg);
16340            }
16341
16342            final long origId = Binder.clearCallingIdentity();
16343            // Instrumentation can kill and relaunch even persistent processes
16344            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16345                    "start instr");
16346            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16347            app.instrumentationClass = className;
16348            app.instrumentationInfo = ai;
16349            app.instrumentationProfileFile = profileFile;
16350            app.instrumentationArguments = arguments;
16351            app.instrumentationWatcher = watcher;
16352            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16353            app.instrumentationResultClass = className;
16354            Binder.restoreCallingIdentity(origId);
16355        }
16356
16357        return true;
16358    }
16359
16360    /**
16361     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16362     * error to the logs, but if somebody is watching, send the report there too.  This enables
16363     * the "am" command to report errors with more information.
16364     *
16365     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16366     * @param cn The component name of the instrumentation.
16367     * @param report The error report.
16368     */
16369    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16370            ComponentName cn, String report) {
16371        Slog.w(TAG, report);
16372        try {
16373            if (watcher != null) {
16374                Bundle results = new Bundle();
16375                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16376                results.putString("Error", report);
16377                watcher.instrumentationStatus(cn, -1, results);
16378            }
16379        } catch (RemoteException e) {
16380            Slog.w(TAG, e);
16381        }
16382    }
16383
16384    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16385        if (app.instrumentationWatcher != null) {
16386            try {
16387                // NOTE:  IInstrumentationWatcher *must* be oneway here
16388                app.instrumentationWatcher.instrumentationFinished(
16389                    app.instrumentationClass,
16390                    resultCode,
16391                    results);
16392            } catch (RemoteException e) {
16393            }
16394        }
16395        if (app.instrumentationUiAutomationConnection != null) {
16396            try {
16397                app.instrumentationUiAutomationConnection.shutdown();
16398            } catch (RemoteException re) {
16399                /* ignore */
16400            }
16401            // Only a UiAutomation can set this flag and now that
16402            // it is finished we make sure it is reset to its default.
16403            mUserIsMonkey = false;
16404        }
16405        app.instrumentationWatcher = null;
16406        app.instrumentationUiAutomationConnection = null;
16407        app.instrumentationClass = null;
16408        app.instrumentationInfo = null;
16409        app.instrumentationProfileFile = null;
16410        app.instrumentationArguments = null;
16411
16412        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16413                "finished inst");
16414    }
16415
16416    public void finishInstrumentation(IApplicationThread target,
16417            int resultCode, Bundle results) {
16418        int userId = UserHandle.getCallingUserId();
16419        // Refuse possible leaked file descriptors
16420        if (results != null && results.hasFileDescriptors()) {
16421            throw new IllegalArgumentException("File descriptors passed in Intent");
16422        }
16423
16424        synchronized(this) {
16425            ProcessRecord app = getRecordForAppLocked(target);
16426            if (app == null) {
16427                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16428                return;
16429            }
16430            final long origId = Binder.clearCallingIdentity();
16431            finishInstrumentationLocked(app, resultCode, results);
16432            Binder.restoreCallingIdentity(origId);
16433        }
16434    }
16435
16436    // =========================================================
16437    // CONFIGURATION
16438    // =========================================================
16439
16440    public ConfigurationInfo getDeviceConfigurationInfo() {
16441        ConfigurationInfo config = new ConfigurationInfo();
16442        synchronized (this) {
16443            config.reqTouchScreen = mConfiguration.touchscreen;
16444            config.reqKeyboardType = mConfiguration.keyboard;
16445            config.reqNavigation = mConfiguration.navigation;
16446            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16447                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16448                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16449            }
16450            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16451                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16452                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16453            }
16454            config.reqGlEsVersion = GL_ES_VERSION;
16455        }
16456        return config;
16457    }
16458
16459    ActivityStack getFocusedStack() {
16460        return mStackSupervisor.getFocusedStack();
16461    }
16462
16463    public Configuration getConfiguration() {
16464        Configuration ci;
16465        synchronized(this) {
16466            ci = new Configuration(mConfiguration);
16467        }
16468        return ci;
16469    }
16470
16471    public void updatePersistentConfiguration(Configuration values) {
16472        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16473                "updateConfiguration()");
16474        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16475                "updateConfiguration()");
16476        if (values == null) {
16477            throw new NullPointerException("Configuration must not be null");
16478        }
16479
16480        synchronized(this) {
16481            final long origId = Binder.clearCallingIdentity();
16482            updateConfigurationLocked(values, null, true, false);
16483            Binder.restoreCallingIdentity(origId);
16484        }
16485    }
16486
16487    public void updateConfiguration(Configuration values) {
16488        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16489                "updateConfiguration()");
16490
16491        synchronized(this) {
16492            if (values == null && mWindowManager != null) {
16493                // sentinel: fetch the current configuration from the window manager
16494                values = mWindowManager.computeNewConfiguration();
16495            }
16496
16497            if (mWindowManager != null) {
16498                mProcessList.applyDisplaySize(mWindowManager);
16499            }
16500
16501            final long origId = Binder.clearCallingIdentity();
16502            if (values != null) {
16503                Settings.System.clearConfiguration(values);
16504            }
16505            updateConfigurationLocked(values, null, false, false);
16506            Binder.restoreCallingIdentity(origId);
16507        }
16508    }
16509
16510    /**
16511     * Do either or both things: (1) change the current configuration, and (2)
16512     * make sure the given activity is running with the (now) current
16513     * configuration.  Returns true if the activity has been left running, or
16514     * false if <var>starting</var> is being destroyed to match the new
16515     * configuration.
16516     * @param persistent TODO
16517     */
16518    boolean updateConfigurationLocked(Configuration values,
16519            ActivityRecord starting, boolean persistent, boolean initLocale) {
16520        int changes = 0;
16521
16522        if (values != null) {
16523            Configuration newConfig = new Configuration(mConfiguration);
16524            changes = newConfig.updateFrom(values);
16525            if (changes != 0) {
16526                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16527                    Slog.i(TAG, "Updating configuration to: " + values);
16528                }
16529
16530                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16531
16532                if (values.locale != null && !initLocale) {
16533                    saveLocaleLocked(values.locale,
16534                                     !values.locale.equals(mConfiguration.locale),
16535                                     values.userSetLocale);
16536                }
16537
16538                mConfigurationSeq++;
16539                if (mConfigurationSeq <= 0) {
16540                    mConfigurationSeq = 1;
16541                }
16542                newConfig.seq = mConfigurationSeq;
16543                mConfiguration = newConfig;
16544                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16545                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16546                //mUsageStatsService.noteStartConfig(newConfig);
16547
16548                final Configuration configCopy = new Configuration(mConfiguration);
16549
16550                // TODO: If our config changes, should we auto dismiss any currently
16551                // showing dialogs?
16552                mShowDialogs = shouldShowDialogs(newConfig);
16553
16554                AttributeCache ac = AttributeCache.instance();
16555                if (ac != null) {
16556                    ac.updateConfiguration(configCopy);
16557                }
16558
16559                // Make sure all resources in our process are updated
16560                // right now, so that anyone who is going to retrieve
16561                // resource values after we return will be sure to get
16562                // the new ones.  This is especially important during
16563                // boot, where the first config change needs to guarantee
16564                // all resources have that config before following boot
16565                // code is executed.
16566                mSystemThread.applyConfigurationToResources(configCopy);
16567
16568                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16569                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16570                    msg.obj = new Configuration(configCopy);
16571                    mHandler.sendMessage(msg);
16572                }
16573
16574                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16575                    ProcessRecord app = mLruProcesses.get(i);
16576                    try {
16577                        if (app.thread != null) {
16578                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16579                                    + app.processName + " new config " + mConfiguration);
16580                            app.thread.scheduleConfigurationChanged(configCopy);
16581                        }
16582                    } catch (Exception e) {
16583                    }
16584                }
16585                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16586                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16587                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16588                        | Intent.FLAG_RECEIVER_FOREGROUND);
16589                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16590                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16591                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16592                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16593                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16594                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16595                    broadcastIntentLocked(null, null, intent,
16596                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16597                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16598                }
16599            }
16600        }
16601
16602        boolean kept = true;
16603        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16604        // mainStack is null during startup.
16605        if (mainStack != null) {
16606            if (changes != 0 && starting == null) {
16607                // If the configuration changed, and the caller is not already
16608                // in the process of starting an activity, then find the top
16609                // activity to check if its configuration needs to change.
16610                starting = mainStack.topRunningActivityLocked(null);
16611            }
16612
16613            if (starting != null) {
16614                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16615                // And we need to make sure at this point that all other activities
16616                // are made visible with the correct configuration.
16617                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16618            }
16619        }
16620
16621        if (values != null && mWindowManager != null) {
16622            mWindowManager.setNewConfiguration(mConfiguration);
16623        }
16624
16625        return kept;
16626    }
16627
16628    /**
16629     * Decide based on the configuration whether we should shouw the ANR,
16630     * crash, etc dialogs.  The idea is that if there is no affordnace to
16631     * press the on-screen buttons, we shouldn't show the dialog.
16632     *
16633     * A thought: SystemUI might also want to get told about this, the Power
16634     * dialog / global actions also might want different behaviors.
16635     */
16636    private static final boolean shouldShowDialogs(Configuration config) {
16637        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16638                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16639    }
16640
16641    /**
16642     * Save the locale.  You must be inside a synchronized (this) block.
16643     */
16644    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16645        if(isDiff) {
16646            SystemProperties.set("user.language", l.getLanguage());
16647            SystemProperties.set("user.region", l.getCountry());
16648        }
16649
16650        if(isPersist) {
16651            SystemProperties.set("persist.sys.language", l.getLanguage());
16652            SystemProperties.set("persist.sys.country", l.getCountry());
16653            SystemProperties.set("persist.sys.localevar", l.getVariant());
16654
16655            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16656        }
16657    }
16658
16659    @Override
16660    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16661        synchronized (this) {
16662            ActivityRecord srec = ActivityRecord.forToken(token);
16663            if (srec.task != null && srec.task.stack != null) {
16664                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16665            }
16666        }
16667        return false;
16668    }
16669
16670    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16671            Intent resultData) {
16672
16673        synchronized (this) {
16674            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16675            if (stack != null) {
16676                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16677            }
16678            return false;
16679        }
16680    }
16681
16682    public int getLaunchedFromUid(IBinder activityToken) {
16683        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16684        if (srec == null) {
16685            return -1;
16686        }
16687        return srec.launchedFromUid;
16688    }
16689
16690    public String getLaunchedFromPackage(IBinder activityToken) {
16691        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16692        if (srec == null) {
16693            return null;
16694        }
16695        return srec.launchedFromPackage;
16696    }
16697
16698    // =========================================================
16699    // LIFETIME MANAGEMENT
16700    // =========================================================
16701
16702    // Returns which broadcast queue the app is the current [or imminent] receiver
16703    // on, or 'null' if the app is not an active broadcast recipient.
16704    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16705        BroadcastRecord r = app.curReceiver;
16706        if (r != null) {
16707            return r.queue;
16708        }
16709
16710        // It's not the current receiver, but it might be starting up to become one
16711        synchronized (this) {
16712            for (BroadcastQueue queue : mBroadcastQueues) {
16713                r = queue.mPendingBroadcast;
16714                if (r != null && r.curApp == app) {
16715                    // found it; report which queue it's in
16716                    return queue;
16717                }
16718            }
16719        }
16720
16721        return null;
16722    }
16723
16724    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16725            boolean doingAll, long now) {
16726        if (mAdjSeq == app.adjSeq) {
16727            // This adjustment has already been computed.
16728            return app.curRawAdj;
16729        }
16730
16731        if (app.thread == null) {
16732            app.adjSeq = mAdjSeq;
16733            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16734            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16735            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16736        }
16737
16738        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16739        app.adjSource = null;
16740        app.adjTarget = null;
16741        app.empty = false;
16742        app.cached = false;
16743
16744        final int activitiesSize = app.activities.size();
16745
16746        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16747            // The max adjustment doesn't allow this app to be anything
16748            // below foreground, so it is not worth doing work for it.
16749            app.adjType = "fixed";
16750            app.adjSeq = mAdjSeq;
16751            app.curRawAdj = app.maxAdj;
16752            app.foregroundActivities = false;
16753            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16754            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16755            // System processes can do UI, and when they do we want to have
16756            // them trim their memory after the user leaves the UI.  To
16757            // facilitate this, here we need to determine whether or not it
16758            // is currently showing UI.
16759            app.systemNoUi = true;
16760            if (app == TOP_APP) {
16761                app.systemNoUi = false;
16762            } else if (activitiesSize > 0) {
16763                for (int j = 0; j < activitiesSize; j++) {
16764                    final ActivityRecord r = app.activities.get(j);
16765                    if (r.visible) {
16766                        app.systemNoUi = false;
16767                    }
16768                }
16769            }
16770            if (!app.systemNoUi) {
16771                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16772            }
16773            return (app.curAdj=app.maxAdj);
16774        }
16775
16776        app.systemNoUi = false;
16777
16778        // Determine the importance of the process, starting with most
16779        // important to least, and assign an appropriate OOM adjustment.
16780        int adj;
16781        int schedGroup;
16782        int procState;
16783        boolean foregroundActivities = false;
16784        BroadcastQueue queue;
16785        if (app == TOP_APP) {
16786            // The last app on the list is the foreground app.
16787            adj = ProcessList.FOREGROUND_APP_ADJ;
16788            schedGroup = Process.THREAD_GROUP_DEFAULT;
16789            app.adjType = "top-activity";
16790            foregroundActivities = true;
16791            procState = ActivityManager.PROCESS_STATE_TOP;
16792        } else if (app.instrumentationClass != null) {
16793            // Don't want to kill running instrumentation.
16794            adj = ProcessList.FOREGROUND_APP_ADJ;
16795            schedGroup = Process.THREAD_GROUP_DEFAULT;
16796            app.adjType = "instrumentation";
16797            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16798        } else if ((queue = isReceivingBroadcast(app)) != null) {
16799            // An app that is currently receiving a broadcast also
16800            // counts as being in the foreground for OOM killer purposes.
16801            // It's placed in a sched group based on the nature of the
16802            // broadcast as reflected by which queue it's active in.
16803            adj = ProcessList.FOREGROUND_APP_ADJ;
16804            schedGroup = (queue == mFgBroadcastQueue)
16805                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16806            app.adjType = "broadcast";
16807            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16808        } else if (app.executingServices.size() > 0) {
16809            // An app that is currently executing a service callback also
16810            // counts as being in the foreground.
16811            adj = ProcessList.FOREGROUND_APP_ADJ;
16812            schedGroup = app.execServicesFg ?
16813                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16814            app.adjType = "exec-service";
16815            procState = ActivityManager.PROCESS_STATE_SERVICE;
16816            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16817        } else {
16818            // As far as we know the process is empty.  We may change our mind later.
16819            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16820            // At this point we don't actually know the adjustment.  Use the cached adj
16821            // value that the caller wants us to.
16822            adj = cachedAdj;
16823            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16824            app.cached = true;
16825            app.empty = true;
16826            app.adjType = "cch-empty";
16827        }
16828
16829        // Examine all activities if not already foreground.
16830        if (!foregroundActivities && activitiesSize > 0) {
16831            for (int j = 0; j < activitiesSize; j++) {
16832                final ActivityRecord r = app.activities.get(j);
16833                if (r.app != app) {
16834                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16835                            + app + "?!?");
16836                    continue;
16837                }
16838                if (r.visible) {
16839                    // App has a visible activity; only upgrade adjustment.
16840                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16841                        adj = ProcessList.VISIBLE_APP_ADJ;
16842                        app.adjType = "visible";
16843                    }
16844                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16845                        procState = ActivityManager.PROCESS_STATE_TOP;
16846                    }
16847                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16848                    app.cached = false;
16849                    app.empty = false;
16850                    foregroundActivities = true;
16851                    break;
16852                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16853                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16854                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16855                        app.adjType = "pausing";
16856                    }
16857                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16858                        procState = ActivityManager.PROCESS_STATE_TOP;
16859                    }
16860                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16861                    app.cached = false;
16862                    app.empty = false;
16863                    foregroundActivities = true;
16864                } else if (r.state == ActivityState.STOPPING) {
16865                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16866                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16867                        app.adjType = "stopping";
16868                    }
16869                    // For the process state, we will at this point consider the
16870                    // process to be cached.  It will be cached either as an activity
16871                    // or empty depending on whether the activity is finishing.  We do
16872                    // this so that we can treat the process as cached for purposes of
16873                    // memory trimming (determing current memory level, trim command to
16874                    // send to process) since there can be an arbitrary number of stopping
16875                    // processes and they should soon all go into the cached state.
16876                    if (!r.finishing) {
16877                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16878                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16879                        }
16880                    }
16881                    app.cached = false;
16882                    app.empty = false;
16883                    foregroundActivities = true;
16884                } else {
16885                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16886                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16887                        app.adjType = "cch-act";
16888                    }
16889                }
16890            }
16891        }
16892
16893        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16894            if (app.foregroundServices) {
16895                // The user is aware of this app, so make it visible.
16896                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16897                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16898                app.cached = false;
16899                app.adjType = "fg-service";
16900                schedGroup = Process.THREAD_GROUP_DEFAULT;
16901            } else if (app.forcingToForeground != null) {
16902                // The user is aware of this app, so make it visible.
16903                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16904                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16905                app.cached = false;
16906                app.adjType = "force-fg";
16907                app.adjSource = app.forcingToForeground;
16908                schedGroup = Process.THREAD_GROUP_DEFAULT;
16909            }
16910        }
16911
16912        if (app == mHeavyWeightProcess) {
16913            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16914                // We don't want to kill the current heavy-weight process.
16915                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16916                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16917                app.cached = false;
16918                app.adjType = "heavy";
16919            }
16920            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16921                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16922            }
16923        }
16924
16925        if (app == mHomeProcess) {
16926            if (adj > ProcessList.HOME_APP_ADJ) {
16927                // This process is hosting what we currently consider to be the
16928                // home app, so we don't want to let it go into the background.
16929                adj = ProcessList.HOME_APP_ADJ;
16930                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16931                app.cached = false;
16932                app.adjType = "home";
16933            }
16934            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16935                procState = ActivityManager.PROCESS_STATE_HOME;
16936            }
16937        }
16938
16939        if (app == mPreviousProcess && app.activities.size() > 0) {
16940            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16941                // This was the previous process that showed UI to the user.
16942                // We want to try to keep it around more aggressively, to give
16943                // a good experience around switching between two apps.
16944                adj = ProcessList.PREVIOUS_APP_ADJ;
16945                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16946                app.cached = false;
16947                app.adjType = "previous";
16948            }
16949            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16950                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16951            }
16952        }
16953
16954        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16955                + " reason=" + app.adjType);
16956
16957        // By default, we use the computed adjustment.  It may be changed if
16958        // there are applications dependent on our services or providers, but
16959        // this gives us a baseline and makes sure we don't get into an
16960        // infinite recursion.
16961        app.adjSeq = mAdjSeq;
16962        app.curRawAdj = adj;
16963        app.hasStartedServices = false;
16964
16965        if (mBackupTarget != null && app == mBackupTarget.app) {
16966            // If possible we want to avoid killing apps while they're being backed up
16967            if (adj > ProcessList.BACKUP_APP_ADJ) {
16968                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16969                adj = ProcessList.BACKUP_APP_ADJ;
16970                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16971                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16972                }
16973                app.adjType = "backup";
16974                app.cached = false;
16975            }
16976            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16977                procState = ActivityManager.PROCESS_STATE_BACKUP;
16978            }
16979        }
16980
16981        boolean mayBeTop = false;
16982
16983        for (int is = app.services.size()-1;
16984                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16985                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16986                        || procState > ActivityManager.PROCESS_STATE_TOP);
16987                is--) {
16988            ServiceRecord s = app.services.valueAt(is);
16989            if (s.startRequested) {
16990                app.hasStartedServices = true;
16991                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16992                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16993                }
16994                if (app.hasShownUi && app != mHomeProcess) {
16995                    // If this process has shown some UI, let it immediately
16996                    // go to the LRU list because it may be pretty heavy with
16997                    // UI stuff.  We'll tag it with a label just to help
16998                    // debug and understand what is going on.
16999                    if (adj > ProcessList.SERVICE_ADJ) {
17000                        app.adjType = "cch-started-ui-services";
17001                    }
17002                } else {
17003                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17004                        // This service has seen some activity within
17005                        // recent memory, so we will keep its process ahead
17006                        // of the background processes.
17007                        if (adj > ProcessList.SERVICE_ADJ) {
17008                            adj = ProcessList.SERVICE_ADJ;
17009                            app.adjType = "started-services";
17010                            app.cached = false;
17011                        }
17012                    }
17013                    // If we have let the service slide into the background
17014                    // state, still have some text describing what it is doing
17015                    // even though the service no longer has an impact.
17016                    if (adj > ProcessList.SERVICE_ADJ) {
17017                        app.adjType = "cch-started-services";
17018                    }
17019                }
17020            }
17021            for (int conni = s.connections.size()-1;
17022                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17023                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17024                            || procState > ActivityManager.PROCESS_STATE_TOP);
17025                    conni--) {
17026                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17027                for (int i = 0;
17028                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17029                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17030                                || procState > ActivityManager.PROCESS_STATE_TOP);
17031                        i++) {
17032                    // XXX should compute this based on the max of
17033                    // all connected clients.
17034                    ConnectionRecord cr = clist.get(i);
17035                    if (cr.binding.client == app) {
17036                        // Binding to ourself is not interesting.
17037                        continue;
17038                    }
17039                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17040                        ProcessRecord client = cr.binding.client;
17041                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17042                                TOP_APP, doingAll, now);
17043                        int clientProcState = client.curProcState;
17044                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17045                            // If the other app is cached for any reason, for purposes here
17046                            // we are going to consider it empty.  The specific cached state
17047                            // doesn't propagate except under certain conditions.
17048                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17049                        }
17050                        String adjType = null;
17051                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17052                            // Not doing bind OOM management, so treat
17053                            // this guy more like a started service.
17054                            if (app.hasShownUi && app != mHomeProcess) {
17055                                // If this process has shown some UI, let it immediately
17056                                // go to the LRU list because it may be pretty heavy with
17057                                // UI stuff.  We'll tag it with a label just to help
17058                                // debug and understand what is going on.
17059                                if (adj > clientAdj) {
17060                                    adjType = "cch-bound-ui-services";
17061                                }
17062                                app.cached = false;
17063                                clientAdj = adj;
17064                                clientProcState = procState;
17065                            } else {
17066                                if (now >= (s.lastActivity
17067                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17068                                    // This service has not seen activity within
17069                                    // recent memory, so allow it to drop to the
17070                                    // LRU list if there is no other reason to keep
17071                                    // it around.  We'll also tag it with a label just
17072                                    // to help debug and undertand what is going on.
17073                                    if (adj > clientAdj) {
17074                                        adjType = "cch-bound-services";
17075                                    }
17076                                    clientAdj = adj;
17077                                }
17078                            }
17079                        }
17080                        if (adj > clientAdj) {
17081                            // If this process has recently shown UI, and
17082                            // the process that is binding to it is less
17083                            // important than being visible, then we don't
17084                            // care about the binding as much as we care
17085                            // about letting this process get into the LRU
17086                            // list to be killed and restarted if needed for
17087                            // memory.
17088                            if (app.hasShownUi && app != mHomeProcess
17089                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17090                                adjType = "cch-bound-ui-services";
17091                            } else {
17092                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17093                                        |Context.BIND_IMPORTANT)) != 0) {
17094                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17095                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17096                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17097                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17098                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17099                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17100                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17101                                    adj = clientAdj;
17102                                } else {
17103                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17104                                        adj = ProcessList.VISIBLE_APP_ADJ;
17105                                    }
17106                                }
17107                                if (!client.cached) {
17108                                    app.cached = false;
17109                                }
17110                                adjType = "service";
17111                            }
17112                        }
17113                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17114                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17115                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17116                            }
17117                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17118                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17119                                    // Special handling of clients who are in the top state.
17120                                    // We *may* want to consider this process to be in the
17121                                    // top state as well, but only if there is not another
17122                                    // reason for it to be running.  Being on the top is a
17123                                    // special state, meaning you are specifically running
17124                                    // for the current top app.  If the process is already
17125                                    // running in the background for some other reason, it
17126                                    // is more important to continue considering it to be
17127                                    // in the background state.
17128                                    mayBeTop = true;
17129                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17130                                } else {
17131                                    // Special handling for above-top states (persistent
17132                                    // processes).  These should not bring the current process
17133                                    // into the top state, since they are not on top.  Instead
17134                                    // give them the best state after that.
17135                                    clientProcState =
17136                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17137                                }
17138                            }
17139                        } else {
17140                            if (clientProcState <
17141                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17142                                clientProcState =
17143                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17144                            }
17145                        }
17146                        if (procState > clientProcState) {
17147                            procState = clientProcState;
17148                        }
17149                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17150                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17151                            app.pendingUiClean = true;
17152                        }
17153                        if (adjType != null) {
17154                            app.adjType = adjType;
17155                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17156                                    .REASON_SERVICE_IN_USE;
17157                            app.adjSource = cr.binding.client;
17158                            app.adjSourceProcState = clientProcState;
17159                            app.adjTarget = s.name;
17160                        }
17161                    }
17162                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17163                        app.treatLikeActivity = true;
17164                    }
17165                    final ActivityRecord a = cr.activity;
17166                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17167                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17168                                (a.visible || a.state == ActivityState.RESUMED
17169                                 || a.state == ActivityState.PAUSING)) {
17170                            adj = ProcessList.FOREGROUND_APP_ADJ;
17171                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17172                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17173                            }
17174                            app.cached = false;
17175                            app.adjType = "service";
17176                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17177                                    .REASON_SERVICE_IN_USE;
17178                            app.adjSource = a;
17179                            app.adjSourceProcState = procState;
17180                            app.adjTarget = s.name;
17181                        }
17182                    }
17183                }
17184            }
17185        }
17186
17187        for (int provi = app.pubProviders.size()-1;
17188                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17189                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17190                        || procState > ActivityManager.PROCESS_STATE_TOP);
17191                provi--) {
17192            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17193            for (int i = cpr.connections.size()-1;
17194                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17195                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17196                            || procState > ActivityManager.PROCESS_STATE_TOP);
17197                    i--) {
17198                ContentProviderConnection conn = cpr.connections.get(i);
17199                ProcessRecord client = conn.client;
17200                if (client == app) {
17201                    // Being our own client is not interesting.
17202                    continue;
17203                }
17204                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17205                int clientProcState = client.curProcState;
17206                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17207                    // If the other app is cached for any reason, for purposes here
17208                    // we are going to consider it empty.
17209                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17210                }
17211                if (adj > clientAdj) {
17212                    if (app.hasShownUi && app != mHomeProcess
17213                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17214                        app.adjType = "cch-ui-provider";
17215                    } else {
17216                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17217                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17218                        app.adjType = "provider";
17219                    }
17220                    app.cached &= client.cached;
17221                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17222                            .REASON_PROVIDER_IN_USE;
17223                    app.adjSource = client;
17224                    app.adjSourceProcState = clientProcState;
17225                    app.adjTarget = cpr.name;
17226                }
17227                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17228                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17229                        // Special handling of clients who are in the top state.
17230                        // We *may* want to consider this process to be in the
17231                        // top state as well, but only if there is not another
17232                        // reason for it to be running.  Being on the top is a
17233                        // special state, meaning you are specifically running
17234                        // for the current top app.  If the process is already
17235                        // running in the background for some other reason, it
17236                        // is more important to continue considering it to be
17237                        // in the background state.
17238                        mayBeTop = true;
17239                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17240                    } else {
17241                        // Special handling for above-top states (persistent
17242                        // processes).  These should not bring the current process
17243                        // into the top state, since they are not on top.  Instead
17244                        // give them the best state after that.
17245                        clientProcState =
17246                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17247                    }
17248                }
17249                if (procState > clientProcState) {
17250                    procState = clientProcState;
17251                }
17252                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17253                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17254                }
17255            }
17256            // If the provider has external (non-framework) process
17257            // dependencies, ensure that its adjustment is at least
17258            // FOREGROUND_APP_ADJ.
17259            if (cpr.hasExternalProcessHandles()) {
17260                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17261                    adj = ProcessList.FOREGROUND_APP_ADJ;
17262                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17263                    app.cached = false;
17264                    app.adjType = "provider";
17265                    app.adjTarget = cpr.name;
17266                }
17267                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17268                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17269                }
17270            }
17271        }
17272
17273        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17274            // A client of one of our services or providers is in the top state.  We
17275            // *may* want to be in the top state, but not if we are already running in
17276            // the background for some other reason.  For the decision here, we are going
17277            // to pick out a few specific states that we want to remain in when a client
17278            // is top (states that tend to be longer-term) and otherwise allow it to go
17279            // to the top state.
17280            switch (procState) {
17281                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17282                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17283                case ActivityManager.PROCESS_STATE_SERVICE:
17284                    // These all are longer-term states, so pull them up to the top
17285                    // of the background states, but not all the way to the top state.
17286                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17287                    break;
17288                default:
17289                    // Otherwise, top is a better choice, so take it.
17290                    procState = ActivityManager.PROCESS_STATE_TOP;
17291                    break;
17292            }
17293        }
17294
17295        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17296            if (app.hasClientActivities) {
17297                // This is a cached process, but with client activities.  Mark it so.
17298                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17299                app.adjType = "cch-client-act";
17300            } else if (app.treatLikeActivity) {
17301                // This is a cached process, but somebody wants us to treat it like it has
17302                // an activity, okay!
17303                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17304                app.adjType = "cch-as-act";
17305            }
17306        }
17307
17308        if (adj == ProcessList.SERVICE_ADJ) {
17309            if (doingAll) {
17310                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17311                mNewNumServiceProcs++;
17312                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17313                if (!app.serviceb) {
17314                    // This service isn't far enough down on the LRU list to
17315                    // normally be a B service, but if we are low on RAM and it
17316                    // is large we want to force it down since we would prefer to
17317                    // keep launcher over it.
17318                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17319                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17320                        app.serviceHighRam = true;
17321                        app.serviceb = true;
17322                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17323                    } else {
17324                        mNewNumAServiceProcs++;
17325                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17326                    }
17327                } else {
17328                    app.serviceHighRam = false;
17329                }
17330            }
17331            if (app.serviceb) {
17332                adj = ProcessList.SERVICE_B_ADJ;
17333            }
17334        }
17335
17336        app.curRawAdj = adj;
17337
17338        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17339        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17340        if (adj > app.maxAdj) {
17341            adj = app.maxAdj;
17342            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17343                schedGroup = Process.THREAD_GROUP_DEFAULT;
17344            }
17345        }
17346
17347        // Do final modification to adj.  Everything we do between here and applying
17348        // the final setAdj must be done in this function, because we will also use
17349        // it when computing the final cached adj later.  Note that we don't need to
17350        // worry about this for max adj above, since max adj will always be used to
17351        // keep it out of the cached vaues.
17352        app.curAdj = app.modifyRawOomAdj(adj);
17353        app.curSchedGroup = schedGroup;
17354        app.curProcState = procState;
17355        app.foregroundActivities = foregroundActivities;
17356
17357        return app.curRawAdj;
17358    }
17359
17360    /**
17361     * Record new PSS sample for a process.
17362     */
17363    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17364        proc.lastPssTime = now;
17365        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17366        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17367                + ": " + pss + " lastPss=" + proc.lastPss
17368                + " state=" + ProcessList.makeProcStateString(procState));
17369        if (proc.initialIdlePss == 0) {
17370            proc.initialIdlePss = pss;
17371        }
17372        proc.lastPss = pss;
17373        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17374            proc.lastCachedPss = pss;
17375        }
17376    }
17377
17378    /**
17379     * Schedule PSS collection of a process.
17380     */
17381    void requestPssLocked(ProcessRecord proc, int procState) {
17382        if (mPendingPssProcesses.contains(proc)) {
17383            return;
17384        }
17385        if (mPendingPssProcesses.size() == 0) {
17386            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17387        }
17388        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17389        proc.pssProcState = procState;
17390        mPendingPssProcesses.add(proc);
17391    }
17392
17393    /**
17394     * Schedule PSS collection of all processes.
17395     */
17396    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17397        if (!always) {
17398            if (now < (mLastFullPssTime +
17399                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17400                return;
17401            }
17402        }
17403        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17404        mLastFullPssTime = now;
17405        mFullPssPending = true;
17406        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17407        mPendingPssProcesses.clear();
17408        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17409            ProcessRecord app = mLruProcesses.get(i);
17410            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17411                app.pssProcState = app.setProcState;
17412                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17413                        mTestPssMode, isSleeping(), now);
17414                mPendingPssProcesses.add(app);
17415            }
17416        }
17417        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17418    }
17419
17420    public void setTestPssMode(boolean enabled) {
17421        synchronized (this) {
17422            mTestPssMode = enabled;
17423            if (enabled) {
17424                // Whenever we enable the mode, we want to take a snapshot all of current
17425                // process mem use.
17426                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17427            }
17428        }
17429    }
17430
17431    /**
17432     * Ask a given process to GC right now.
17433     */
17434    final void performAppGcLocked(ProcessRecord app) {
17435        try {
17436            app.lastRequestedGc = SystemClock.uptimeMillis();
17437            if (app.thread != null) {
17438                if (app.reportLowMemory) {
17439                    app.reportLowMemory = false;
17440                    app.thread.scheduleLowMemory();
17441                } else {
17442                    app.thread.processInBackground();
17443                }
17444            }
17445        } catch (Exception e) {
17446            // whatever.
17447        }
17448    }
17449
17450    /**
17451     * Returns true if things are idle enough to perform GCs.
17452     */
17453    private final boolean canGcNowLocked() {
17454        boolean processingBroadcasts = false;
17455        for (BroadcastQueue q : mBroadcastQueues) {
17456            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17457                processingBroadcasts = true;
17458            }
17459        }
17460        return !processingBroadcasts
17461                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17462    }
17463
17464    /**
17465     * Perform GCs on all processes that are waiting for it, but only
17466     * if things are idle.
17467     */
17468    final void performAppGcsLocked() {
17469        final int N = mProcessesToGc.size();
17470        if (N <= 0) {
17471            return;
17472        }
17473        if (canGcNowLocked()) {
17474            while (mProcessesToGc.size() > 0) {
17475                ProcessRecord proc = mProcessesToGc.remove(0);
17476                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17477                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17478                            <= SystemClock.uptimeMillis()) {
17479                        // To avoid spamming the system, we will GC processes one
17480                        // at a time, waiting a few seconds between each.
17481                        performAppGcLocked(proc);
17482                        scheduleAppGcsLocked();
17483                        return;
17484                    } else {
17485                        // It hasn't been long enough since we last GCed this
17486                        // process...  put it in the list to wait for its time.
17487                        addProcessToGcListLocked(proc);
17488                        break;
17489                    }
17490                }
17491            }
17492
17493            scheduleAppGcsLocked();
17494        }
17495    }
17496
17497    /**
17498     * If all looks good, perform GCs on all processes waiting for them.
17499     */
17500    final void performAppGcsIfAppropriateLocked() {
17501        if (canGcNowLocked()) {
17502            performAppGcsLocked();
17503            return;
17504        }
17505        // Still not idle, wait some more.
17506        scheduleAppGcsLocked();
17507    }
17508
17509    /**
17510     * Schedule the execution of all pending app GCs.
17511     */
17512    final void scheduleAppGcsLocked() {
17513        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17514
17515        if (mProcessesToGc.size() > 0) {
17516            // Schedule a GC for the time to the next process.
17517            ProcessRecord proc = mProcessesToGc.get(0);
17518            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17519
17520            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17521            long now = SystemClock.uptimeMillis();
17522            if (when < (now+GC_TIMEOUT)) {
17523                when = now + GC_TIMEOUT;
17524            }
17525            mHandler.sendMessageAtTime(msg, when);
17526        }
17527    }
17528
17529    /**
17530     * Add a process to the array of processes waiting to be GCed.  Keeps the
17531     * list in sorted order by the last GC time.  The process can't already be
17532     * on the list.
17533     */
17534    final void addProcessToGcListLocked(ProcessRecord proc) {
17535        boolean added = false;
17536        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17537            if (mProcessesToGc.get(i).lastRequestedGc <
17538                    proc.lastRequestedGc) {
17539                added = true;
17540                mProcessesToGc.add(i+1, proc);
17541                break;
17542            }
17543        }
17544        if (!added) {
17545            mProcessesToGc.add(0, proc);
17546        }
17547    }
17548
17549    /**
17550     * Set up to ask a process to GC itself.  This will either do it
17551     * immediately, or put it on the list of processes to gc the next
17552     * time things are idle.
17553     */
17554    final void scheduleAppGcLocked(ProcessRecord app) {
17555        long now = SystemClock.uptimeMillis();
17556        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17557            return;
17558        }
17559        if (!mProcessesToGc.contains(app)) {
17560            addProcessToGcListLocked(app);
17561            scheduleAppGcsLocked();
17562        }
17563    }
17564
17565    final void checkExcessivePowerUsageLocked(boolean doKills) {
17566        updateCpuStatsNow();
17567
17568        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17569        boolean doWakeKills = doKills;
17570        boolean doCpuKills = doKills;
17571        if (mLastPowerCheckRealtime == 0) {
17572            doWakeKills = false;
17573        }
17574        if (mLastPowerCheckUptime == 0) {
17575            doCpuKills = false;
17576        }
17577        if (stats.isScreenOn()) {
17578            doWakeKills = false;
17579        }
17580        final long curRealtime = SystemClock.elapsedRealtime();
17581        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17582        final long curUptime = SystemClock.uptimeMillis();
17583        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17584        mLastPowerCheckRealtime = curRealtime;
17585        mLastPowerCheckUptime = curUptime;
17586        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17587            doWakeKills = false;
17588        }
17589        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17590            doCpuKills = false;
17591        }
17592        int i = mLruProcesses.size();
17593        while (i > 0) {
17594            i--;
17595            ProcessRecord app = mLruProcesses.get(i);
17596            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17597                long wtime;
17598                synchronized (stats) {
17599                    wtime = stats.getProcessWakeTime(app.info.uid,
17600                            app.pid, curRealtime);
17601                }
17602                long wtimeUsed = wtime - app.lastWakeTime;
17603                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17604                if (DEBUG_POWER) {
17605                    StringBuilder sb = new StringBuilder(128);
17606                    sb.append("Wake for ");
17607                    app.toShortString(sb);
17608                    sb.append(": over ");
17609                    TimeUtils.formatDuration(realtimeSince, sb);
17610                    sb.append(" used ");
17611                    TimeUtils.formatDuration(wtimeUsed, sb);
17612                    sb.append(" (");
17613                    sb.append((wtimeUsed*100)/realtimeSince);
17614                    sb.append("%)");
17615                    Slog.i(TAG, sb.toString());
17616                    sb.setLength(0);
17617                    sb.append("CPU for ");
17618                    app.toShortString(sb);
17619                    sb.append(": over ");
17620                    TimeUtils.formatDuration(uptimeSince, sb);
17621                    sb.append(" used ");
17622                    TimeUtils.formatDuration(cputimeUsed, sb);
17623                    sb.append(" (");
17624                    sb.append((cputimeUsed*100)/uptimeSince);
17625                    sb.append("%)");
17626                    Slog.i(TAG, sb.toString());
17627                }
17628                // If a process has held a wake lock for more
17629                // than 50% of the time during this period,
17630                // that sounds bad.  Kill!
17631                if (doWakeKills && realtimeSince > 0
17632                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17633                    synchronized (stats) {
17634                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17635                                realtimeSince, wtimeUsed);
17636                    }
17637                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17638                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17639                } else if (doCpuKills && uptimeSince > 0
17640                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17641                    synchronized (stats) {
17642                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17643                                uptimeSince, cputimeUsed);
17644                    }
17645                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17646                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17647                } else {
17648                    app.lastWakeTime = wtime;
17649                    app.lastCpuTime = app.curCpuTime;
17650                }
17651            }
17652        }
17653    }
17654
17655    private final boolean applyOomAdjLocked(ProcessRecord app,
17656            ProcessRecord TOP_APP, boolean doingAll, long now) {
17657        boolean success = true;
17658
17659        if (app.curRawAdj != app.setRawAdj) {
17660            app.setRawAdj = app.curRawAdj;
17661        }
17662
17663        int changes = 0;
17664
17665        if (app.curAdj != app.setAdj) {
17666            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17667            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17668                TAG, "Set " + app.pid + " " + app.processName +
17669                " adj " + app.curAdj + ": " + app.adjType);
17670            app.setAdj = app.curAdj;
17671        }
17672
17673        if (app.setSchedGroup != app.curSchedGroup) {
17674            app.setSchedGroup = app.curSchedGroup;
17675            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17676                    "Setting process group of " + app.processName
17677                    + " to " + app.curSchedGroup);
17678            if (app.waitingToKill != null &&
17679                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17680                app.kill(app.waitingToKill, true);
17681                success = false;
17682            } else {
17683                if (true) {
17684                    long oldId = Binder.clearCallingIdentity();
17685                    try {
17686                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17687                    } catch (Exception e) {
17688                        Slog.w(TAG, "Failed setting process group of " + app.pid
17689                                + " to " + app.curSchedGroup);
17690                        e.printStackTrace();
17691                    } finally {
17692                        Binder.restoreCallingIdentity(oldId);
17693                    }
17694                } else {
17695                    if (app.thread != null) {
17696                        try {
17697                            app.thread.setSchedulingGroup(app.curSchedGroup);
17698                        } catch (RemoteException e) {
17699                        }
17700                    }
17701                }
17702                Process.setSwappiness(app.pid,
17703                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17704            }
17705        }
17706        if (app.repForegroundActivities != app.foregroundActivities) {
17707            app.repForegroundActivities = app.foregroundActivities;
17708            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17709        }
17710        if (app.repProcState != app.curProcState) {
17711            app.repProcState = app.curProcState;
17712            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17713            if (app.thread != null) {
17714                try {
17715                    if (false) {
17716                        //RuntimeException h = new RuntimeException("here");
17717                        Slog.i(TAG, "Sending new process state " + app.repProcState
17718                                + " to " + app /*, h*/);
17719                    }
17720                    app.thread.setProcessState(app.repProcState);
17721                } catch (RemoteException e) {
17722                }
17723            }
17724        }
17725        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17726                app.setProcState)) {
17727            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17728                // Experimental code to more aggressively collect pss while
17729                // running test...  the problem is that this tends to collect
17730                // the data right when a process is transitioning between process
17731                // states, which well tend to give noisy data.
17732                long start = SystemClock.uptimeMillis();
17733                long pss = Debug.getPss(app.pid, mTmpLong, null);
17734                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17735                mPendingPssProcesses.remove(app);
17736                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17737                        + " to " + app.curProcState + ": "
17738                        + (SystemClock.uptimeMillis()-start) + "ms");
17739            }
17740            app.lastStateTime = now;
17741            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17742                    mTestPssMode, isSleeping(), now);
17743            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17744                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17745                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17746                    + (app.nextPssTime-now) + ": " + app);
17747        } else {
17748            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17749                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17750                requestPssLocked(app, app.setProcState);
17751                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17752                        mTestPssMode, isSleeping(), now);
17753            } else if (false && DEBUG_PSS) {
17754                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17755            }
17756        }
17757        if (app.setProcState != app.curProcState) {
17758            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17759                    "Proc state change of " + app.processName
17760                    + " to " + app.curProcState);
17761            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17762            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17763            if (setImportant && !curImportant) {
17764                // This app is no longer something we consider important enough to allow to
17765                // use arbitrary amounts of battery power.  Note
17766                // its current wake lock time to later know to kill it if
17767                // it is not behaving well.
17768                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17769                synchronized (stats) {
17770                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17771                            app.pid, SystemClock.elapsedRealtime());
17772                }
17773                app.lastCpuTime = app.curCpuTime;
17774
17775            }
17776            app.setProcState = app.curProcState;
17777            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17778                app.notCachedSinceIdle = false;
17779            }
17780            if (!doingAll) {
17781                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17782            } else {
17783                app.procStateChanged = true;
17784            }
17785        }
17786
17787        if (changes != 0) {
17788            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17789            int i = mPendingProcessChanges.size()-1;
17790            ProcessChangeItem item = null;
17791            while (i >= 0) {
17792                item = mPendingProcessChanges.get(i);
17793                if (item.pid == app.pid) {
17794                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17795                    break;
17796                }
17797                i--;
17798            }
17799            if (i < 0) {
17800                // No existing item in pending changes; need a new one.
17801                final int NA = mAvailProcessChanges.size();
17802                if (NA > 0) {
17803                    item = mAvailProcessChanges.remove(NA-1);
17804                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17805                } else {
17806                    item = new ProcessChangeItem();
17807                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17808                }
17809                item.changes = 0;
17810                item.pid = app.pid;
17811                item.uid = app.info.uid;
17812                if (mPendingProcessChanges.size() == 0) {
17813                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17814                            "*** Enqueueing dispatch processes changed!");
17815                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17816                }
17817                mPendingProcessChanges.add(item);
17818            }
17819            item.changes |= changes;
17820            item.processState = app.repProcState;
17821            item.foregroundActivities = app.repForegroundActivities;
17822            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17823                    + Integer.toHexString(System.identityHashCode(item))
17824                    + " " + app.toShortString() + ": changes=" + item.changes
17825                    + " procState=" + item.processState
17826                    + " foreground=" + item.foregroundActivities
17827                    + " type=" + app.adjType + " source=" + app.adjSource
17828                    + " target=" + app.adjTarget);
17829        }
17830
17831        return success;
17832    }
17833
17834    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17835        if (proc.thread != null) {
17836            if (proc.baseProcessTracker != null) {
17837                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17838            }
17839            if (proc.repProcState >= 0) {
17840                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17841                        proc.repProcState);
17842            }
17843        }
17844    }
17845
17846    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17847            ProcessRecord TOP_APP, boolean doingAll, long now) {
17848        if (app.thread == null) {
17849            return false;
17850        }
17851
17852        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17853
17854        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17855    }
17856
17857    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17858            boolean oomAdj) {
17859        if (isForeground != proc.foregroundServices) {
17860            proc.foregroundServices = isForeground;
17861            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17862                    proc.info.uid);
17863            if (isForeground) {
17864                if (curProcs == null) {
17865                    curProcs = new ArrayList<ProcessRecord>();
17866                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17867                }
17868                if (!curProcs.contains(proc)) {
17869                    curProcs.add(proc);
17870                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17871                            proc.info.packageName, proc.info.uid);
17872                }
17873            } else {
17874                if (curProcs != null) {
17875                    if (curProcs.remove(proc)) {
17876                        mBatteryStatsService.noteEvent(
17877                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17878                                proc.info.packageName, proc.info.uid);
17879                        if (curProcs.size() <= 0) {
17880                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17881                        }
17882                    }
17883                }
17884            }
17885            if (oomAdj) {
17886                updateOomAdjLocked();
17887            }
17888        }
17889    }
17890
17891    private final ActivityRecord resumedAppLocked() {
17892        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17893        String pkg;
17894        int uid;
17895        if (act != null) {
17896            pkg = act.packageName;
17897            uid = act.info.applicationInfo.uid;
17898        } else {
17899            pkg = null;
17900            uid = -1;
17901        }
17902        // Has the UID or resumed package name changed?
17903        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17904                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17905            if (mCurResumedPackage != null) {
17906                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17907                        mCurResumedPackage, mCurResumedUid);
17908            }
17909            mCurResumedPackage = pkg;
17910            mCurResumedUid = uid;
17911            if (mCurResumedPackage != null) {
17912                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17913                        mCurResumedPackage, mCurResumedUid);
17914            }
17915        }
17916        return act;
17917    }
17918
17919    final boolean updateOomAdjLocked(ProcessRecord app) {
17920        final ActivityRecord TOP_ACT = resumedAppLocked();
17921        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17922        final boolean wasCached = app.cached;
17923
17924        mAdjSeq++;
17925
17926        // This is the desired cached adjusment we want to tell it to use.
17927        // If our app is currently cached, we know it, and that is it.  Otherwise,
17928        // we don't know it yet, and it needs to now be cached we will then
17929        // need to do a complete oom adj.
17930        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17931                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17932        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17933                SystemClock.uptimeMillis());
17934        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17935            // Changed to/from cached state, so apps after it in the LRU
17936            // list may also be changed.
17937            updateOomAdjLocked();
17938        }
17939        return success;
17940    }
17941
17942    final void updateOomAdjLocked() {
17943        final ActivityRecord TOP_ACT = resumedAppLocked();
17944        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17945        final long now = SystemClock.uptimeMillis();
17946        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17947        final int N = mLruProcesses.size();
17948
17949        if (false) {
17950            RuntimeException e = new RuntimeException();
17951            e.fillInStackTrace();
17952            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17953        }
17954
17955        mAdjSeq++;
17956        mNewNumServiceProcs = 0;
17957        mNewNumAServiceProcs = 0;
17958
17959        final int emptyProcessLimit;
17960        final int cachedProcessLimit;
17961        if (mProcessLimit <= 0) {
17962            emptyProcessLimit = cachedProcessLimit = 0;
17963        } else if (mProcessLimit == 1) {
17964            emptyProcessLimit = 1;
17965            cachedProcessLimit = 0;
17966        } else {
17967            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17968            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17969        }
17970
17971        // Let's determine how many processes we have running vs.
17972        // how many slots we have for background processes; we may want
17973        // to put multiple processes in a slot of there are enough of
17974        // them.
17975        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17976                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17977        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17978        if (numEmptyProcs > cachedProcessLimit) {
17979            // If there are more empty processes than our limit on cached
17980            // processes, then use the cached process limit for the factor.
17981            // This ensures that the really old empty processes get pushed
17982            // down to the bottom, so if we are running low on memory we will
17983            // have a better chance at keeping around more cached processes
17984            // instead of a gazillion empty processes.
17985            numEmptyProcs = cachedProcessLimit;
17986        }
17987        int emptyFactor = numEmptyProcs/numSlots;
17988        if (emptyFactor < 1) emptyFactor = 1;
17989        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17990        if (cachedFactor < 1) cachedFactor = 1;
17991        int stepCached = 0;
17992        int stepEmpty = 0;
17993        int numCached = 0;
17994        int numEmpty = 0;
17995        int numTrimming = 0;
17996
17997        mNumNonCachedProcs = 0;
17998        mNumCachedHiddenProcs = 0;
17999
18000        // First update the OOM adjustment for each of the
18001        // application processes based on their current state.
18002        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18003        int nextCachedAdj = curCachedAdj+1;
18004        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18005        int nextEmptyAdj = curEmptyAdj+2;
18006        for (int i=N-1; i>=0; i--) {
18007            ProcessRecord app = mLruProcesses.get(i);
18008            if (!app.killedByAm && app.thread != null) {
18009                app.procStateChanged = false;
18010                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18011
18012                // If we haven't yet assigned the final cached adj
18013                // to the process, do that now.
18014                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18015                    switch (app.curProcState) {
18016                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18017                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18018                            // This process is a cached process holding activities...
18019                            // assign it the next cached value for that type, and then
18020                            // step that cached level.
18021                            app.curRawAdj = curCachedAdj;
18022                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18023                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18024                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18025                                    + ")");
18026                            if (curCachedAdj != nextCachedAdj) {
18027                                stepCached++;
18028                                if (stepCached >= cachedFactor) {
18029                                    stepCached = 0;
18030                                    curCachedAdj = nextCachedAdj;
18031                                    nextCachedAdj += 2;
18032                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18033                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18034                                    }
18035                                }
18036                            }
18037                            break;
18038                        default:
18039                            // For everything else, assign next empty cached process
18040                            // level and bump that up.  Note that this means that
18041                            // long-running services that have dropped down to the
18042                            // cached level will be treated as empty (since their process
18043                            // state is still as a service), which is what we want.
18044                            app.curRawAdj = curEmptyAdj;
18045                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18046                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18047                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18048                                    + ")");
18049                            if (curEmptyAdj != nextEmptyAdj) {
18050                                stepEmpty++;
18051                                if (stepEmpty >= emptyFactor) {
18052                                    stepEmpty = 0;
18053                                    curEmptyAdj = nextEmptyAdj;
18054                                    nextEmptyAdj += 2;
18055                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18056                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18057                                    }
18058                                }
18059                            }
18060                            break;
18061                    }
18062                }
18063
18064                applyOomAdjLocked(app, TOP_APP, true, now);
18065
18066                // Count the number of process types.
18067                switch (app.curProcState) {
18068                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18069                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18070                        mNumCachedHiddenProcs++;
18071                        numCached++;
18072                        if (numCached > cachedProcessLimit) {
18073                            app.kill("cached #" + numCached, true);
18074                        }
18075                        break;
18076                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18077                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18078                                && app.lastActivityTime < oldTime) {
18079                            app.kill("empty for "
18080                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18081                                    / 1000) + "s", true);
18082                        } else {
18083                            numEmpty++;
18084                            if (numEmpty > emptyProcessLimit) {
18085                                app.kill("empty #" + numEmpty, true);
18086                            }
18087                        }
18088                        break;
18089                    default:
18090                        mNumNonCachedProcs++;
18091                        break;
18092                }
18093
18094                if (app.isolated && app.services.size() <= 0) {
18095                    // If this is an isolated process, and there are no
18096                    // services running in it, then the process is no longer
18097                    // needed.  We agressively kill these because we can by
18098                    // definition not re-use the same process again, and it is
18099                    // good to avoid having whatever code was running in them
18100                    // left sitting around after no longer needed.
18101                    app.kill("isolated not needed", true);
18102                }
18103
18104                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18105                        && !app.killedByAm) {
18106                    numTrimming++;
18107                }
18108            }
18109        }
18110
18111        mNumServiceProcs = mNewNumServiceProcs;
18112
18113        // Now determine the memory trimming level of background processes.
18114        // Unfortunately we need to start at the back of the list to do this
18115        // properly.  We only do this if the number of background apps we
18116        // are managing to keep around is less than half the maximum we desire;
18117        // if we are keeping a good number around, we'll let them use whatever
18118        // memory they want.
18119        final int numCachedAndEmpty = numCached + numEmpty;
18120        int memFactor;
18121        if (numCached <= ProcessList.TRIM_CACHED_APPS
18122                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18123            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18124                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18125            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18126                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18127            } else {
18128                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18129            }
18130        } else {
18131            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18132        }
18133        // We always allow the memory level to go up (better).  We only allow it to go
18134        // down if we are in a state where that is allowed, *and* the total number of processes
18135        // has gone down since last time.
18136        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18137                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18138                + " last=" + mLastNumProcesses);
18139        if (memFactor > mLastMemoryLevel) {
18140            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18141                memFactor = mLastMemoryLevel;
18142                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18143            }
18144        }
18145        mLastMemoryLevel = memFactor;
18146        mLastNumProcesses = mLruProcesses.size();
18147        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18148        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18149        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18150            if (mLowRamStartTime == 0) {
18151                mLowRamStartTime = now;
18152            }
18153            int step = 0;
18154            int fgTrimLevel;
18155            switch (memFactor) {
18156                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18157                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18158                    break;
18159                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18160                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18161                    break;
18162                default:
18163                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18164                    break;
18165            }
18166            int factor = numTrimming/3;
18167            int minFactor = 2;
18168            if (mHomeProcess != null) minFactor++;
18169            if (mPreviousProcess != null) minFactor++;
18170            if (factor < minFactor) factor = minFactor;
18171            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18172            for (int i=N-1; i>=0; i--) {
18173                ProcessRecord app = mLruProcesses.get(i);
18174                if (allChanged || app.procStateChanged) {
18175                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18176                    app.procStateChanged = false;
18177                }
18178                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18179                        && !app.killedByAm) {
18180                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18181                        try {
18182                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18183                                    "Trimming memory of " + app.processName
18184                                    + " to " + curLevel);
18185                            app.thread.scheduleTrimMemory(curLevel);
18186                        } catch (RemoteException e) {
18187                        }
18188                        if (false) {
18189                            // For now we won't do this; our memory trimming seems
18190                            // to be good enough at this point that destroying
18191                            // activities causes more harm than good.
18192                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18193                                    && app != mHomeProcess && app != mPreviousProcess) {
18194                                // Need to do this on its own message because the stack may not
18195                                // be in a consistent state at this point.
18196                                // For these apps we will also finish their activities
18197                                // to help them free memory.
18198                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18199                            }
18200                        }
18201                    }
18202                    app.trimMemoryLevel = curLevel;
18203                    step++;
18204                    if (step >= factor) {
18205                        step = 0;
18206                        switch (curLevel) {
18207                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18208                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18209                                break;
18210                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18211                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18212                                break;
18213                        }
18214                    }
18215                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18216                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18217                            && app.thread != null) {
18218                        try {
18219                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18220                                    "Trimming memory of heavy-weight " + app.processName
18221                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18222                            app.thread.scheduleTrimMemory(
18223                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18224                        } catch (RemoteException e) {
18225                        }
18226                    }
18227                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18228                } else {
18229                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18230                            || app.systemNoUi) && app.pendingUiClean) {
18231                        // If this application is now in the background and it
18232                        // had done UI, then give it the special trim level to
18233                        // have it free UI resources.
18234                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18235                        if (app.trimMemoryLevel < level && app.thread != null) {
18236                            try {
18237                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18238                                        "Trimming memory of bg-ui " + app.processName
18239                                        + " to " + level);
18240                                app.thread.scheduleTrimMemory(level);
18241                            } catch (RemoteException e) {
18242                            }
18243                        }
18244                        app.pendingUiClean = false;
18245                    }
18246                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18247                        try {
18248                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18249                                    "Trimming memory of fg " + app.processName
18250                                    + " to " + fgTrimLevel);
18251                            app.thread.scheduleTrimMemory(fgTrimLevel);
18252                        } catch (RemoteException e) {
18253                        }
18254                    }
18255                    app.trimMemoryLevel = fgTrimLevel;
18256                }
18257            }
18258        } else {
18259            if (mLowRamStartTime != 0) {
18260                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18261                mLowRamStartTime = 0;
18262            }
18263            for (int i=N-1; i>=0; i--) {
18264                ProcessRecord app = mLruProcesses.get(i);
18265                if (allChanged || app.procStateChanged) {
18266                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18267                    app.procStateChanged = false;
18268                }
18269                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18270                        || app.systemNoUi) && app.pendingUiClean) {
18271                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18272                            && app.thread != null) {
18273                        try {
18274                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18275                                    "Trimming memory of ui hidden " + app.processName
18276                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18277                            app.thread.scheduleTrimMemory(
18278                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18279                        } catch (RemoteException e) {
18280                        }
18281                    }
18282                    app.pendingUiClean = false;
18283                }
18284                app.trimMemoryLevel = 0;
18285            }
18286        }
18287
18288        if (mAlwaysFinishActivities) {
18289            // Need to do this on its own message because the stack may not
18290            // be in a consistent state at this point.
18291            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18292        }
18293
18294        if (allChanged) {
18295            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18296        }
18297
18298        if (mProcessStats.shouldWriteNowLocked(now)) {
18299            mHandler.post(new Runnable() {
18300                @Override public void run() {
18301                    synchronized (ActivityManagerService.this) {
18302                        mProcessStats.writeStateAsyncLocked();
18303                    }
18304                }
18305            });
18306        }
18307
18308        if (DEBUG_OOM_ADJ) {
18309            if (false) {
18310                RuntimeException here = new RuntimeException("here");
18311                here.fillInStackTrace();
18312                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18313            } else {
18314                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18315            }
18316        }
18317    }
18318
18319    final void trimApplications() {
18320        synchronized (this) {
18321            int i;
18322
18323            // First remove any unused application processes whose package
18324            // has been removed.
18325            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18326                final ProcessRecord app = mRemovedProcesses.get(i);
18327                if (app.activities.size() == 0
18328                        && app.curReceiver == null && app.services.size() == 0) {
18329                    Slog.i(
18330                        TAG, "Exiting empty application process "
18331                        + app.processName + " ("
18332                        + (app.thread != null ? app.thread.asBinder() : null)
18333                        + ")\n");
18334                    if (app.pid > 0 && app.pid != MY_PID) {
18335                        app.kill("empty", false);
18336                    } else {
18337                        try {
18338                            app.thread.scheduleExit();
18339                        } catch (Exception e) {
18340                            // Ignore exceptions.
18341                        }
18342                    }
18343                    cleanUpApplicationRecordLocked(app, false, true, -1);
18344                    mRemovedProcesses.remove(i);
18345
18346                    if (app.persistent) {
18347                        addAppLocked(app.info, false, null /* ABI override */);
18348                    }
18349                }
18350            }
18351
18352            // Now update the oom adj for all processes.
18353            updateOomAdjLocked();
18354        }
18355    }
18356
18357    /** This method sends the specified signal to each of the persistent apps */
18358    public void signalPersistentProcesses(int sig) throws RemoteException {
18359        if (sig != Process.SIGNAL_USR1) {
18360            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18361        }
18362
18363        synchronized (this) {
18364            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18365                    != PackageManager.PERMISSION_GRANTED) {
18366                throw new SecurityException("Requires permission "
18367                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18368            }
18369
18370            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18371                ProcessRecord r = mLruProcesses.get(i);
18372                if (r.thread != null && r.persistent) {
18373                    Process.sendSignal(r.pid, sig);
18374                }
18375            }
18376        }
18377    }
18378
18379    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18380        if (proc == null || proc == mProfileProc) {
18381            proc = mProfileProc;
18382            profileType = mProfileType;
18383            clearProfilerLocked();
18384        }
18385        if (proc == null) {
18386            return;
18387        }
18388        try {
18389            proc.thread.profilerControl(false, null, profileType);
18390        } catch (RemoteException e) {
18391            throw new IllegalStateException("Process disappeared");
18392        }
18393    }
18394
18395    private void clearProfilerLocked() {
18396        if (mProfileFd != null) {
18397            try {
18398                mProfileFd.close();
18399            } catch (IOException e) {
18400            }
18401        }
18402        mProfileApp = null;
18403        mProfileProc = null;
18404        mProfileFile = null;
18405        mProfileType = 0;
18406        mAutoStopProfiler = false;
18407        mSamplingInterval = 0;
18408    }
18409
18410    public boolean profileControl(String process, int userId, boolean start,
18411            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18412
18413        try {
18414            synchronized (this) {
18415                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18416                // its own permission.
18417                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18418                        != PackageManager.PERMISSION_GRANTED) {
18419                    throw new SecurityException("Requires permission "
18420                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18421                }
18422
18423                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18424                    throw new IllegalArgumentException("null profile info or fd");
18425                }
18426
18427                ProcessRecord proc = null;
18428                if (process != null) {
18429                    proc = findProcessLocked(process, userId, "profileControl");
18430                }
18431
18432                if (start && (proc == null || proc.thread == null)) {
18433                    throw new IllegalArgumentException("Unknown process: " + process);
18434                }
18435
18436                if (start) {
18437                    stopProfilerLocked(null, 0);
18438                    setProfileApp(proc.info, proc.processName, profilerInfo);
18439                    mProfileProc = proc;
18440                    mProfileType = profileType;
18441                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18442                    try {
18443                        fd = fd.dup();
18444                    } catch (IOException e) {
18445                        fd = null;
18446                    }
18447                    profilerInfo.profileFd = fd;
18448                    proc.thread.profilerControl(start, profilerInfo, profileType);
18449                    fd = null;
18450                    mProfileFd = null;
18451                } else {
18452                    stopProfilerLocked(proc, profileType);
18453                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18454                        try {
18455                            profilerInfo.profileFd.close();
18456                        } catch (IOException e) {
18457                        }
18458                    }
18459                }
18460
18461                return true;
18462            }
18463        } catch (RemoteException e) {
18464            throw new IllegalStateException("Process disappeared");
18465        } finally {
18466            if (profilerInfo != null && profilerInfo.profileFd != null) {
18467                try {
18468                    profilerInfo.profileFd.close();
18469                } catch (IOException e) {
18470                }
18471            }
18472        }
18473    }
18474
18475    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18476        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18477                userId, true, ALLOW_FULL_ONLY, callName, null);
18478        ProcessRecord proc = null;
18479        try {
18480            int pid = Integer.parseInt(process);
18481            synchronized (mPidsSelfLocked) {
18482                proc = mPidsSelfLocked.get(pid);
18483            }
18484        } catch (NumberFormatException e) {
18485        }
18486
18487        if (proc == null) {
18488            ArrayMap<String, SparseArray<ProcessRecord>> all
18489                    = mProcessNames.getMap();
18490            SparseArray<ProcessRecord> procs = all.get(process);
18491            if (procs != null && procs.size() > 0) {
18492                proc = procs.valueAt(0);
18493                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18494                    for (int i=1; i<procs.size(); i++) {
18495                        ProcessRecord thisProc = procs.valueAt(i);
18496                        if (thisProc.userId == userId) {
18497                            proc = thisProc;
18498                            break;
18499                        }
18500                    }
18501                }
18502            }
18503        }
18504
18505        return proc;
18506    }
18507
18508    public boolean dumpHeap(String process, int userId, boolean managed,
18509            String path, ParcelFileDescriptor fd) throws RemoteException {
18510
18511        try {
18512            synchronized (this) {
18513                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18514                // its own permission (same as profileControl).
18515                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18516                        != PackageManager.PERMISSION_GRANTED) {
18517                    throw new SecurityException("Requires permission "
18518                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18519                }
18520
18521                if (fd == null) {
18522                    throw new IllegalArgumentException("null fd");
18523                }
18524
18525                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18526                if (proc == null || proc.thread == null) {
18527                    throw new IllegalArgumentException("Unknown process: " + process);
18528                }
18529
18530                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18531                if (!isDebuggable) {
18532                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18533                        throw new SecurityException("Process not debuggable: " + proc);
18534                    }
18535                }
18536
18537                proc.thread.dumpHeap(managed, path, fd);
18538                fd = null;
18539                return true;
18540            }
18541        } catch (RemoteException e) {
18542            throw new IllegalStateException("Process disappeared");
18543        } finally {
18544            if (fd != null) {
18545                try {
18546                    fd.close();
18547                } catch (IOException e) {
18548                }
18549            }
18550        }
18551    }
18552
18553    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18554    public void monitor() {
18555        synchronized (this) { }
18556    }
18557
18558    void onCoreSettingsChange(Bundle settings) {
18559        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18560            ProcessRecord processRecord = mLruProcesses.get(i);
18561            try {
18562                if (processRecord.thread != null) {
18563                    processRecord.thread.setCoreSettings(settings);
18564                }
18565            } catch (RemoteException re) {
18566                /* ignore */
18567            }
18568        }
18569    }
18570
18571    // Multi-user methods
18572
18573    /**
18574     * Start user, if its not already running, but don't bring it to foreground.
18575     */
18576    @Override
18577    public boolean startUserInBackground(final int userId) {
18578        return startUser(userId, /* foreground */ false);
18579    }
18580
18581    /**
18582     * Start user, if its not already running, and bring it to foreground.
18583     */
18584    boolean startUserInForeground(final int userId, Dialog dlg) {
18585        boolean result = startUser(userId, /* foreground */ true);
18586        dlg.dismiss();
18587        return result;
18588    }
18589
18590    /**
18591     * Refreshes the list of users related to the current user when either a
18592     * user switch happens or when a new related user is started in the
18593     * background.
18594     */
18595    private void updateCurrentProfileIdsLocked() {
18596        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18597                mCurrentUserId, false /* enabledOnly */);
18598        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18599        for (int i = 0; i < currentProfileIds.length; i++) {
18600            currentProfileIds[i] = profiles.get(i).id;
18601        }
18602        mCurrentProfileIds = currentProfileIds;
18603
18604        synchronized (mUserProfileGroupIdsSelfLocked) {
18605            mUserProfileGroupIdsSelfLocked.clear();
18606            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18607            for (int i = 0; i < users.size(); i++) {
18608                UserInfo user = users.get(i);
18609                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18610                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18611                }
18612            }
18613        }
18614    }
18615
18616    private Set getProfileIdsLocked(int userId) {
18617        Set userIds = new HashSet<Integer>();
18618        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18619                userId, false /* enabledOnly */);
18620        for (UserInfo user : profiles) {
18621            userIds.add(Integer.valueOf(user.id));
18622        }
18623        return userIds;
18624    }
18625
18626    @Override
18627    public boolean switchUser(final int userId) {
18628        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18629        String userName;
18630        synchronized (this) {
18631            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18632            if (userInfo == null) {
18633                Slog.w(TAG, "No user info for user #" + userId);
18634                return false;
18635            }
18636            if (userInfo.isManagedProfile()) {
18637                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18638                return false;
18639            }
18640            userName = userInfo.name;
18641            mTargetUserId = userId;
18642        }
18643        mHandler.removeMessages(START_USER_SWITCH_MSG);
18644        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18645        return true;
18646    }
18647
18648    private void showUserSwitchDialog(int userId, String userName) {
18649        // The dialog will show and then initiate the user switch by calling startUserInForeground
18650        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18651                true /* above system */);
18652        d.show();
18653    }
18654
18655    private boolean startUser(final int userId, final boolean foreground) {
18656        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18657                != PackageManager.PERMISSION_GRANTED) {
18658            String msg = "Permission Denial: switchUser() from pid="
18659                    + Binder.getCallingPid()
18660                    + ", uid=" + Binder.getCallingUid()
18661                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18662            Slog.w(TAG, msg);
18663            throw new SecurityException(msg);
18664        }
18665
18666        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18667
18668        final long ident = Binder.clearCallingIdentity();
18669        try {
18670            synchronized (this) {
18671                final int oldUserId = mCurrentUserId;
18672                if (oldUserId == userId) {
18673                    return true;
18674                }
18675
18676                mStackSupervisor.setLockTaskModeLocked(null, false);
18677
18678                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18679                if (userInfo == null) {
18680                    Slog.w(TAG, "No user info for user #" + userId);
18681                    return false;
18682                }
18683                if (foreground && userInfo.isManagedProfile()) {
18684                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18685                    return false;
18686                }
18687
18688                if (foreground) {
18689                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18690                            R.anim.screen_user_enter);
18691                }
18692
18693                boolean needStart = false;
18694
18695                // If the user we are switching to is not currently started, then
18696                // we need to start it now.
18697                if (mStartedUsers.get(userId) == null) {
18698                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18699                    updateStartedUserArrayLocked();
18700                    needStart = true;
18701                }
18702
18703                final Integer userIdInt = Integer.valueOf(userId);
18704                mUserLru.remove(userIdInt);
18705                mUserLru.add(userIdInt);
18706
18707                if (foreground) {
18708                    mCurrentUserId = userId;
18709                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18710                    updateCurrentProfileIdsLocked();
18711                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18712                    // Once the internal notion of the active user has switched, we lock the device
18713                    // with the option to show the user switcher on the keyguard.
18714                    mWindowManager.lockNow(null);
18715                } else {
18716                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18717                    updateCurrentProfileIdsLocked();
18718                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18719                    mUserLru.remove(currentUserIdInt);
18720                    mUserLru.add(currentUserIdInt);
18721                }
18722
18723                final UserStartedState uss = mStartedUsers.get(userId);
18724
18725                // Make sure user is in the started state.  If it is currently
18726                // stopping, we need to knock that off.
18727                if (uss.mState == UserStartedState.STATE_STOPPING) {
18728                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18729                    // so we can just fairly silently bring the user back from
18730                    // the almost-dead.
18731                    uss.mState = UserStartedState.STATE_RUNNING;
18732                    updateStartedUserArrayLocked();
18733                    needStart = true;
18734                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18735                    // This means ACTION_SHUTDOWN has been sent, so we will
18736                    // need to treat this as a new boot of the user.
18737                    uss.mState = UserStartedState.STATE_BOOTING;
18738                    updateStartedUserArrayLocked();
18739                    needStart = true;
18740                }
18741
18742                if (uss.mState == UserStartedState.STATE_BOOTING) {
18743                    // Booting up a new user, need to tell system services about it.
18744                    // Note that this is on the same handler as scheduling of broadcasts,
18745                    // which is important because it needs to go first.
18746                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18747                }
18748
18749                if (foreground) {
18750                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18751                            oldUserId));
18752                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18753                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18754                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18755                            oldUserId, userId, uss));
18756                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18757                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18758                }
18759
18760                if (needStart) {
18761                    // Send USER_STARTED broadcast
18762                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18763                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18764                            | Intent.FLAG_RECEIVER_FOREGROUND);
18765                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18766                    broadcastIntentLocked(null, null, intent,
18767                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18768                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18769                }
18770
18771                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18772                    if (userId != UserHandle.USER_OWNER) {
18773                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18774                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18775                        broadcastIntentLocked(null, null, intent, null,
18776                                new IIntentReceiver.Stub() {
18777                                    public void performReceive(Intent intent, int resultCode,
18778                                            String data, Bundle extras, boolean ordered,
18779                                            boolean sticky, int sendingUser) {
18780                                        onUserInitialized(uss, foreground, oldUserId, userId);
18781                                    }
18782                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18783                                true, false, MY_PID, Process.SYSTEM_UID,
18784                                userId);
18785                        uss.initializing = true;
18786                    } else {
18787                        getUserManagerLocked().makeInitialized(userInfo.id);
18788                    }
18789                }
18790
18791                if (foreground) {
18792                    if (!uss.initializing) {
18793                        moveUserToForeground(uss, oldUserId, userId);
18794                    }
18795                } else {
18796                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18797                }
18798
18799                if (needStart) {
18800                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18801                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18802                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18803                    broadcastIntentLocked(null, null, intent,
18804                            null, new IIntentReceiver.Stub() {
18805                                @Override
18806                                public void performReceive(Intent intent, int resultCode, String data,
18807                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18808                                        throws RemoteException {
18809                                }
18810                            }, 0, null, null,
18811                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18812                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18813                }
18814            }
18815        } finally {
18816            Binder.restoreCallingIdentity(ident);
18817        }
18818
18819        return true;
18820    }
18821
18822    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18823        long ident = Binder.clearCallingIdentity();
18824        try {
18825            Intent intent;
18826            if (oldUserId >= 0) {
18827                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18828                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18829                int count = profiles.size();
18830                for (int i = 0; i < count; i++) {
18831                    int profileUserId = profiles.get(i).id;
18832                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18833                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18834                            | Intent.FLAG_RECEIVER_FOREGROUND);
18835                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18836                    broadcastIntentLocked(null, null, intent,
18837                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18838                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18839                }
18840            }
18841            if (newUserId >= 0) {
18842                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18843                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18844                int count = profiles.size();
18845                for (int i = 0; i < count; i++) {
18846                    int profileUserId = profiles.get(i).id;
18847                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18848                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18849                            | Intent.FLAG_RECEIVER_FOREGROUND);
18850                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18851                    broadcastIntentLocked(null, null, intent,
18852                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18853                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18854                }
18855                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18856                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18857                        | Intent.FLAG_RECEIVER_FOREGROUND);
18858                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18859                broadcastIntentLocked(null, null, intent,
18860                        null, null, 0, null, null,
18861                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18862                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18863            }
18864        } finally {
18865            Binder.restoreCallingIdentity(ident);
18866        }
18867    }
18868
18869    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18870            final int newUserId) {
18871        final int N = mUserSwitchObservers.beginBroadcast();
18872        if (N > 0) {
18873            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18874                int mCount = 0;
18875                @Override
18876                public void sendResult(Bundle data) throws RemoteException {
18877                    synchronized (ActivityManagerService.this) {
18878                        if (mCurUserSwitchCallback == this) {
18879                            mCount++;
18880                            if (mCount == N) {
18881                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18882                            }
18883                        }
18884                    }
18885                }
18886            };
18887            synchronized (this) {
18888                uss.switching = true;
18889                mCurUserSwitchCallback = callback;
18890            }
18891            for (int i=0; i<N; i++) {
18892                try {
18893                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18894                            newUserId, callback);
18895                } catch (RemoteException e) {
18896                }
18897            }
18898        } else {
18899            synchronized (this) {
18900                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18901            }
18902        }
18903        mUserSwitchObservers.finishBroadcast();
18904    }
18905
18906    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18907        synchronized (this) {
18908            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18909            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18910        }
18911    }
18912
18913    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18914        mCurUserSwitchCallback = null;
18915        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18916        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18917                oldUserId, newUserId, uss));
18918    }
18919
18920    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18921        synchronized (this) {
18922            if (foreground) {
18923                moveUserToForeground(uss, oldUserId, newUserId);
18924            }
18925        }
18926
18927        completeSwitchAndInitalize(uss, newUserId, true, false);
18928    }
18929
18930    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18931        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18932        if (homeInFront) {
18933            startHomeActivityLocked(newUserId);
18934        } else {
18935            mStackSupervisor.resumeTopActivitiesLocked();
18936        }
18937        EventLogTags.writeAmSwitchUser(newUserId);
18938        getUserManagerLocked().userForeground(newUserId);
18939        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18940    }
18941
18942    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18943        completeSwitchAndInitalize(uss, newUserId, false, true);
18944    }
18945
18946    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18947            boolean clearInitializing, boolean clearSwitching) {
18948        boolean unfrozen = false;
18949        synchronized (this) {
18950            if (clearInitializing) {
18951                uss.initializing = false;
18952                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18953            }
18954            if (clearSwitching) {
18955                uss.switching = false;
18956            }
18957            if (!uss.switching && !uss.initializing) {
18958                mWindowManager.stopFreezingScreen();
18959                unfrozen = true;
18960            }
18961        }
18962        if (unfrozen) {
18963            final int N = mUserSwitchObservers.beginBroadcast();
18964            for (int i=0; i<N; i++) {
18965                try {
18966                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18967                } catch (RemoteException e) {
18968                }
18969            }
18970            mUserSwitchObservers.finishBroadcast();
18971        }
18972    }
18973
18974    void scheduleStartProfilesLocked() {
18975        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18976            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18977                    DateUtils.SECOND_IN_MILLIS);
18978        }
18979    }
18980
18981    void startProfilesLocked() {
18982        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18983        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18984                mCurrentUserId, false /* enabledOnly */);
18985        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18986        for (UserInfo user : profiles) {
18987            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18988                    && user.id != mCurrentUserId) {
18989                toStart.add(user);
18990            }
18991        }
18992        final int n = toStart.size();
18993        int i = 0;
18994        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18995            startUserInBackground(toStart.get(i).id);
18996        }
18997        if (i < n) {
18998            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18999        }
19000    }
19001
19002    void finishUserBoot(UserStartedState uss) {
19003        synchronized (this) {
19004            if (uss.mState == UserStartedState.STATE_BOOTING
19005                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19006                uss.mState = UserStartedState.STATE_RUNNING;
19007                final int userId = uss.mHandle.getIdentifier();
19008                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19009                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19010                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19011                broadcastIntentLocked(null, null, intent,
19012                        null, null, 0, null, null,
19013                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19014                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19015            }
19016        }
19017    }
19018
19019    void finishUserSwitch(UserStartedState uss) {
19020        synchronized (this) {
19021            finishUserBoot(uss);
19022
19023            startProfilesLocked();
19024
19025            int num = mUserLru.size();
19026            int i = 0;
19027            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19028                Integer oldUserId = mUserLru.get(i);
19029                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19030                if (oldUss == null) {
19031                    // Shouldn't happen, but be sane if it does.
19032                    mUserLru.remove(i);
19033                    num--;
19034                    continue;
19035                }
19036                if (oldUss.mState == UserStartedState.STATE_STOPPING
19037                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19038                    // This user is already stopping, doesn't count.
19039                    num--;
19040                    i++;
19041                    continue;
19042                }
19043                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19044                    // Owner and current can't be stopped, but count as running.
19045                    i++;
19046                    continue;
19047                }
19048                // This is a user to be stopped.
19049                stopUserLocked(oldUserId, null);
19050                num--;
19051                i++;
19052            }
19053        }
19054    }
19055
19056    @Override
19057    public int stopUser(final int userId, final IStopUserCallback callback) {
19058        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19059                != PackageManager.PERMISSION_GRANTED) {
19060            String msg = "Permission Denial: switchUser() from pid="
19061                    + Binder.getCallingPid()
19062                    + ", uid=" + Binder.getCallingUid()
19063                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19064            Slog.w(TAG, msg);
19065            throw new SecurityException(msg);
19066        }
19067        if (userId <= 0) {
19068            throw new IllegalArgumentException("Can't stop primary user " + userId);
19069        }
19070        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19071        synchronized (this) {
19072            return stopUserLocked(userId, callback);
19073        }
19074    }
19075
19076    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19077        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19078        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19079            return ActivityManager.USER_OP_IS_CURRENT;
19080        }
19081
19082        final UserStartedState uss = mStartedUsers.get(userId);
19083        if (uss == null) {
19084            // User is not started, nothing to do...  but we do need to
19085            // callback if requested.
19086            if (callback != null) {
19087                mHandler.post(new Runnable() {
19088                    @Override
19089                    public void run() {
19090                        try {
19091                            callback.userStopped(userId);
19092                        } catch (RemoteException e) {
19093                        }
19094                    }
19095                });
19096            }
19097            return ActivityManager.USER_OP_SUCCESS;
19098        }
19099
19100        if (callback != null) {
19101            uss.mStopCallbacks.add(callback);
19102        }
19103
19104        if (uss.mState != UserStartedState.STATE_STOPPING
19105                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19106            uss.mState = UserStartedState.STATE_STOPPING;
19107            updateStartedUserArrayLocked();
19108
19109            long ident = Binder.clearCallingIdentity();
19110            try {
19111                // We are going to broadcast ACTION_USER_STOPPING and then
19112                // once that is done send a final ACTION_SHUTDOWN and then
19113                // stop the user.
19114                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19115                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19116                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19117                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19118                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19119                // This is the result receiver for the final shutdown broadcast.
19120                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19121                    @Override
19122                    public void performReceive(Intent intent, int resultCode, String data,
19123                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19124                        finishUserStop(uss);
19125                    }
19126                };
19127                // This is the result receiver for the initial stopping broadcast.
19128                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19129                    @Override
19130                    public void performReceive(Intent intent, int resultCode, String data,
19131                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19132                        // On to the next.
19133                        synchronized (ActivityManagerService.this) {
19134                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19135                                // Whoops, we are being started back up.  Abort, abort!
19136                                return;
19137                            }
19138                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19139                        }
19140                        mBatteryStatsService.noteEvent(
19141                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19142                                Integer.toString(userId), userId);
19143                        mSystemServiceManager.stopUser(userId);
19144                        broadcastIntentLocked(null, null, shutdownIntent,
19145                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19146                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19147                    }
19148                };
19149                // Kick things off.
19150                broadcastIntentLocked(null, null, stoppingIntent,
19151                        null, stoppingReceiver, 0, null, null,
19152                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19153                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19154            } finally {
19155                Binder.restoreCallingIdentity(ident);
19156            }
19157        }
19158
19159        return ActivityManager.USER_OP_SUCCESS;
19160    }
19161
19162    void finishUserStop(UserStartedState uss) {
19163        final int userId = uss.mHandle.getIdentifier();
19164        boolean stopped;
19165        ArrayList<IStopUserCallback> callbacks;
19166        synchronized (this) {
19167            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19168            if (mStartedUsers.get(userId) != uss) {
19169                stopped = false;
19170            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19171                stopped = false;
19172            } else {
19173                stopped = true;
19174                // User can no longer run.
19175                mStartedUsers.remove(userId);
19176                mUserLru.remove(Integer.valueOf(userId));
19177                updateStartedUserArrayLocked();
19178
19179                // Clean up all state and processes associated with the user.
19180                // Kill all the processes for the user.
19181                forceStopUserLocked(userId, "finish user");
19182            }
19183
19184            // Explicitly remove the old information in mRecentTasks.
19185            removeRecentTasksForUserLocked(userId);
19186        }
19187
19188        for (int i=0; i<callbacks.size(); i++) {
19189            try {
19190                if (stopped) callbacks.get(i).userStopped(userId);
19191                else callbacks.get(i).userStopAborted(userId);
19192            } catch (RemoteException e) {
19193            }
19194        }
19195
19196        if (stopped) {
19197            mSystemServiceManager.cleanupUser(userId);
19198            synchronized (this) {
19199                mStackSupervisor.removeUserLocked(userId);
19200            }
19201        }
19202    }
19203
19204    @Override
19205    public UserInfo getCurrentUser() {
19206        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19207                != PackageManager.PERMISSION_GRANTED) && (
19208                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19209                != PackageManager.PERMISSION_GRANTED)) {
19210            String msg = "Permission Denial: getCurrentUser() from pid="
19211                    + Binder.getCallingPid()
19212                    + ", uid=" + Binder.getCallingUid()
19213                    + " requires " + INTERACT_ACROSS_USERS;
19214            Slog.w(TAG, msg);
19215            throw new SecurityException(msg);
19216        }
19217        synchronized (this) {
19218            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19219            return getUserManagerLocked().getUserInfo(userId);
19220        }
19221    }
19222
19223    int getCurrentUserIdLocked() {
19224        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19225    }
19226
19227    @Override
19228    public boolean isUserRunning(int userId, boolean orStopped) {
19229        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19230                != PackageManager.PERMISSION_GRANTED) {
19231            String msg = "Permission Denial: isUserRunning() from pid="
19232                    + Binder.getCallingPid()
19233                    + ", uid=" + Binder.getCallingUid()
19234                    + " requires " + INTERACT_ACROSS_USERS;
19235            Slog.w(TAG, msg);
19236            throw new SecurityException(msg);
19237        }
19238        synchronized (this) {
19239            return isUserRunningLocked(userId, orStopped);
19240        }
19241    }
19242
19243    boolean isUserRunningLocked(int userId, boolean orStopped) {
19244        UserStartedState state = mStartedUsers.get(userId);
19245        if (state == null) {
19246            return false;
19247        }
19248        if (orStopped) {
19249            return true;
19250        }
19251        return state.mState != UserStartedState.STATE_STOPPING
19252                && state.mState != UserStartedState.STATE_SHUTDOWN;
19253    }
19254
19255    @Override
19256    public int[] getRunningUserIds() {
19257        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19258                != PackageManager.PERMISSION_GRANTED) {
19259            String msg = "Permission Denial: isUserRunning() from pid="
19260                    + Binder.getCallingPid()
19261                    + ", uid=" + Binder.getCallingUid()
19262                    + " requires " + INTERACT_ACROSS_USERS;
19263            Slog.w(TAG, msg);
19264            throw new SecurityException(msg);
19265        }
19266        synchronized (this) {
19267            return mStartedUserArray;
19268        }
19269    }
19270
19271    private void updateStartedUserArrayLocked() {
19272        int num = 0;
19273        for (int i=0; i<mStartedUsers.size();  i++) {
19274            UserStartedState uss = mStartedUsers.valueAt(i);
19275            // This list does not include stopping users.
19276            if (uss.mState != UserStartedState.STATE_STOPPING
19277                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19278                num++;
19279            }
19280        }
19281        mStartedUserArray = new int[num];
19282        num = 0;
19283        for (int i=0; i<mStartedUsers.size();  i++) {
19284            UserStartedState uss = mStartedUsers.valueAt(i);
19285            if (uss.mState != UserStartedState.STATE_STOPPING
19286                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19287                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19288                num++;
19289            }
19290        }
19291    }
19292
19293    @Override
19294    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19295        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19296                != PackageManager.PERMISSION_GRANTED) {
19297            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19298                    + Binder.getCallingPid()
19299                    + ", uid=" + Binder.getCallingUid()
19300                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19301            Slog.w(TAG, msg);
19302            throw new SecurityException(msg);
19303        }
19304
19305        mUserSwitchObservers.register(observer);
19306    }
19307
19308    @Override
19309    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19310        mUserSwitchObservers.unregister(observer);
19311    }
19312
19313    private boolean userExists(int userId) {
19314        if (userId == 0) {
19315            return true;
19316        }
19317        UserManagerService ums = getUserManagerLocked();
19318        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19319    }
19320
19321    int[] getUsersLocked() {
19322        UserManagerService ums = getUserManagerLocked();
19323        return ums != null ? ums.getUserIds() : new int[] { 0 };
19324    }
19325
19326    UserManagerService getUserManagerLocked() {
19327        if (mUserManager == null) {
19328            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19329            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19330        }
19331        return mUserManager;
19332    }
19333
19334    private int applyUserId(int uid, int userId) {
19335        return UserHandle.getUid(userId, uid);
19336    }
19337
19338    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19339        if (info == null) return null;
19340        ApplicationInfo newInfo = new ApplicationInfo(info);
19341        newInfo.uid = applyUserId(info.uid, userId);
19342        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19343                + info.packageName;
19344        return newInfo;
19345    }
19346
19347    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19348        if (aInfo == null
19349                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19350            return aInfo;
19351        }
19352
19353        ActivityInfo info = new ActivityInfo(aInfo);
19354        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19355        return info;
19356    }
19357
19358    private final class LocalService extends ActivityManagerInternal {
19359        @Override
19360        public void onWakefulnessChanged(int wakefulness) {
19361            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19362        }
19363
19364        @Override
19365        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19366                String processName, String abiOverride, int uid, Runnable crashHandler) {
19367            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19368                    processName, abiOverride, uid, crashHandler);
19369        }
19370    }
19371
19372    /**
19373     * An implementation of IAppTask, that allows an app to manage its own tasks via
19374     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19375     * only the process that calls getAppTasks() can call the AppTask methods.
19376     */
19377    class AppTaskImpl extends IAppTask.Stub {
19378        private int mTaskId;
19379        private int mCallingUid;
19380
19381        public AppTaskImpl(int taskId, int callingUid) {
19382            mTaskId = taskId;
19383            mCallingUid = callingUid;
19384        }
19385
19386        private void checkCaller() {
19387            if (mCallingUid != Binder.getCallingUid()) {
19388                throw new SecurityException("Caller " + mCallingUid
19389                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19390            }
19391        }
19392
19393        @Override
19394        public void finishAndRemoveTask() {
19395            checkCaller();
19396
19397            synchronized (ActivityManagerService.this) {
19398                long origId = Binder.clearCallingIdentity();
19399                try {
19400                    if (!removeTaskByIdLocked(mTaskId, false)) {
19401                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19402                    }
19403                } finally {
19404                    Binder.restoreCallingIdentity(origId);
19405                }
19406            }
19407        }
19408
19409        @Override
19410        public ActivityManager.RecentTaskInfo getTaskInfo() {
19411            checkCaller();
19412
19413            synchronized (ActivityManagerService.this) {
19414                long origId = Binder.clearCallingIdentity();
19415                try {
19416                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19417                    if (tr == null) {
19418                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19419                    }
19420                    return createRecentTaskInfoFromTaskRecord(tr);
19421                } finally {
19422                    Binder.restoreCallingIdentity(origId);
19423                }
19424            }
19425        }
19426
19427        @Override
19428        public void moveToFront() {
19429            checkCaller();
19430
19431            final TaskRecord tr;
19432            synchronized (ActivityManagerService.this) {
19433                tr = recentTaskForIdLocked(mTaskId);
19434                if (tr == null) {
19435                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19436                }
19437                if (tr.getRootActivity() != null) {
19438                    moveTaskToFrontLocked(tr.taskId, 0, null);
19439                    return;
19440                }
19441            }
19442
19443            startActivityFromRecentsInner(tr.taskId, null);
19444        }
19445
19446        @Override
19447        public int startActivity(IBinder whoThread, String callingPackage,
19448                Intent intent, String resolvedType, Bundle options) {
19449            checkCaller();
19450
19451            int callingUser = UserHandle.getCallingUserId();
19452            TaskRecord tr;
19453            IApplicationThread appThread;
19454            synchronized (ActivityManagerService.this) {
19455                tr = recentTaskForIdLocked(mTaskId);
19456                if (tr == null) {
19457                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19458                }
19459                appThread = ApplicationThreadNative.asInterface(whoThread);
19460                if (appThread == null) {
19461                    throw new IllegalArgumentException("Bad app thread " + appThread);
19462                }
19463            }
19464            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19465                    resolvedType, null, null, null, null, 0, 0, null, null,
19466                    null, options, callingUser, null, tr);
19467        }
19468
19469        @Override
19470        public void setExcludeFromRecents(boolean exclude) {
19471            checkCaller();
19472
19473            synchronized (ActivityManagerService.this) {
19474                long origId = Binder.clearCallingIdentity();
19475                try {
19476                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19477                    if (tr == null) {
19478                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19479                    }
19480                    Intent intent = tr.getBaseIntent();
19481                    if (exclude) {
19482                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19483                    } else {
19484                        intent.setFlags(intent.getFlags()
19485                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19486                    }
19487                } finally {
19488                    Binder.restoreCallingIdentity(origId);
19489                }
19490            }
19491        }
19492    }
19493}
19494