ActivityManagerService.java revision 7de0535701351d76b634ab18577269e8130749ea
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                                && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1846                                        < SystemClock.uptimeMillis()) {
1847                            pid = proc.pid;
1848                        } else {
1849                            proc = null;
1850                            pid = 0;
1851                        }
1852                    }
1853                    if (proc != null) {
1854                        long pss = Debug.getPss(pid, tmp, null);
1855                        synchronized (ActivityManagerService.this) {
1856                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1857                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1858                                num++;
1859                                recordPssSample(proc, procState, pss, tmp[0],
1860                                        SystemClock.uptimeMillis());
1861                            }
1862                        }
1863                    }
1864                } while (true);
1865            }
1866            }
1867        }
1868    };
1869
1870    public void setSystemProcess() {
1871        try {
1872            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1873            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1874            ServiceManager.addService("meminfo", new MemBinder(this));
1875            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1876            ServiceManager.addService("dbinfo", new DbBinder(this));
1877            if (MONITOR_CPU_USAGE) {
1878                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1879            }
1880            ServiceManager.addService("permission", new PermissionController(this));
1881
1882            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1883                    "android", STOCK_PM_FLAGS);
1884            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1885
1886            synchronized (this) {
1887                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1888                app.persistent = true;
1889                app.pid = MY_PID;
1890                app.maxAdj = ProcessList.SYSTEM_ADJ;
1891                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1892                mProcessNames.put(app.processName, app.uid, app);
1893                synchronized (mPidsSelfLocked) {
1894                    mPidsSelfLocked.put(app.pid, app);
1895                }
1896                updateLruProcessLocked(app, false, null);
1897                updateOomAdjLocked();
1898            }
1899        } catch (PackageManager.NameNotFoundException e) {
1900            throw new RuntimeException(
1901                    "Unable to find android system package", e);
1902        }
1903    }
1904
1905    public void setWindowManager(WindowManagerService wm) {
1906        mWindowManager = wm;
1907        mStackSupervisor.setWindowManager(wm);
1908    }
1909
1910    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1911        mUsageStatsService = usageStatsManager;
1912    }
1913
1914    public void startObservingNativeCrashes() {
1915        final NativeCrashListener ncl = new NativeCrashListener(this);
1916        ncl.start();
1917    }
1918
1919    public IAppOpsService getAppOpsService() {
1920        return mAppOpsService;
1921    }
1922
1923    static class MemBinder extends Binder {
1924        ActivityManagerService mActivityManagerService;
1925        MemBinder(ActivityManagerService activityManagerService) {
1926            mActivityManagerService = activityManagerService;
1927        }
1928
1929        @Override
1930        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1931            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1932                    != PackageManager.PERMISSION_GRANTED) {
1933                pw.println("Permission Denial: can't dump meminfo from from pid="
1934                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1935                        + " without permission " + android.Manifest.permission.DUMP);
1936                return;
1937            }
1938
1939            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1940        }
1941    }
1942
1943    static class GraphicsBinder extends Binder {
1944        ActivityManagerService mActivityManagerService;
1945        GraphicsBinder(ActivityManagerService activityManagerService) {
1946            mActivityManagerService = activityManagerService;
1947        }
1948
1949        @Override
1950        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1951            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1952                    != PackageManager.PERMISSION_GRANTED) {
1953                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1954                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1955                        + " without permission " + android.Manifest.permission.DUMP);
1956                return;
1957            }
1958
1959            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1960        }
1961    }
1962
1963    static class DbBinder extends Binder {
1964        ActivityManagerService mActivityManagerService;
1965        DbBinder(ActivityManagerService activityManagerService) {
1966            mActivityManagerService = activityManagerService;
1967        }
1968
1969        @Override
1970        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1971            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1972                    != PackageManager.PERMISSION_GRANTED) {
1973                pw.println("Permission Denial: can't dump dbinfo from from pid="
1974                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1975                        + " without permission " + android.Manifest.permission.DUMP);
1976                return;
1977            }
1978
1979            mActivityManagerService.dumpDbInfo(fd, pw, args);
1980        }
1981    }
1982
1983    static class CpuBinder extends Binder {
1984        ActivityManagerService mActivityManagerService;
1985        CpuBinder(ActivityManagerService activityManagerService) {
1986            mActivityManagerService = activityManagerService;
1987        }
1988
1989        @Override
1990        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1991            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1992                    != PackageManager.PERMISSION_GRANTED) {
1993                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1994                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1995                        + " without permission " + android.Manifest.permission.DUMP);
1996                return;
1997            }
1998
1999            synchronized (mActivityManagerService.mProcessCpuTracker) {
2000                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2001                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2002                        SystemClock.uptimeMillis()));
2003            }
2004        }
2005    }
2006
2007    public static final class Lifecycle extends SystemService {
2008        private final ActivityManagerService mService;
2009
2010        public Lifecycle(Context context) {
2011            super(context);
2012            mService = new ActivityManagerService(context);
2013        }
2014
2015        @Override
2016        public void onStart() {
2017            mService.start();
2018        }
2019
2020        public ActivityManagerService getService() {
2021            return mService;
2022        }
2023    }
2024
2025    // Note: This method is invoked on the main thread but may need to attach various
2026    // handlers to other threads.  So take care to be explicit about the looper.
2027    public ActivityManagerService(Context systemContext) {
2028        mContext = systemContext;
2029        mFactoryTest = FactoryTest.getMode();
2030        mSystemThread = ActivityThread.currentActivityThread();
2031
2032        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2033
2034        mHandlerThread = new ServiceThread(TAG,
2035                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2036        mHandlerThread.start();
2037        mHandler = new MainHandler(mHandlerThread.getLooper());
2038
2039        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2040                "foreground", BROADCAST_FG_TIMEOUT, false);
2041        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2042                "background", BROADCAST_BG_TIMEOUT, true);
2043        mBroadcastQueues[0] = mFgBroadcastQueue;
2044        mBroadcastQueues[1] = mBgBroadcastQueue;
2045
2046        mServices = new ActiveServices(this);
2047        mProviderMap = new ProviderMap(this);
2048
2049        // TODO: Move creation of battery stats service outside of activity manager service.
2050        File dataDir = Environment.getDataDirectory();
2051        File systemDir = new File(dataDir, "system");
2052        systemDir.mkdirs();
2053        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2054        mBatteryStatsService.getActiveStatistics().readLocked();
2055        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2056        mOnBattery = DEBUG_POWER ? true
2057                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2058        mBatteryStatsService.getActiveStatistics().setCallback(this);
2059
2060        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2061
2062        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2063
2064        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2065
2066        // User 0 is the first and only user that runs at boot.
2067        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2068        mUserLru.add(Integer.valueOf(0));
2069        updateStartedUserArrayLocked();
2070
2071        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2072            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2073
2074        mConfiguration.setToDefaults();
2075        mConfiguration.setLocale(Locale.getDefault());
2076
2077        mConfigurationSeq = mConfiguration.seq = 1;
2078        mProcessCpuTracker.init();
2079
2080        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2081        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2082        mStackSupervisor = new ActivityStackSupervisor(this);
2083        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2084
2085        mProcessCpuThread = new Thread("CpuTracker") {
2086            @Override
2087            public void run() {
2088                while (true) {
2089                    try {
2090                        try {
2091                            synchronized(this) {
2092                                final long now = SystemClock.uptimeMillis();
2093                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2094                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2095                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2096                                //        + ", write delay=" + nextWriteDelay);
2097                                if (nextWriteDelay < nextCpuDelay) {
2098                                    nextCpuDelay = nextWriteDelay;
2099                                }
2100                                if (nextCpuDelay > 0) {
2101                                    mProcessCpuMutexFree.set(true);
2102                                    this.wait(nextCpuDelay);
2103                                }
2104                            }
2105                        } catch (InterruptedException e) {
2106                        }
2107                        updateCpuStatsNow();
2108                    } catch (Exception e) {
2109                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2110                    }
2111                }
2112            }
2113        };
2114
2115        Watchdog.getInstance().addMonitor(this);
2116        Watchdog.getInstance().addThread(mHandler);
2117    }
2118
2119    public void setSystemServiceManager(SystemServiceManager mgr) {
2120        mSystemServiceManager = mgr;
2121    }
2122
2123    public void setInstaller(Installer installer) {
2124        mInstaller = installer;
2125    }
2126
2127    private void start() {
2128        Process.removeAllProcessGroups();
2129        mProcessCpuThread.start();
2130
2131        mBatteryStatsService.publish(mContext);
2132        mAppOpsService.publish(mContext);
2133        Slog.d("AppOps", "AppOpsService published");
2134        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2135    }
2136
2137    public void initPowerManagement() {
2138        mStackSupervisor.initPowerManagement();
2139        mBatteryStatsService.initPowerManagement();
2140    }
2141
2142    @Override
2143    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2144            throws RemoteException {
2145        if (code == SYSPROPS_TRANSACTION) {
2146            // We need to tell all apps about the system property change.
2147            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2148            synchronized(this) {
2149                final int NP = mProcessNames.getMap().size();
2150                for (int ip=0; ip<NP; ip++) {
2151                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2152                    final int NA = apps.size();
2153                    for (int ia=0; ia<NA; ia++) {
2154                        ProcessRecord app = apps.valueAt(ia);
2155                        if (app.thread != null) {
2156                            procs.add(app.thread.asBinder());
2157                        }
2158                    }
2159                }
2160            }
2161
2162            int N = procs.size();
2163            for (int i=0; i<N; i++) {
2164                Parcel data2 = Parcel.obtain();
2165                try {
2166                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2167                } catch (RemoteException e) {
2168                }
2169                data2.recycle();
2170            }
2171        }
2172        try {
2173            return super.onTransact(code, data, reply, flags);
2174        } catch (RuntimeException e) {
2175            // The activity manager only throws security exceptions, so let's
2176            // log all others.
2177            if (!(e instanceof SecurityException)) {
2178                Slog.wtf(TAG, "Activity Manager Crash", e);
2179            }
2180            throw e;
2181        }
2182    }
2183
2184    void updateCpuStats() {
2185        final long now = SystemClock.uptimeMillis();
2186        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2187            return;
2188        }
2189        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2190            synchronized (mProcessCpuThread) {
2191                mProcessCpuThread.notify();
2192            }
2193        }
2194    }
2195
2196    void updateCpuStatsNow() {
2197        synchronized (mProcessCpuTracker) {
2198            mProcessCpuMutexFree.set(false);
2199            final long now = SystemClock.uptimeMillis();
2200            boolean haveNewCpuStats = false;
2201
2202            if (MONITOR_CPU_USAGE &&
2203                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2204                mLastCpuTime.set(now);
2205                haveNewCpuStats = true;
2206                mProcessCpuTracker.update();
2207                //Slog.i(TAG, mProcessCpu.printCurrentState());
2208                //Slog.i(TAG, "Total CPU usage: "
2209                //        + mProcessCpu.getTotalCpuPercent() + "%");
2210
2211                // Slog the cpu usage if the property is set.
2212                if ("true".equals(SystemProperties.get("events.cpu"))) {
2213                    int user = mProcessCpuTracker.getLastUserTime();
2214                    int system = mProcessCpuTracker.getLastSystemTime();
2215                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2216                    int irq = mProcessCpuTracker.getLastIrqTime();
2217                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2218                    int idle = mProcessCpuTracker.getLastIdleTime();
2219
2220                    int total = user + system + iowait + irq + softIrq + idle;
2221                    if (total == 0) total = 1;
2222
2223                    EventLog.writeEvent(EventLogTags.CPU,
2224                            ((user+system+iowait+irq+softIrq) * 100) / total,
2225                            (user * 100) / total,
2226                            (system * 100) / total,
2227                            (iowait * 100) / total,
2228                            (irq * 100) / total,
2229                            (softIrq * 100) / total);
2230                }
2231            }
2232
2233            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2234            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2235            synchronized(bstats) {
2236                synchronized(mPidsSelfLocked) {
2237                    if (haveNewCpuStats) {
2238                        if (mOnBattery) {
2239                            int perc = bstats.startAddingCpuLocked();
2240                            int totalUTime = 0;
2241                            int totalSTime = 0;
2242                            final int N = mProcessCpuTracker.countStats();
2243                            for (int i=0; i<N; i++) {
2244                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2245                                if (!st.working) {
2246                                    continue;
2247                                }
2248                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2249                                int otherUTime = (st.rel_utime*perc)/100;
2250                                int otherSTime = (st.rel_stime*perc)/100;
2251                                totalUTime += otherUTime;
2252                                totalSTime += otherSTime;
2253                                if (pr != null) {
2254                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2255                                    if (ps == null || !ps.isActive()) {
2256                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2257                                                pr.info.uid, pr.processName);
2258                                    }
2259                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2260                                            st.rel_stime-otherSTime);
2261                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2262                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2263                                } else {
2264                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2265                                    if (ps == null || !ps.isActive()) {
2266                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2267                                                bstats.mapUid(st.uid), st.name);
2268                                    }
2269                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2270                                            st.rel_stime-otherSTime);
2271                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2272                                }
2273                            }
2274                            bstats.finishAddingCpuLocked(perc, totalUTime,
2275                                    totalSTime, cpuSpeedTimes);
2276                        }
2277                    }
2278                }
2279
2280                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2281                    mLastWriteTime = now;
2282                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2283                }
2284            }
2285        }
2286    }
2287
2288    @Override
2289    public void batteryNeedsCpuUpdate() {
2290        updateCpuStatsNow();
2291    }
2292
2293    @Override
2294    public void batteryPowerChanged(boolean onBattery) {
2295        // When plugging in, update the CPU stats first before changing
2296        // the plug state.
2297        updateCpuStatsNow();
2298        synchronized (this) {
2299            synchronized(mPidsSelfLocked) {
2300                mOnBattery = DEBUG_POWER ? true : onBattery;
2301            }
2302        }
2303    }
2304
2305    /**
2306     * Initialize the application bind args. These are passed to each
2307     * process when the bindApplication() IPC is sent to the process. They're
2308     * lazily setup to make sure the services are running when they're asked for.
2309     */
2310    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2311        if (mAppBindArgs == null) {
2312            mAppBindArgs = new HashMap<>();
2313
2314            // Isolated processes won't get this optimization, so that we don't
2315            // violate the rules about which services they have access to.
2316            if (!isolated) {
2317                // Setup the application init args
2318                mAppBindArgs.put("package", ServiceManager.getService("package"));
2319                mAppBindArgs.put("window", ServiceManager.getService("window"));
2320                mAppBindArgs.put(Context.ALARM_SERVICE,
2321                        ServiceManager.getService(Context.ALARM_SERVICE));
2322            }
2323        }
2324        return mAppBindArgs;
2325    }
2326
2327    final void setFocusedActivityLocked(ActivityRecord r) {
2328        if (mFocusedActivity != r) {
2329            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2330            mFocusedActivity = r;
2331            if (r.task != null && r.task.voiceInteractor != null) {
2332                startRunningVoiceLocked();
2333            } else {
2334                finishRunningVoiceLocked();
2335            }
2336            mStackSupervisor.setFocusedStack(r);
2337            if (r != null) {
2338                mWindowManager.setFocusedApp(r.appToken, true);
2339            }
2340            applyUpdateLockStateLocked(r);
2341        }
2342    }
2343
2344    final void clearFocusedActivity(ActivityRecord r) {
2345        if (mFocusedActivity == r) {
2346            mFocusedActivity = null;
2347        }
2348    }
2349
2350    @Override
2351    public void setFocusedStack(int stackId) {
2352        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2353        synchronized (ActivityManagerService.this) {
2354            ActivityStack stack = mStackSupervisor.getStack(stackId);
2355            if (stack != null) {
2356                ActivityRecord r = stack.topRunningActivityLocked(null);
2357                if (r != null) {
2358                    setFocusedActivityLocked(r);
2359                }
2360            }
2361        }
2362    }
2363
2364    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2365    @Override
2366    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2367        synchronized (ActivityManagerService.this) {
2368            if (listener != null) {
2369                mTaskStackListeners.register(listener);
2370            }
2371        }
2372    }
2373
2374    @Override
2375    public void notifyActivityDrawn(IBinder token) {
2376        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2377        synchronized (this) {
2378            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2379            if (r != null) {
2380                r.task.stack.notifyActivityDrawnLocked(r);
2381            }
2382        }
2383    }
2384
2385    final void applyUpdateLockStateLocked(ActivityRecord r) {
2386        // Modifications to the UpdateLock state are done on our handler, outside
2387        // the activity manager's locks.  The new state is determined based on the
2388        // state *now* of the relevant activity record.  The object is passed to
2389        // the handler solely for logging detail, not to be consulted/modified.
2390        final boolean nextState = r != null && r.immersive;
2391        mHandler.sendMessage(
2392                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2393    }
2394
2395    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2396        Message msg = Message.obtain();
2397        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2398        msg.obj = r.task.askedCompatMode ? null : r;
2399        mHandler.sendMessage(msg);
2400    }
2401
2402    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2403            String what, Object obj, ProcessRecord srcApp) {
2404        app.lastActivityTime = now;
2405
2406        if (app.activities.size() > 0) {
2407            // Don't want to touch dependent processes that are hosting activities.
2408            return index;
2409        }
2410
2411        int lrui = mLruProcesses.lastIndexOf(app);
2412        if (lrui < 0) {
2413            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2414                    + what + " " + obj + " from " + srcApp);
2415            return index;
2416        }
2417
2418        if (lrui >= index) {
2419            // Don't want to cause this to move dependent processes *back* in the
2420            // list as if they were less frequently used.
2421            return index;
2422        }
2423
2424        if (lrui >= mLruProcessActivityStart) {
2425            // Don't want to touch dependent processes that are hosting activities.
2426            return index;
2427        }
2428
2429        mLruProcesses.remove(lrui);
2430        if (index > 0) {
2431            index--;
2432        }
2433        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2434                + " in LRU list: " + app);
2435        mLruProcesses.add(index, app);
2436        return index;
2437    }
2438
2439    final void removeLruProcessLocked(ProcessRecord app) {
2440        int lrui = mLruProcesses.lastIndexOf(app);
2441        if (lrui >= 0) {
2442            if (!app.killed) {
2443                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2444                Process.killProcessQuiet(app.pid);
2445                Process.killProcessGroup(app.info.uid, app.pid);
2446            }
2447            if (lrui <= mLruProcessActivityStart) {
2448                mLruProcessActivityStart--;
2449            }
2450            if (lrui <= mLruProcessServiceStart) {
2451                mLruProcessServiceStart--;
2452            }
2453            mLruProcesses.remove(lrui);
2454        }
2455    }
2456
2457    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2458            ProcessRecord client) {
2459        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2460                || app.treatLikeActivity;
2461        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2462        if (!activityChange && hasActivity) {
2463            // The process has activities, so we are only allowing activity-based adjustments
2464            // to move it.  It should be kept in the front of the list with other
2465            // processes that have activities, and we don't want those to change their
2466            // order except due to activity operations.
2467            return;
2468        }
2469
2470        mLruSeq++;
2471        final long now = SystemClock.uptimeMillis();
2472        app.lastActivityTime = now;
2473
2474        // First a quick reject: if the app is already at the position we will
2475        // put it, then there is nothing to do.
2476        if (hasActivity) {
2477            final int N = mLruProcesses.size();
2478            if (N > 0 && mLruProcesses.get(N-1) == app) {
2479                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2480                return;
2481            }
2482        } else {
2483            if (mLruProcessServiceStart > 0
2484                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2485                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2486                return;
2487            }
2488        }
2489
2490        int lrui = mLruProcesses.lastIndexOf(app);
2491
2492        if (app.persistent && lrui >= 0) {
2493            // We don't care about the position of persistent processes, as long as
2494            // they are in the list.
2495            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2496            return;
2497        }
2498
2499        /* In progress: compute new position first, so we can avoid doing work
2500           if the process is not actually going to move.  Not yet working.
2501        int addIndex;
2502        int nextIndex;
2503        boolean inActivity = false, inService = false;
2504        if (hasActivity) {
2505            // Process has activities, put it at the very tipsy-top.
2506            addIndex = mLruProcesses.size();
2507            nextIndex = mLruProcessServiceStart;
2508            inActivity = true;
2509        } else if (hasService) {
2510            // Process has services, put it at the top of the service list.
2511            addIndex = mLruProcessActivityStart;
2512            nextIndex = mLruProcessServiceStart;
2513            inActivity = true;
2514            inService = true;
2515        } else  {
2516            // Process not otherwise of interest, it goes to the top of the non-service area.
2517            addIndex = mLruProcessServiceStart;
2518            if (client != null) {
2519                int clientIndex = mLruProcesses.lastIndexOf(client);
2520                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2521                        + app);
2522                if (clientIndex >= 0 && addIndex > clientIndex) {
2523                    addIndex = clientIndex;
2524                }
2525            }
2526            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2527        }
2528
2529        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2530                + mLruProcessActivityStart + "): " + app);
2531        */
2532
2533        if (lrui >= 0) {
2534            if (lrui < mLruProcessActivityStart) {
2535                mLruProcessActivityStart--;
2536            }
2537            if (lrui < mLruProcessServiceStart) {
2538                mLruProcessServiceStart--;
2539            }
2540            /*
2541            if (addIndex > lrui) {
2542                addIndex--;
2543            }
2544            if (nextIndex > lrui) {
2545                nextIndex--;
2546            }
2547            */
2548            mLruProcesses.remove(lrui);
2549        }
2550
2551        /*
2552        mLruProcesses.add(addIndex, app);
2553        if (inActivity) {
2554            mLruProcessActivityStart++;
2555        }
2556        if (inService) {
2557            mLruProcessActivityStart++;
2558        }
2559        */
2560
2561        int nextIndex;
2562        if (hasActivity) {
2563            final int N = mLruProcesses.size();
2564            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2565                // Process doesn't have activities, but has clients with
2566                // activities...  move it up, but one below the top (the top
2567                // should always have a real activity).
2568                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2569                mLruProcesses.add(N-1, app);
2570                // To keep it from spamming the LRU list (by making a bunch of clients),
2571                // we will push down any other entries owned by the app.
2572                final int uid = app.info.uid;
2573                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2574                    ProcessRecord subProc = mLruProcesses.get(i);
2575                    if (subProc.info.uid == uid) {
2576                        // We want to push this one down the list.  If the process after
2577                        // it is for the same uid, however, don't do so, because we don't
2578                        // want them internally to be re-ordered.
2579                        if (mLruProcesses.get(i-1).info.uid != uid) {
2580                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2581                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2582                            ProcessRecord tmp = mLruProcesses.get(i);
2583                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2584                            mLruProcesses.set(i-1, tmp);
2585                            i--;
2586                        }
2587                    } else {
2588                        // A gap, we can stop here.
2589                        break;
2590                    }
2591                }
2592            } else {
2593                // Process has activities, put it at the very tipsy-top.
2594                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2595                mLruProcesses.add(app);
2596            }
2597            nextIndex = mLruProcessServiceStart;
2598        } else if (hasService) {
2599            // Process has services, put it at the top of the service list.
2600            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2601            mLruProcesses.add(mLruProcessActivityStart, app);
2602            nextIndex = mLruProcessServiceStart;
2603            mLruProcessActivityStart++;
2604        } else  {
2605            // Process not otherwise of interest, it goes to the top of the non-service area.
2606            int index = mLruProcessServiceStart;
2607            if (client != null) {
2608                // If there is a client, don't allow the process to be moved up higher
2609                // in the list than that client.
2610                int clientIndex = mLruProcesses.lastIndexOf(client);
2611                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2612                        + " when updating " + app);
2613                if (clientIndex <= lrui) {
2614                    // Don't allow the client index restriction to push it down farther in the
2615                    // list than it already is.
2616                    clientIndex = lrui;
2617                }
2618                if (clientIndex >= 0 && index > clientIndex) {
2619                    index = clientIndex;
2620                }
2621            }
2622            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2623            mLruProcesses.add(index, app);
2624            nextIndex = index-1;
2625            mLruProcessActivityStart++;
2626            mLruProcessServiceStart++;
2627        }
2628
2629        // If the app is currently using a content provider or service,
2630        // bump those processes as well.
2631        for (int j=app.connections.size()-1; j>=0; j--) {
2632            ConnectionRecord cr = app.connections.valueAt(j);
2633            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2634                    && cr.binding.service.app != null
2635                    && cr.binding.service.app.lruSeq != mLruSeq
2636                    && !cr.binding.service.app.persistent) {
2637                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2638                        "service connection", cr, app);
2639            }
2640        }
2641        for (int j=app.conProviders.size()-1; j>=0; j--) {
2642            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2643            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2644                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2645                        "provider reference", cpr, app);
2646            }
2647        }
2648    }
2649
2650    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2651        if (uid == Process.SYSTEM_UID) {
2652            // The system gets to run in any process.  If there are multiple
2653            // processes with the same uid, just pick the first (this
2654            // should never happen).
2655            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2656            if (procs == null) return null;
2657            final int N = procs.size();
2658            for (int i = 0; i < N; i++) {
2659                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2660            }
2661        }
2662        ProcessRecord proc = mProcessNames.get(processName, uid);
2663        if (false && proc != null && !keepIfLarge
2664                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2665                && proc.lastCachedPss >= 4000) {
2666            // Turn this condition on to cause killing to happen regularly, for testing.
2667            if (proc.baseProcessTracker != null) {
2668                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2669            }
2670            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2671        } else if (proc != null && !keepIfLarge
2672                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2673                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2674            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2675            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2676                if (proc.baseProcessTracker != null) {
2677                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2678                }
2679                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2680            }
2681        }
2682        return proc;
2683    }
2684
2685    void ensurePackageDexOpt(String packageName) {
2686        IPackageManager pm = AppGlobals.getPackageManager();
2687        try {
2688            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2689                mDidDexOpt = true;
2690            }
2691        } catch (RemoteException e) {
2692        }
2693    }
2694
2695    boolean isNextTransitionForward() {
2696        int transit = mWindowManager.getPendingAppTransition();
2697        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2698                || transit == AppTransition.TRANSIT_TASK_OPEN
2699                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2700    }
2701
2702    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2703            String processName, String abiOverride, int uid, Runnable crashHandler) {
2704        synchronized(this) {
2705            ApplicationInfo info = new ApplicationInfo();
2706            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2707            // For isolated processes, the former contains the parent's uid and the latter the
2708            // actual uid of the isolated process.
2709            // In the special case introduced by this method (which is, starting an isolated
2710            // process directly from the SystemServer without an actual parent app process) the
2711            // closest thing to a parent's uid is SYSTEM_UID.
2712            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2713            // the |isolated| logic in the ProcessRecord constructor.
2714            info.uid = Process.SYSTEM_UID;
2715            info.processName = processName;
2716            info.className = entryPoint;
2717            info.packageName = "android";
2718            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2719                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2720                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2721                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2722                    crashHandler);
2723            return proc != null ? proc.pid : 0;
2724        }
2725    }
2726
2727    final ProcessRecord startProcessLocked(String processName,
2728            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2729            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2730            boolean isolated, boolean keepIfLarge) {
2731        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2732                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2733                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2734                null /* crashHandler */);
2735    }
2736
2737    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2738            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2739            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2740            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2741        long startTime = SystemClock.elapsedRealtime();
2742        ProcessRecord app;
2743        if (!isolated) {
2744            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2745            checkTime(startTime, "startProcess: after getProcessRecord");
2746        } else {
2747            // If this is an isolated process, it can't re-use an existing process.
2748            app = null;
2749        }
2750        // We don't have to do anything more if:
2751        // (1) There is an existing application record; and
2752        // (2) The caller doesn't think it is dead, OR there is no thread
2753        //     object attached to it so we know it couldn't have crashed; and
2754        // (3) There is a pid assigned to it, so it is either starting or
2755        //     already running.
2756        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2757                + " app=" + app + " knownToBeDead=" + knownToBeDead
2758                + " thread=" + (app != null ? app.thread : null)
2759                + " pid=" + (app != null ? app.pid : -1));
2760        if (app != null && app.pid > 0) {
2761            if (!knownToBeDead || app.thread == null) {
2762                // We already have the app running, or are waiting for it to
2763                // come up (we have a pid but not yet its thread), so keep it.
2764                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2765                // If this is a new package in the process, add the package to the list
2766                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2767                checkTime(startTime, "startProcess: done, added package to proc");
2768                return app;
2769            }
2770
2771            // An application record is attached to a previous process,
2772            // clean it up now.
2773            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2774            checkTime(startTime, "startProcess: bad proc running, killing");
2775            Process.killProcessGroup(app.info.uid, app.pid);
2776            handleAppDiedLocked(app, true, true);
2777            checkTime(startTime, "startProcess: done killing old proc");
2778        }
2779
2780        String hostingNameStr = hostingName != null
2781                ? hostingName.flattenToShortString() : null;
2782
2783        if (!isolated) {
2784            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2785                // If we are in the background, then check to see if this process
2786                // is bad.  If so, we will just silently fail.
2787                if (mBadProcesses.get(info.processName, info.uid) != null) {
2788                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2789                            + "/" + info.processName);
2790                    return null;
2791                }
2792            } else {
2793                // When the user is explicitly starting a process, then clear its
2794                // crash count so that we won't make it bad until they see at
2795                // least one crash dialog again, and make the process good again
2796                // if it had been bad.
2797                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2798                        + "/" + info.processName);
2799                mProcessCrashTimes.remove(info.processName, info.uid);
2800                if (mBadProcesses.get(info.processName, info.uid) != null) {
2801                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2802                            UserHandle.getUserId(info.uid), info.uid,
2803                            info.processName);
2804                    mBadProcesses.remove(info.processName, info.uid);
2805                    if (app != null) {
2806                        app.bad = false;
2807                    }
2808                }
2809            }
2810        }
2811
2812        if (app == null) {
2813            checkTime(startTime, "startProcess: creating new process record");
2814            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2815            if (app == null) {
2816                Slog.w(TAG, "Failed making new process record for "
2817                        + processName + "/" + info.uid + " isolated=" + isolated);
2818                return null;
2819            }
2820            app.crashHandler = crashHandler;
2821            mProcessNames.put(processName, app.uid, app);
2822            if (isolated) {
2823                mIsolatedProcesses.put(app.uid, app);
2824            }
2825            checkTime(startTime, "startProcess: done creating new process record");
2826        } else {
2827            // If this is a new package in the process, add the package to the list
2828            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2829            checkTime(startTime, "startProcess: added package to existing proc");
2830        }
2831
2832        // If the system is not ready yet, then hold off on starting this
2833        // process until it is.
2834        if (!mProcessesReady
2835                && !isAllowedWhileBooting(info)
2836                && !allowWhileBooting) {
2837            if (!mProcessesOnHold.contains(app)) {
2838                mProcessesOnHold.add(app);
2839            }
2840            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2841            checkTime(startTime, "startProcess: returning with proc on hold");
2842            return app;
2843        }
2844
2845        checkTime(startTime, "startProcess: stepping in to startProcess");
2846        startProcessLocked(
2847                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2848        checkTime(startTime, "startProcess: done starting proc!");
2849        return (app.pid != 0) ? app : null;
2850    }
2851
2852    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2853        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2854    }
2855
2856    private final void startProcessLocked(ProcessRecord app,
2857            String hostingType, String hostingNameStr) {
2858        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2859                null /* entryPoint */, null /* entryPointArgs */);
2860    }
2861
2862    private final void startProcessLocked(ProcessRecord app, String hostingType,
2863            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2864        long startTime = SystemClock.elapsedRealtime();
2865        if (app.pid > 0 && app.pid != MY_PID) {
2866            checkTime(startTime, "startProcess: removing from pids map");
2867            synchronized (mPidsSelfLocked) {
2868                mPidsSelfLocked.remove(app.pid);
2869                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2870            }
2871            checkTime(startTime, "startProcess: done removing from pids map");
2872            app.setPid(0);
2873        }
2874
2875        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2876                "startProcessLocked removing on hold: " + app);
2877        mProcessesOnHold.remove(app);
2878
2879        checkTime(startTime, "startProcess: starting to update cpu stats");
2880        updateCpuStats();
2881        checkTime(startTime, "startProcess: done updating cpu stats");
2882
2883        try {
2884            int uid = app.uid;
2885
2886            int[] gids = null;
2887            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2888            if (!app.isolated) {
2889                int[] permGids = null;
2890                try {
2891                    checkTime(startTime, "startProcess: getting gids from package manager");
2892                    final PackageManager pm = mContext.getPackageManager();
2893                    permGids = pm.getPackageGids(app.info.packageName);
2894
2895                    if (Environment.isExternalStorageEmulated()) {
2896                        checkTime(startTime, "startProcess: checking external storage perm");
2897                        if (pm.checkPermission(
2898                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2899                                app.info.packageName) == PERMISSION_GRANTED) {
2900                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2901                        } else {
2902                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2903                        }
2904                    }
2905                } catch (PackageManager.NameNotFoundException e) {
2906                    Slog.w(TAG, "Unable to retrieve gids", e);
2907                }
2908
2909                /*
2910                 * Add shared application and profile GIDs so applications can share some
2911                 * resources like shared libraries and access user-wide resources
2912                 */
2913                if (permGids == null) {
2914                    gids = new int[2];
2915                } else {
2916                    gids = new int[permGids.length + 2];
2917                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2918                }
2919                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2920                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2921            }
2922            checkTime(startTime, "startProcess: building args");
2923            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2924                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2925                        && mTopComponent != null
2926                        && app.processName.equals(mTopComponent.getPackageName())) {
2927                    uid = 0;
2928                }
2929                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2930                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2931                    uid = 0;
2932                }
2933            }
2934            int debugFlags = 0;
2935            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2936                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2937                // Also turn on CheckJNI for debuggable apps. It's quite
2938                // awkward to turn on otherwise.
2939                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2940            }
2941            // Run the app in safe mode if its manifest requests so or the
2942            // system is booted in safe mode.
2943            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2944                mSafeMode == true) {
2945                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2946            }
2947            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2948                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2949            }
2950            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2951                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2952            }
2953            if ("1".equals(SystemProperties.get("debug.assert"))) {
2954                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2955            }
2956
2957            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2958            if (requiredAbi == null) {
2959                requiredAbi = Build.SUPPORTED_ABIS[0];
2960            }
2961
2962            String instructionSet = null;
2963            if (app.info.primaryCpuAbi != null) {
2964                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2965            }
2966
2967            // Start the process.  It will either succeed and return a result containing
2968            // the PID of the new process, or else throw a RuntimeException.
2969            boolean isActivityProcess = (entryPoint == null);
2970            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2971            checkTime(startTime, "startProcess: asking zygote to start proc");
2972            Process.ProcessStartResult startResult = Process.start(entryPoint,
2973                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2974                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2975                    app.info.dataDir, entryPointArgs);
2976            checkTime(startTime, "startProcess: returned from zygote!");
2977
2978            if (app.isolated) {
2979                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2980            }
2981            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2982            checkTime(startTime, "startProcess: done updating battery stats");
2983
2984            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2985                    UserHandle.getUserId(uid), startResult.pid, uid,
2986                    app.processName, hostingType,
2987                    hostingNameStr != null ? hostingNameStr : "");
2988
2989            if (app.persistent) {
2990                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2991            }
2992
2993            checkTime(startTime, "startProcess: building log message");
2994            StringBuilder buf = mStringBuilder;
2995            buf.setLength(0);
2996            buf.append("Start proc ");
2997            buf.append(app.processName);
2998            if (!isActivityProcess) {
2999                buf.append(" [");
3000                buf.append(entryPoint);
3001                buf.append("]");
3002            }
3003            buf.append(" for ");
3004            buf.append(hostingType);
3005            if (hostingNameStr != null) {
3006                buf.append(" ");
3007                buf.append(hostingNameStr);
3008            }
3009            buf.append(": pid=");
3010            buf.append(startResult.pid);
3011            buf.append(" uid=");
3012            buf.append(uid);
3013            buf.append(" gids={");
3014            if (gids != null) {
3015                for (int gi=0; gi<gids.length; gi++) {
3016                    if (gi != 0) buf.append(", ");
3017                    buf.append(gids[gi]);
3018
3019                }
3020            }
3021            buf.append("}");
3022            if (requiredAbi != null) {
3023                buf.append(" abi=");
3024                buf.append(requiredAbi);
3025            }
3026            Slog.i(TAG, buf.toString());
3027            app.setPid(startResult.pid);
3028            app.usingWrapper = startResult.usingWrapper;
3029            app.removed = false;
3030            app.killed = false;
3031            app.killedByAm = false;
3032            checkTime(startTime, "startProcess: starting to update pids map");
3033            synchronized (mPidsSelfLocked) {
3034                this.mPidsSelfLocked.put(startResult.pid, app);
3035                if (isActivityProcess) {
3036                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3037                    msg.obj = app;
3038                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3039                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3040                }
3041            }
3042            checkTime(startTime, "startProcess: done updating pids map");
3043        } catch (RuntimeException e) {
3044            // XXX do better error recovery.
3045            app.setPid(0);
3046            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3047            if (app.isolated) {
3048                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3049            }
3050            Slog.e(TAG, "Failure starting process " + app.processName, e);
3051        }
3052    }
3053
3054    void updateUsageStats(ActivityRecord component, boolean resumed) {
3055        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3056        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3057        if (resumed) {
3058            if (mUsageStatsService != null) {
3059                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3060                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3061            }
3062            synchronized (stats) {
3063                stats.noteActivityResumedLocked(component.app.uid);
3064            }
3065        } else {
3066            if (mUsageStatsService != null) {
3067                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3068                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3069            }
3070            synchronized (stats) {
3071                stats.noteActivityPausedLocked(component.app.uid);
3072            }
3073        }
3074    }
3075
3076    Intent getHomeIntent() {
3077        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3078        intent.setComponent(mTopComponent);
3079        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3080            intent.addCategory(Intent.CATEGORY_HOME);
3081        }
3082        return intent;
3083    }
3084
3085    boolean startHomeActivityLocked(int userId) {
3086        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3087                && mTopAction == null) {
3088            // We are running in factory test mode, but unable to find
3089            // the factory test app, so just sit around displaying the
3090            // error message and don't try to start anything.
3091            return false;
3092        }
3093        Intent intent = getHomeIntent();
3094        ActivityInfo aInfo =
3095            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3096        if (aInfo != null) {
3097            intent.setComponent(new ComponentName(
3098                    aInfo.applicationInfo.packageName, aInfo.name));
3099            // Don't do this if the home app is currently being
3100            // instrumented.
3101            aInfo = new ActivityInfo(aInfo);
3102            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3103            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3104                    aInfo.applicationInfo.uid, true);
3105            if (app == null || app.instrumentationClass == null) {
3106                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3107                mStackSupervisor.startHomeActivity(intent, aInfo);
3108            }
3109        }
3110
3111        return true;
3112    }
3113
3114    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3115        ActivityInfo ai = null;
3116        ComponentName comp = intent.getComponent();
3117        try {
3118            if (comp != null) {
3119                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3120            } else {
3121                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3122                        intent,
3123                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3124                            flags, userId);
3125
3126                if (info != null) {
3127                    ai = info.activityInfo;
3128                }
3129            }
3130        } catch (RemoteException e) {
3131            // ignore
3132        }
3133
3134        return ai;
3135    }
3136
3137    /**
3138     * Starts the "new version setup screen" if appropriate.
3139     */
3140    void startSetupActivityLocked() {
3141        // Only do this once per boot.
3142        if (mCheckedForSetup) {
3143            return;
3144        }
3145
3146        // We will show this screen if the current one is a different
3147        // version than the last one shown, and we are not running in
3148        // low-level factory test mode.
3149        final ContentResolver resolver = mContext.getContentResolver();
3150        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3151                Settings.Global.getInt(resolver,
3152                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3153            mCheckedForSetup = true;
3154
3155            // See if we should be showing the platform update setup UI.
3156            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3157            List<ResolveInfo> ris = mContext.getPackageManager()
3158                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3159
3160            // We don't allow third party apps to replace this.
3161            ResolveInfo ri = null;
3162            for (int i=0; ris != null && i<ris.size(); i++) {
3163                if ((ris.get(i).activityInfo.applicationInfo.flags
3164                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3165                    ri = ris.get(i);
3166                    break;
3167                }
3168            }
3169
3170            if (ri != null) {
3171                String vers = ri.activityInfo.metaData != null
3172                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3173                        : null;
3174                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3175                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3176                            Intent.METADATA_SETUP_VERSION);
3177                }
3178                String lastVers = Settings.Secure.getString(
3179                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3180                if (vers != null && !vers.equals(lastVers)) {
3181                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3182                    intent.setComponent(new ComponentName(
3183                            ri.activityInfo.packageName, ri.activityInfo.name));
3184                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3185                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3186                            null);
3187                }
3188            }
3189        }
3190    }
3191
3192    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3193        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3194    }
3195
3196    void enforceNotIsolatedCaller(String caller) {
3197        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3198            throw new SecurityException("Isolated process not allowed to call " + caller);
3199        }
3200    }
3201
3202    void enforceShellRestriction(String restriction, int userHandle) {
3203        if (Binder.getCallingUid() == Process.SHELL_UID) {
3204            if (userHandle < 0
3205                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3206                throw new SecurityException("Shell does not have permission to access user "
3207                        + userHandle);
3208            }
3209        }
3210    }
3211
3212    @Override
3213    public int getFrontActivityScreenCompatMode() {
3214        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3215        synchronized (this) {
3216            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3217        }
3218    }
3219
3220    @Override
3221    public void setFrontActivityScreenCompatMode(int mode) {
3222        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3223                "setFrontActivityScreenCompatMode");
3224        synchronized (this) {
3225            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3226        }
3227    }
3228
3229    @Override
3230    public int getPackageScreenCompatMode(String packageName) {
3231        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3232        synchronized (this) {
3233            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3234        }
3235    }
3236
3237    @Override
3238    public void setPackageScreenCompatMode(String packageName, int mode) {
3239        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3240                "setPackageScreenCompatMode");
3241        synchronized (this) {
3242            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3243        }
3244    }
3245
3246    @Override
3247    public boolean getPackageAskScreenCompat(String packageName) {
3248        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3249        synchronized (this) {
3250            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3251        }
3252    }
3253
3254    @Override
3255    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3256        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3257                "setPackageAskScreenCompat");
3258        synchronized (this) {
3259            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3260        }
3261    }
3262
3263    private void dispatchProcessesChanged() {
3264        int N;
3265        synchronized (this) {
3266            N = mPendingProcessChanges.size();
3267            if (mActiveProcessChanges.length < N) {
3268                mActiveProcessChanges = new ProcessChangeItem[N];
3269            }
3270            mPendingProcessChanges.toArray(mActiveProcessChanges);
3271            mAvailProcessChanges.addAll(mPendingProcessChanges);
3272            mPendingProcessChanges.clear();
3273            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3274        }
3275
3276        int i = mProcessObservers.beginBroadcast();
3277        while (i > 0) {
3278            i--;
3279            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3280            if (observer != null) {
3281                try {
3282                    for (int j=0; j<N; j++) {
3283                        ProcessChangeItem item = mActiveProcessChanges[j];
3284                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3285                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3286                                    + item.pid + " uid=" + item.uid + ": "
3287                                    + item.foregroundActivities);
3288                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3289                                    item.foregroundActivities);
3290                        }
3291                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3292                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3293                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3294                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3295                        }
3296                    }
3297                } catch (RemoteException e) {
3298                }
3299            }
3300        }
3301        mProcessObservers.finishBroadcast();
3302    }
3303
3304    private void dispatchProcessDied(int pid, int uid) {
3305        int i = mProcessObservers.beginBroadcast();
3306        while (i > 0) {
3307            i--;
3308            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3309            if (observer != null) {
3310                try {
3311                    observer.onProcessDied(pid, uid);
3312                } catch (RemoteException e) {
3313                }
3314            }
3315        }
3316        mProcessObservers.finishBroadcast();
3317    }
3318
3319    @Override
3320    public final int startActivity(IApplicationThread caller, String callingPackage,
3321            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3322            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3323        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3324            resultWho, requestCode, startFlags, profilerInfo, options,
3325            UserHandle.getCallingUserId());
3326    }
3327
3328    @Override
3329    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3330            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3331            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3332        enforceNotIsolatedCaller("startActivity");
3333        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3334                false, ALLOW_FULL_ONLY, "startActivity", null);
3335        // TODO: Switch to user app stacks here.
3336        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3337                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3338                profilerInfo, null, null, options, userId, null, null);
3339    }
3340
3341    @Override
3342    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3343            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3344            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3345
3346        // This is very dangerous -- it allows you to perform a start activity (including
3347        // permission grants) as any app that may launch one of your own activities.  So
3348        // we will only allow this to be done from activities that are part of the core framework,
3349        // and then only when they are running as the system.
3350        final ActivityRecord sourceRecord;
3351        final int targetUid;
3352        final String targetPackage;
3353        synchronized (this) {
3354            if (resultTo == null) {
3355                throw new SecurityException("Must be called from an activity");
3356            }
3357            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3358            if (sourceRecord == null) {
3359                throw new SecurityException("Called with bad activity token: " + resultTo);
3360            }
3361            if (!sourceRecord.info.packageName.equals("android")) {
3362                throw new SecurityException(
3363                        "Must be called from an activity that is declared in the android package");
3364            }
3365            if (sourceRecord.app == null) {
3366                throw new SecurityException("Called without a process attached to activity");
3367            }
3368            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3369                // This is still okay, as long as this activity is running under the
3370                // uid of the original calling activity.
3371                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3372                    throw new SecurityException(
3373                            "Calling activity in uid " + sourceRecord.app.uid
3374                                    + " must be system uid or original calling uid "
3375                                    + sourceRecord.launchedFromUid);
3376                }
3377            }
3378            targetUid = sourceRecord.launchedFromUid;
3379            targetPackage = sourceRecord.launchedFromPackage;
3380        }
3381
3382        if (userId == UserHandle.USER_NULL) {
3383            userId = UserHandle.getUserId(sourceRecord.app.uid);
3384        }
3385
3386        // TODO: Switch to user app stacks here.
3387        try {
3388            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3389                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3390                    null, null, options, userId, null, null);
3391            return ret;
3392        } catch (SecurityException e) {
3393            // XXX need to figure out how to propagate to original app.
3394            // A SecurityException here is generally actually a fault of the original
3395            // calling activity (such as a fairly granting permissions), so propagate it
3396            // back to them.
3397            /*
3398            StringBuilder msg = new StringBuilder();
3399            msg.append("While launching");
3400            msg.append(intent.toString());
3401            msg.append(": ");
3402            msg.append(e.getMessage());
3403            */
3404            throw e;
3405        }
3406    }
3407
3408    @Override
3409    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3410            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3411            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3412        enforceNotIsolatedCaller("startActivityAndWait");
3413        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3414                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3415        WaitResult res = new WaitResult();
3416        // TODO: Switch to user app stacks here.
3417        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3418                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3419                options, userId, null, null);
3420        return res;
3421    }
3422
3423    @Override
3424    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3425            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3426            int startFlags, Configuration config, Bundle options, int userId) {
3427        enforceNotIsolatedCaller("startActivityWithConfig");
3428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3429                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3430        // TODO: Switch to user app stacks here.
3431        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3432                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3433                null, null, config, options, userId, null, null);
3434        return ret;
3435    }
3436
3437    @Override
3438    public int startActivityIntentSender(IApplicationThread caller,
3439            IntentSender intent, Intent fillInIntent, String resolvedType,
3440            IBinder resultTo, String resultWho, int requestCode,
3441            int flagsMask, int flagsValues, Bundle options) {
3442        enforceNotIsolatedCaller("startActivityIntentSender");
3443        // Refuse possible leaked file descriptors
3444        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3445            throw new IllegalArgumentException("File descriptors passed in Intent");
3446        }
3447
3448        IIntentSender sender = intent.getTarget();
3449        if (!(sender instanceof PendingIntentRecord)) {
3450            throw new IllegalArgumentException("Bad PendingIntent object");
3451        }
3452
3453        PendingIntentRecord pir = (PendingIntentRecord)sender;
3454
3455        synchronized (this) {
3456            // If this is coming from the currently resumed activity, it is
3457            // effectively saying that app switches are allowed at this point.
3458            final ActivityStack stack = getFocusedStack();
3459            if (stack.mResumedActivity != null &&
3460                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3461                mAppSwitchesAllowedTime = 0;
3462            }
3463        }
3464        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3465                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3466        return ret;
3467    }
3468
3469    @Override
3470    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3471            Intent intent, String resolvedType, IVoiceInteractionSession session,
3472            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3473            Bundle options, int userId) {
3474        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3475                != PackageManager.PERMISSION_GRANTED) {
3476            String msg = "Permission Denial: startVoiceActivity() from pid="
3477                    + Binder.getCallingPid()
3478                    + ", uid=" + Binder.getCallingUid()
3479                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3480            Slog.w(TAG, msg);
3481            throw new SecurityException(msg);
3482        }
3483        if (session == null || interactor == null) {
3484            throw new NullPointerException("null session or interactor");
3485        }
3486        userId = handleIncomingUser(callingPid, callingUid, userId,
3487                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3488        // TODO: Switch to user app stacks here.
3489        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3490                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3491                null, options, userId, null, null);
3492    }
3493
3494    @Override
3495    public boolean startNextMatchingActivity(IBinder callingActivity,
3496            Intent intent, Bundle options) {
3497        // Refuse possible leaked file descriptors
3498        if (intent != null && intent.hasFileDescriptors() == true) {
3499            throw new IllegalArgumentException("File descriptors passed in Intent");
3500        }
3501
3502        synchronized (this) {
3503            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3504            if (r == null) {
3505                ActivityOptions.abort(options);
3506                return false;
3507            }
3508            if (r.app == null || r.app.thread == null) {
3509                // The caller is not running...  d'oh!
3510                ActivityOptions.abort(options);
3511                return false;
3512            }
3513            intent = new Intent(intent);
3514            // The caller is not allowed to change the data.
3515            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3516            // And we are resetting to find the next component...
3517            intent.setComponent(null);
3518
3519            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3520
3521            ActivityInfo aInfo = null;
3522            try {
3523                List<ResolveInfo> resolves =
3524                    AppGlobals.getPackageManager().queryIntentActivities(
3525                            intent, r.resolvedType,
3526                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3527                            UserHandle.getCallingUserId());
3528
3529                // Look for the original activity in the list...
3530                final int N = resolves != null ? resolves.size() : 0;
3531                for (int i=0; i<N; i++) {
3532                    ResolveInfo rInfo = resolves.get(i);
3533                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3534                            && rInfo.activityInfo.name.equals(r.info.name)) {
3535                        // We found the current one...  the next matching is
3536                        // after it.
3537                        i++;
3538                        if (i<N) {
3539                            aInfo = resolves.get(i).activityInfo;
3540                        }
3541                        if (debug) {
3542                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3543                                    + "/" + r.info.name);
3544                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3545                                    + "/" + aInfo.name);
3546                        }
3547                        break;
3548                    }
3549                }
3550            } catch (RemoteException e) {
3551            }
3552
3553            if (aInfo == null) {
3554                // Nobody who is next!
3555                ActivityOptions.abort(options);
3556                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3557                return false;
3558            }
3559
3560            intent.setComponent(new ComponentName(
3561                    aInfo.applicationInfo.packageName, aInfo.name));
3562            intent.setFlags(intent.getFlags()&~(
3563                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3564                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3565                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3566                    Intent.FLAG_ACTIVITY_NEW_TASK));
3567
3568            // Okay now we need to start the new activity, replacing the
3569            // currently running activity.  This is a little tricky because
3570            // we want to start the new one as if the current one is finished,
3571            // but not finish the current one first so that there is no flicker.
3572            // And thus...
3573            final boolean wasFinishing = r.finishing;
3574            r.finishing = true;
3575
3576            // Propagate reply information over to the new activity.
3577            final ActivityRecord resultTo = r.resultTo;
3578            final String resultWho = r.resultWho;
3579            final int requestCode = r.requestCode;
3580            r.resultTo = null;
3581            if (resultTo != null) {
3582                resultTo.removeResultsLocked(r, resultWho, requestCode);
3583            }
3584
3585            final long origId = Binder.clearCallingIdentity();
3586            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3587                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3588                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3589                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3590            Binder.restoreCallingIdentity(origId);
3591
3592            r.finishing = wasFinishing;
3593            if (res != ActivityManager.START_SUCCESS) {
3594                return false;
3595            }
3596            return true;
3597        }
3598    }
3599
3600    @Override
3601    public final int startActivityFromRecents(int taskId, Bundle options) {
3602        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3603            String msg = "Permission Denial: startActivityFromRecents called without " +
3604                    START_TASKS_FROM_RECENTS;
3605            Slog.w(TAG, msg);
3606            throw new SecurityException(msg);
3607        }
3608        return startActivityFromRecentsInner(taskId, options);
3609    }
3610
3611    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3612        final TaskRecord task;
3613        final int callingUid;
3614        final String callingPackage;
3615        final Intent intent;
3616        final int userId;
3617        synchronized (this) {
3618            task = recentTaskForIdLocked(taskId);
3619            if (task == null) {
3620                throw new IllegalArgumentException("Task " + taskId + " not found.");
3621            }
3622            callingUid = task.mCallingUid;
3623            callingPackage = task.mCallingPackage;
3624            intent = task.intent;
3625            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3626            userId = task.userId;
3627        }
3628        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3629                options, userId, null, task);
3630    }
3631
3632    final int startActivityInPackage(int uid, String callingPackage,
3633            Intent intent, String resolvedType, IBinder resultTo,
3634            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3635            IActivityContainer container, TaskRecord inTask) {
3636
3637        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3638                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3639
3640        // TODO: Switch to user app stacks here.
3641        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3642                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3643                null, null, null, options, userId, container, inTask);
3644        return ret;
3645    }
3646
3647    @Override
3648    public final int startActivities(IApplicationThread caller, String callingPackage,
3649            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3650            int userId) {
3651        enforceNotIsolatedCaller("startActivities");
3652        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3653                false, ALLOW_FULL_ONLY, "startActivity", null);
3654        // TODO: Switch to user app stacks here.
3655        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3656                resolvedTypes, resultTo, options, userId);
3657        return ret;
3658    }
3659
3660    final int startActivitiesInPackage(int uid, String callingPackage,
3661            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3662            Bundle options, int userId) {
3663
3664        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3665                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3666        // TODO: Switch to user app stacks here.
3667        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3668                resultTo, options, userId);
3669        return ret;
3670    }
3671
3672    //explicitly remove thd old information in mRecentTasks when removing existing user.
3673    private void removeRecentTasksForUserLocked(int userId) {
3674        if(userId <= 0) {
3675            Slog.i(TAG, "Can't remove recent task on user " + userId);
3676            return;
3677        }
3678
3679        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3680            TaskRecord tr = mRecentTasks.get(i);
3681            if (tr.userId == userId) {
3682                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3683                        + " when finishing user" + userId);
3684                mRecentTasks.remove(i);
3685                tr.removedFromRecents();
3686            }
3687        }
3688
3689        // Remove tasks from persistent storage.
3690        notifyTaskPersisterLocked(null, true);
3691    }
3692
3693    // Sort by taskId
3694    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3695        @Override
3696        public int compare(TaskRecord lhs, TaskRecord rhs) {
3697            return rhs.taskId - lhs.taskId;
3698        }
3699    };
3700
3701    // Extract the affiliates of the chain containing mRecentTasks[start].
3702    private int processNextAffiliateChainLocked(int start) {
3703        final TaskRecord startTask = mRecentTasks.get(start);
3704        final int affiliateId = startTask.mAffiliatedTaskId;
3705
3706        // Quick identification of isolated tasks. I.e. those not launched behind.
3707        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3708                startTask.mNextAffiliate == null) {
3709            // There is still a slim chance that there are other tasks that point to this task
3710            // and that the chain is so messed up that this task no longer points to them but
3711            // the gain of this optimization outweighs the risk.
3712            startTask.inRecents = true;
3713            return start + 1;
3714        }
3715
3716        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3717        mTmpRecents.clear();
3718        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3719            final TaskRecord task = mRecentTasks.get(i);
3720            if (task.mAffiliatedTaskId == affiliateId) {
3721                mRecentTasks.remove(i);
3722                mTmpRecents.add(task);
3723            }
3724        }
3725
3726        // Sort them all by taskId. That is the order they were create in and that order will
3727        // always be correct.
3728        Collections.sort(mTmpRecents, mTaskRecordComparator);
3729
3730        // Go through and fix up the linked list.
3731        // The first one is the end of the chain and has no next.
3732        final TaskRecord first = mTmpRecents.get(0);
3733        first.inRecents = true;
3734        if (first.mNextAffiliate != null) {
3735            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3736            first.setNextAffiliate(null);
3737            notifyTaskPersisterLocked(first, false);
3738        }
3739        // Everything in the middle is doubly linked from next to prev.
3740        final int tmpSize = mTmpRecents.size();
3741        for (int i = 0; i < tmpSize - 1; ++i) {
3742            final TaskRecord next = mTmpRecents.get(i);
3743            final TaskRecord prev = mTmpRecents.get(i + 1);
3744            if (next.mPrevAffiliate != prev) {
3745                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3746                        " setting prev=" + prev);
3747                next.setPrevAffiliate(prev);
3748                notifyTaskPersisterLocked(next, false);
3749            }
3750            if (prev.mNextAffiliate != next) {
3751                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3752                        " setting next=" + next);
3753                prev.setNextAffiliate(next);
3754                notifyTaskPersisterLocked(prev, false);
3755            }
3756            prev.inRecents = true;
3757        }
3758        // The last one is the beginning of the list and has no prev.
3759        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3760        if (last.mPrevAffiliate != null) {
3761            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3762            last.setPrevAffiliate(null);
3763            notifyTaskPersisterLocked(last, false);
3764        }
3765
3766        // Insert the group back into mRecentTasks at start.
3767        mRecentTasks.addAll(start, mTmpRecents);
3768
3769        // Let the caller know where we left off.
3770        return start + tmpSize;
3771    }
3772
3773    /**
3774     * Update the recent tasks lists: make sure tasks should still be here (their
3775     * applications / activities still exist), update their availability, fixup ordering
3776     * of affiliations.
3777     */
3778    void cleanupRecentTasksLocked(int userId) {
3779        if (mRecentTasks == null) {
3780            // Happens when called from the packagemanager broadcast before boot.
3781            return;
3782        }
3783
3784        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3785        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3786        final IPackageManager pm = AppGlobals.getPackageManager();
3787        final ActivityInfo dummyAct = new ActivityInfo();
3788        final ApplicationInfo dummyApp = new ApplicationInfo();
3789
3790        int N = mRecentTasks.size();
3791
3792        int[] users = userId == UserHandle.USER_ALL
3793                ? getUsersLocked() : new int[] { userId };
3794        for (int user : users) {
3795            for (int i = 0; i < N; i++) {
3796                TaskRecord task = mRecentTasks.get(i);
3797                if (task.userId != user) {
3798                    // Only look at tasks for the user ID of interest.
3799                    continue;
3800                }
3801                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3802                    // This situation is broken, and we should just get rid of it now.
3803                    mRecentTasks.remove(i);
3804                    task.removedFromRecents();
3805                    i--;
3806                    N--;
3807                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3808                    continue;
3809                }
3810                // Check whether this activity is currently available.
3811                if (task.realActivity != null) {
3812                    ActivityInfo ai = availActCache.get(task.realActivity);
3813                    if (ai == null) {
3814                        try {
3815                            ai = pm.getActivityInfo(task.realActivity,
3816                                    PackageManager.GET_UNINSTALLED_PACKAGES
3817                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3818                        } catch (RemoteException e) {
3819                            // Will never happen.
3820                            continue;
3821                        }
3822                        if (ai == null) {
3823                            ai = dummyAct;
3824                        }
3825                        availActCache.put(task.realActivity, ai);
3826                    }
3827                    if (ai == dummyAct) {
3828                        // This could be either because the activity no longer exists, or the
3829                        // app is temporarily gone.  For the former we want to remove the recents
3830                        // entry; for the latter we want to mark it as unavailable.
3831                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3832                        if (app == null) {
3833                            try {
3834                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3835                                        PackageManager.GET_UNINSTALLED_PACKAGES
3836                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3837                            } catch (RemoteException e) {
3838                                // Will never happen.
3839                                continue;
3840                            }
3841                            if (app == null) {
3842                                app = dummyApp;
3843                            }
3844                            availAppCache.put(task.realActivity.getPackageName(), app);
3845                        }
3846                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3847                            // Doesn't exist any more!  Good-bye.
3848                            mRecentTasks.remove(i);
3849                            task.removedFromRecents();
3850                            i--;
3851                            N--;
3852                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3853                            continue;
3854                        } else {
3855                            // Otherwise just not available for now.
3856                            if (task.isAvailable) {
3857                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3858                                        + task);
3859                            }
3860                            task.isAvailable = false;
3861                        }
3862                    } else {
3863                        if (!ai.enabled || !ai.applicationInfo.enabled
3864                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3865                            if (task.isAvailable) {
3866                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3867                                        + task + " (enabled=" + ai.enabled + "/"
3868                                        + ai.applicationInfo.enabled +  " flags="
3869                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3870                            }
3871                            task.isAvailable = false;
3872                        } else {
3873                            if (!task.isAvailable) {
3874                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3875                                        + task);
3876                            }
3877                            task.isAvailable = true;
3878                        }
3879                    }
3880                }
3881            }
3882        }
3883
3884        // Verify the affiliate chain for each task.
3885        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3886        }
3887
3888        mTmpRecents.clear();
3889        // mRecentTasks is now in sorted, affiliated order.
3890    }
3891
3892    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3893        int N = mRecentTasks.size();
3894        TaskRecord top = task;
3895        int topIndex = taskIndex;
3896        while (top.mNextAffiliate != null && topIndex > 0) {
3897            top = top.mNextAffiliate;
3898            topIndex--;
3899        }
3900        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3901                + topIndex + " from intial " + taskIndex);
3902        // Find the end of the chain, doing a sanity check along the way.
3903        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3904        int endIndex = topIndex;
3905        TaskRecord prev = top;
3906        while (endIndex < N) {
3907            TaskRecord cur = mRecentTasks.get(endIndex);
3908            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3909                    + endIndex + " " + cur);
3910            if (cur == top) {
3911                // Verify start of the chain.
3912                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3913                    Slog.wtf(TAG, "Bad chain @" + endIndex
3914                            + ": first task has next affiliate: " + prev);
3915                    sane = false;
3916                    break;
3917                }
3918            } else {
3919                // Verify middle of the chain's next points back to the one before.
3920                if (cur.mNextAffiliate != prev
3921                        || cur.mNextAffiliateTaskId != prev.taskId) {
3922                    Slog.wtf(TAG, "Bad chain @" + endIndex
3923                            + ": middle task " + cur + " @" + endIndex
3924                            + " has bad next affiliate "
3925                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3926                            + ", expected " + prev);
3927                    sane = false;
3928                    break;
3929                }
3930            }
3931            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3932                // Chain ends here.
3933                if (cur.mPrevAffiliate != null) {
3934                    Slog.wtf(TAG, "Bad chain @" + endIndex
3935                            + ": last task " + cur + " has previous affiliate "
3936                            + cur.mPrevAffiliate);
3937                    sane = false;
3938                }
3939                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3940                break;
3941            } else {
3942                // Verify middle of the chain's prev points to a valid item.
3943                if (cur.mPrevAffiliate == null) {
3944                    Slog.wtf(TAG, "Bad chain @" + endIndex
3945                            + ": task " + cur + " has previous affiliate "
3946                            + cur.mPrevAffiliate + " but should be id "
3947                            + cur.mPrevAffiliate);
3948                    sane = false;
3949                    break;
3950                }
3951            }
3952            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3953                Slog.wtf(TAG, "Bad chain @" + endIndex
3954                        + ": task " + cur + " has affiliated id "
3955                        + cur.mAffiliatedTaskId + " but should be "
3956                        + task.mAffiliatedTaskId);
3957                sane = false;
3958                break;
3959            }
3960            prev = cur;
3961            endIndex++;
3962            if (endIndex >= N) {
3963                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3964                        + ": last task " + prev);
3965                sane = false;
3966                break;
3967            }
3968        }
3969        if (sane) {
3970            if (endIndex < taskIndex) {
3971                Slog.wtf(TAG, "Bad chain @" + endIndex
3972                        + ": did not extend to task " + task + " @" + taskIndex);
3973                sane = false;
3974            }
3975        }
3976        if (sane) {
3977            // All looks good, we can just move all of the affiliated tasks
3978            // to the top.
3979            for (int i=topIndex; i<=endIndex; i++) {
3980                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3981                        + " from " + i + " to " + (i-topIndex));
3982                TaskRecord cur = mRecentTasks.remove(i);
3983                mRecentTasks.add(i-topIndex, cur);
3984            }
3985            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3986                    + " to " + endIndex);
3987            return true;
3988        }
3989
3990        // Whoops, couldn't do it.
3991        return false;
3992    }
3993
3994    final void addRecentTaskLocked(TaskRecord task) {
3995        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3996                || task.mNextAffiliateTaskId != INVALID_TASK_ID
3997                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
3998
3999        int N = mRecentTasks.size();
4000        // Quick case: check if the top-most recent task is the same.
4001        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4002            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4003            return;
4004        }
4005        // Another quick case: check if this is part of a set of affiliated
4006        // tasks that are at the top.
4007        if (isAffiliated && N > 0 && task.inRecents
4008                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4009            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4010                    + " at top when adding " + task);
4011            return;
4012        }
4013        // Another quick case: never add voice sessions.
4014        if (task.voiceSession != null) {
4015            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4016            return;
4017        }
4018
4019        boolean needAffiliationFix = false;
4020
4021        // Slightly less quick case: the task is already in recents, so all we need
4022        // to do is move it.
4023        if (task.inRecents) {
4024            int taskIndex = mRecentTasks.indexOf(task);
4025            if (taskIndex >= 0) {
4026                if (!isAffiliated) {
4027                    // Simple case: this is not an affiliated task, so we just move it to the front.
4028                    mRecentTasks.remove(taskIndex);
4029                    mRecentTasks.add(0, task);
4030                    notifyTaskPersisterLocked(task, false);
4031                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4032                            + " from " + taskIndex);
4033                    return;
4034                } else {
4035                    // More complicated: need to keep all affiliated tasks together.
4036                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4037                        // All went well.
4038                        return;
4039                    }
4040
4041                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4042                    // everything and then go through our general path of adding a new task.
4043                    needAffiliationFix = true;
4044                }
4045            } else {
4046                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4047                needAffiliationFix = true;
4048            }
4049        }
4050
4051        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4052        trimRecentsForTaskLocked(task, true);
4053
4054        N = mRecentTasks.size();
4055        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4056            final TaskRecord tr = mRecentTasks.remove(N - 1);
4057            tr.removedFromRecents();
4058            N--;
4059        }
4060        task.inRecents = true;
4061        if (!isAffiliated || needAffiliationFix) {
4062            // If this is a simple non-affiliated task, or we had some failure trying to
4063            // handle it as part of an affilated task, then just place it at the top.
4064            mRecentTasks.add(0, task);
4065        } else if (isAffiliated) {
4066            // If this is a new affiliated task, then move all of the affiliated tasks
4067            // to the front and insert this new one.
4068            TaskRecord other = task.mNextAffiliate;
4069            if (other == null) {
4070                other = task.mPrevAffiliate;
4071            }
4072            if (other != null) {
4073                int otherIndex = mRecentTasks.indexOf(other);
4074                if (otherIndex >= 0) {
4075                    // Insert new task at appropriate location.
4076                    int taskIndex;
4077                    if (other == task.mNextAffiliate) {
4078                        // We found the index of our next affiliation, which is who is
4079                        // before us in the list, so add after that point.
4080                        taskIndex = otherIndex+1;
4081                    } else {
4082                        // We found the index of our previous affiliation, which is who is
4083                        // after us in the list, so add at their position.
4084                        taskIndex = otherIndex;
4085                    }
4086                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4087                            + taskIndex + ": " + task);
4088                    mRecentTasks.add(taskIndex, task);
4089
4090                    // Now move everything to the front.
4091                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4092                        // All went well.
4093                        return;
4094                    }
4095
4096                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4097                    // everything and then go through our general path of adding a new task.
4098                    needAffiliationFix = true;
4099                } else {
4100                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4101                            + other);
4102                    needAffiliationFix = true;
4103                }
4104            } else {
4105                if (DEBUG_RECENTS) Slog.d(TAG,
4106                        "addRecent: adding affiliated task without next/prev:" + task);
4107                needAffiliationFix = true;
4108            }
4109        }
4110        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4111
4112        if (needAffiliationFix) {
4113            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4114            cleanupRecentTasksLocked(task.userId);
4115        }
4116    }
4117
4118    /**
4119     * If needed, remove oldest existing entries in recents that are for the same kind
4120     * of task as the given one.
4121     */
4122    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4123        int N = mRecentTasks.size();
4124        final Intent intent = task.intent;
4125        final boolean document = intent != null && intent.isDocument();
4126
4127        int maxRecents = task.maxRecents - 1;
4128        for (int i=0; i<N; i++) {
4129            final TaskRecord tr = mRecentTasks.get(i);
4130            if (task != tr) {
4131                if (task.userId != tr.userId) {
4132                    continue;
4133                }
4134                if (i > MAX_RECENT_BITMAPS) {
4135                    tr.freeLastThumbnail();
4136                }
4137                final Intent trIntent = tr.intent;
4138                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4139                    (intent == null || !intent.filterEquals(trIntent))) {
4140                    continue;
4141                }
4142                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4143                if (document && trIsDocument) {
4144                    // These are the same document activity (not necessarily the same doc).
4145                    if (maxRecents > 0) {
4146                        --maxRecents;
4147                        continue;
4148                    }
4149                    // Hit the maximum number of documents for this task. Fall through
4150                    // and remove this document from recents.
4151                } else if (document || trIsDocument) {
4152                    // Only one of these is a document. Not the droid we're looking for.
4153                    continue;
4154                }
4155            }
4156
4157            if (!doTrim) {
4158                // If the caller is not actually asking for a trim, just tell them we reached
4159                // a point where the trim would happen.
4160                return i;
4161            }
4162
4163            // Either task and tr are the same or, their affinities match or their intents match
4164            // and neither of them is a document, or they are documents using the same activity
4165            // and their maxRecents has been reached.
4166            tr.disposeThumbnail();
4167            mRecentTasks.remove(i);
4168            if (task != tr) {
4169                tr.removedFromRecents();
4170            }
4171            i--;
4172            N--;
4173            if (task.intent == null) {
4174                // If the new recent task we are adding is not fully
4175                // specified, then replace it with the existing recent task.
4176                task = tr;
4177            }
4178            notifyTaskPersisterLocked(tr, false);
4179        }
4180
4181        return -1;
4182    }
4183
4184    @Override
4185    public void reportActivityFullyDrawn(IBinder token) {
4186        synchronized (this) {
4187            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4188            if (r == null) {
4189                return;
4190            }
4191            r.reportFullyDrawnLocked();
4192        }
4193    }
4194
4195    @Override
4196    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4197        synchronized (this) {
4198            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4199            if (r == null) {
4200                return;
4201            }
4202            final long origId = Binder.clearCallingIdentity();
4203            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4204            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4205                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4206            if (config != null) {
4207                r.frozenBeforeDestroy = true;
4208                if (!updateConfigurationLocked(config, r, false, false)) {
4209                    mStackSupervisor.resumeTopActivitiesLocked();
4210                }
4211            }
4212            Binder.restoreCallingIdentity(origId);
4213        }
4214    }
4215
4216    @Override
4217    public int getRequestedOrientation(IBinder token) {
4218        synchronized (this) {
4219            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4220            if (r == null) {
4221                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4222            }
4223            return mWindowManager.getAppOrientation(r.appToken);
4224        }
4225    }
4226
4227    /**
4228     * This is the internal entry point for handling Activity.finish().
4229     *
4230     * @param token The Binder token referencing the Activity we want to finish.
4231     * @param resultCode Result code, if any, from this Activity.
4232     * @param resultData Result data (Intent), if any, from this Activity.
4233     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4234     *            the root Activity in the task.
4235     *
4236     * @return Returns true if the activity successfully finished, or false if it is still running.
4237     */
4238    @Override
4239    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4240            boolean finishTask) {
4241        // Refuse possible leaked file descriptors
4242        if (resultData != null && resultData.hasFileDescriptors() == true) {
4243            throw new IllegalArgumentException("File descriptors passed in Intent");
4244        }
4245
4246        synchronized(this) {
4247            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4248            if (r == null) {
4249                return true;
4250            }
4251            // Keep track of the root activity of the task before we finish it
4252            TaskRecord tr = r.task;
4253            ActivityRecord rootR = tr.getRootActivity();
4254            if (rootR == null) {
4255                Slog.w(TAG, "Finishing task with all activities already finished");
4256            }
4257            // Do not allow task to finish in Lock Task mode.
4258            if (tr == mStackSupervisor.mLockTaskModeTask) {
4259                if (rootR == r) {
4260                    Slog.i(TAG, "Not finishing task in lock task mode");
4261                    mStackSupervisor.showLockTaskToast();
4262                    return false;
4263                }
4264            }
4265            if (mController != null) {
4266                // Find the first activity that is not finishing.
4267                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4268                if (next != null) {
4269                    // ask watcher if this is allowed
4270                    boolean resumeOK = true;
4271                    try {
4272                        resumeOK = mController.activityResuming(next.packageName);
4273                    } catch (RemoteException e) {
4274                        mController = null;
4275                        Watchdog.getInstance().setActivityController(null);
4276                    }
4277
4278                    if (!resumeOK) {
4279                        Slog.i(TAG, "Not finishing activity because controller resumed");
4280                        return false;
4281                    }
4282                }
4283            }
4284            final long origId = Binder.clearCallingIdentity();
4285            try {
4286                boolean res;
4287                if (finishTask && r == rootR) {
4288                    // If requested, remove the task that is associated to this activity only if it
4289                    // was the root activity in the task. The result code and data is ignored
4290                    // because we don't support returning them across task boundaries.
4291                    res = removeTaskByIdLocked(tr.taskId, false);
4292                    if (!res) {
4293                        Slog.i(TAG, "Removing task failed to finish activity");
4294                    }
4295                } else {
4296                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4297                            resultData, "app-request", true);
4298                    if (!res) {
4299                        Slog.i(TAG, "Failed to finish by app-request");
4300                    }
4301                }
4302                return res;
4303            } finally {
4304                Binder.restoreCallingIdentity(origId);
4305            }
4306        }
4307    }
4308
4309    @Override
4310    public final void finishHeavyWeightApp() {
4311        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4312                != PackageManager.PERMISSION_GRANTED) {
4313            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4314                    + Binder.getCallingPid()
4315                    + ", uid=" + Binder.getCallingUid()
4316                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4317            Slog.w(TAG, msg);
4318            throw new SecurityException(msg);
4319        }
4320
4321        synchronized(this) {
4322            if (mHeavyWeightProcess == null) {
4323                return;
4324            }
4325
4326            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4327                    mHeavyWeightProcess.activities);
4328            for (int i=0; i<activities.size(); i++) {
4329                ActivityRecord r = activities.get(i);
4330                if (!r.finishing) {
4331                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4332                            null, "finish-heavy", true);
4333                }
4334            }
4335
4336            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4337                    mHeavyWeightProcess.userId, 0));
4338            mHeavyWeightProcess = null;
4339        }
4340    }
4341
4342    @Override
4343    public void crashApplication(int uid, int initialPid, String packageName,
4344            String message) {
4345        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4346                != PackageManager.PERMISSION_GRANTED) {
4347            String msg = "Permission Denial: crashApplication() from pid="
4348                    + Binder.getCallingPid()
4349                    + ", uid=" + Binder.getCallingUid()
4350                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4351            Slog.w(TAG, msg);
4352            throw new SecurityException(msg);
4353        }
4354
4355        synchronized(this) {
4356            ProcessRecord proc = null;
4357
4358            // Figure out which process to kill.  We don't trust that initialPid
4359            // still has any relation to current pids, so must scan through the
4360            // list.
4361            synchronized (mPidsSelfLocked) {
4362                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4363                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4364                    if (p.uid != uid) {
4365                        continue;
4366                    }
4367                    if (p.pid == initialPid) {
4368                        proc = p;
4369                        break;
4370                    }
4371                    if (p.pkgList.containsKey(packageName)) {
4372                        proc = p;
4373                    }
4374                }
4375            }
4376
4377            if (proc == null) {
4378                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4379                        + " initialPid=" + initialPid
4380                        + " packageName=" + packageName);
4381                return;
4382            }
4383
4384            if (proc.thread != null) {
4385                if (proc.pid == Process.myPid()) {
4386                    Log.w(TAG, "crashApplication: trying to crash self!");
4387                    return;
4388                }
4389                long ident = Binder.clearCallingIdentity();
4390                try {
4391                    proc.thread.scheduleCrash(message);
4392                } catch (RemoteException e) {
4393                }
4394                Binder.restoreCallingIdentity(ident);
4395            }
4396        }
4397    }
4398
4399    @Override
4400    public final void finishSubActivity(IBinder token, String resultWho,
4401            int requestCode) {
4402        synchronized(this) {
4403            final long origId = Binder.clearCallingIdentity();
4404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4405            if (r != null) {
4406                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4407            }
4408            Binder.restoreCallingIdentity(origId);
4409        }
4410    }
4411
4412    @Override
4413    public boolean finishActivityAffinity(IBinder token) {
4414        synchronized(this) {
4415            final long origId = Binder.clearCallingIdentity();
4416            try {
4417                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4418
4419                ActivityRecord rootR = r.task.getRootActivity();
4420                // Do not allow task to finish in Lock Task mode.
4421                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4422                    if (rootR == r) {
4423                        mStackSupervisor.showLockTaskToast();
4424                        return false;
4425                    }
4426                }
4427                boolean res = false;
4428                if (r != null) {
4429                    res = r.task.stack.finishActivityAffinityLocked(r);
4430                }
4431                return res;
4432            } finally {
4433                Binder.restoreCallingIdentity(origId);
4434            }
4435        }
4436    }
4437
4438    @Override
4439    public void finishVoiceTask(IVoiceInteractionSession session) {
4440        synchronized(this) {
4441            final long origId = Binder.clearCallingIdentity();
4442            try {
4443                mStackSupervisor.finishVoiceTask(session);
4444            } finally {
4445                Binder.restoreCallingIdentity(origId);
4446            }
4447        }
4448
4449    }
4450
4451    @Override
4452    public boolean releaseActivityInstance(IBinder token) {
4453        synchronized(this) {
4454            final long origId = Binder.clearCallingIdentity();
4455            try {
4456                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4457                if (r.task == null || r.task.stack == null) {
4458                    return false;
4459                }
4460                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4461            } finally {
4462                Binder.restoreCallingIdentity(origId);
4463            }
4464        }
4465    }
4466
4467    @Override
4468    public void releaseSomeActivities(IApplicationThread appInt) {
4469        synchronized(this) {
4470            final long origId = Binder.clearCallingIdentity();
4471            try {
4472                ProcessRecord app = getRecordForAppLocked(appInt);
4473                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4474            } finally {
4475                Binder.restoreCallingIdentity(origId);
4476            }
4477        }
4478    }
4479
4480    @Override
4481    public boolean willActivityBeVisible(IBinder token) {
4482        synchronized(this) {
4483            ActivityStack stack = ActivityRecord.getStackLocked(token);
4484            if (stack != null) {
4485                return stack.willActivityBeVisibleLocked(token);
4486            }
4487            return false;
4488        }
4489    }
4490
4491    @Override
4492    public void overridePendingTransition(IBinder token, String packageName,
4493            int enterAnim, int exitAnim) {
4494        synchronized(this) {
4495            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4496            if (self == null) {
4497                return;
4498            }
4499
4500            final long origId = Binder.clearCallingIdentity();
4501
4502            if (self.state == ActivityState.RESUMED
4503                    || self.state == ActivityState.PAUSING) {
4504                mWindowManager.overridePendingAppTransition(packageName,
4505                        enterAnim, exitAnim, null);
4506            }
4507
4508            Binder.restoreCallingIdentity(origId);
4509        }
4510    }
4511
4512    /**
4513     * Main function for removing an existing process from the activity manager
4514     * as a result of that process going away.  Clears out all connections
4515     * to the process.
4516     */
4517    private final void handleAppDiedLocked(ProcessRecord app,
4518            boolean restarting, boolean allowRestart) {
4519        int pid = app.pid;
4520        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4521        if (!kept && !restarting) {
4522            removeLruProcessLocked(app);
4523            if (pid > 0) {
4524                ProcessList.remove(pid);
4525            }
4526        }
4527
4528        if (mProfileProc == app) {
4529            clearProfilerLocked();
4530        }
4531
4532        // Remove this application's activities from active lists.
4533        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4534
4535        app.activities.clear();
4536
4537        if (app.instrumentationClass != null) {
4538            Slog.w(TAG, "Crash of app " + app.processName
4539                  + " running instrumentation " + app.instrumentationClass);
4540            Bundle info = new Bundle();
4541            info.putString("shortMsg", "Process crashed.");
4542            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4543        }
4544
4545        if (!restarting) {
4546            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4547                // If there was nothing to resume, and we are not already
4548                // restarting this process, but there is a visible activity that
4549                // is hosted by the process...  then make sure all visible
4550                // activities are running, taking care of restarting this
4551                // process.
4552                if (hasVisibleActivities) {
4553                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4554                }
4555            }
4556        }
4557    }
4558
4559    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4560        IBinder threadBinder = thread.asBinder();
4561        // Find the application record.
4562        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4563            ProcessRecord rec = mLruProcesses.get(i);
4564            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4565                return i;
4566            }
4567        }
4568        return -1;
4569    }
4570
4571    final ProcessRecord getRecordForAppLocked(
4572            IApplicationThread thread) {
4573        if (thread == null) {
4574            return null;
4575        }
4576
4577        int appIndex = getLRURecordIndexForAppLocked(thread);
4578        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4579    }
4580
4581    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4582        // If there are no longer any background processes running,
4583        // and the app that died was not running instrumentation,
4584        // then tell everyone we are now low on memory.
4585        boolean haveBg = false;
4586        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4587            ProcessRecord rec = mLruProcesses.get(i);
4588            if (rec.thread != null
4589                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4590                haveBg = true;
4591                break;
4592            }
4593        }
4594
4595        if (!haveBg) {
4596            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4597            if (doReport) {
4598                long now = SystemClock.uptimeMillis();
4599                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4600                    doReport = false;
4601                } else {
4602                    mLastMemUsageReportTime = now;
4603                }
4604            }
4605            final ArrayList<ProcessMemInfo> memInfos
4606                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4607            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4608            long now = SystemClock.uptimeMillis();
4609            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4610                ProcessRecord rec = mLruProcesses.get(i);
4611                if (rec == dyingProc || rec.thread == null) {
4612                    continue;
4613                }
4614                if (doReport) {
4615                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4616                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4617                }
4618                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4619                    // The low memory report is overriding any current
4620                    // state for a GC request.  Make sure to do
4621                    // heavy/important/visible/foreground processes first.
4622                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4623                        rec.lastRequestedGc = 0;
4624                    } else {
4625                        rec.lastRequestedGc = rec.lastLowMemory;
4626                    }
4627                    rec.reportLowMemory = true;
4628                    rec.lastLowMemory = now;
4629                    mProcessesToGc.remove(rec);
4630                    addProcessToGcListLocked(rec);
4631                }
4632            }
4633            if (doReport) {
4634                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4635                mHandler.sendMessage(msg);
4636            }
4637            scheduleAppGcsLocked();
4638        }
4639    }
4640
4641    final void appDiedLocked(ProcessRecord app) {
4642       appDiedLocked(app, app.pid, app.thread);
4643    }
4644
4645    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4646        // First check if this ProcessRecord is actually active for the pid.
4647        synchronized (mPidsSelfLocked) {
4648            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4649            if (curProc != app) {
4650                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4651                return;
4652            }
4653        }
4654
4655        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4656        synchronized (stats) {
4657            stats.noteProcessDiedLocked(app.info.uid, pid);
4658        }
4659
4660        if (!app.killed) {
4661            Process.killProcessQuiet(pid);
4662            Process.killProcessGroup(app.info.uid, pid);
4663            app.killed = true;
4664        }
4665
4666        // Clean up already done if the process has been re-started.
4667        if (app.pid == pid && app.thread != null &&
4668                app.thread.asBinder() == thread.asBinder()) {
4669            boolean doLowMem = app.instrumentationClass == null;
4670            boolean doOomAdj = doLowMem;
4671            if (!app.killedByAm) {
4672                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4673                        + ") has died");
4674                mAllowLowerMemLevel = true;
4675            } else {
4676                // Note that we always want to do oom adj to update our state with the
4677                // new number of procs.
4678                mAllowLowerMemLevel = false;
4679                doLowMem = false;
4680            }
4681            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4682            if (DEBUG_CLEANUP) Slog.v(
4683                TAG, "Dying app: " + app + ", pid: " + pid
4684                + ", thread: " + thread.asBinder());
4685            handleAppDiedLocked(app, false, true);
4686
4687            if (doOomAdj) {
4688                updateOomAdjLocked();
4689            }
4690            if (doLowMem) {
4691                doLowMemReportIfNeededLocked(app);
4692            }
4693        } else if (app.pid != pid) {
4694            // A new process has already been started.
4695            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4696                    + ") has died and restarted (pid " + app.pid + ").");
4697            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4698        } else if (DEBUG_PROCESSES) {
4699            Slog.d(TAG, "Received spurious death notification for thread "
4700                    + thread.asBinder());
4701        }
4702    }
4703
4704    /**
4705     * If a stack trace dump file is configured, dump process stack traces.
4706     * @param clearTraces causes the dump file to be erased prior to the new
4707     *    traces being written, if true; when false, the new traces will be
4708     *    appended to any existing file content.
4709     * @param firstPids of dalvik VM processes to dump stack traces for first
4710     * @param lastPids of dalvik VM processes to dump stack traces for last
4711     * @param nativeProcs optional list of native process names to dump stack crawls
4712     * @return file containing stack traces, or null if no dump file is configured
4713     */
4714    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4715            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4716        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4717        if (tracesPath == null || tracesPath.length() == 0) {
4718            return null;
4719        }
4720
4721        File tracesFile = new File(tracesPath);
4722        try {
4723            File tracesDir = tracesFile.getParentFile();
4724            if (!tracesDir.exists()) {
4725                tracesDir.mkdirs();
4726                if (!SELinux.restorecon(tracesDir)) {
4727                    return null;
4728                }
4729            }
4730            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4731
4732            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4733            tracesFile.createNewFile();
4734            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4735        } catch (IOException e) {
4736            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4737            return null;
4738        }
4739
4740        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4741        return tracesFile;
4742    }
4743
4744    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4745            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4746        // Use a FileObserver to detect when traces finish writing.
4747        // The order of traces is considered important to maintain for legibility.
4748        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4749            @Override
4750            public synchronized void onEvent(int event, String path) { notify(); }
4751        };
4752
4753        try {
4754            observer.startWatching();
4755
4756            // First collect all of the stacks of the most important pids.
4757            if (firstPids != null) {
4758                try {
4759                    int num = firstPids.size();
4760                    for (int i = 0; i < num; i++) {
4761                        synchronized (observer) {
4762                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4763                            observer.wait(200);  // Wait for write-close, give up after 200msec
4764                        }
4765                    }
4766                } catch (InterruptedException e) {
4767                    Slog.wtf(TAG, e);
4768                }
4769            }
4770
4771            // Next collect the stacks of the native pids
4772            if (nativeProcs != null) {
4773                int[] pids = Process.getPidsForCommands(nativeProcs);
4774                if (pids != null) {
4775                    for (int pid : pids) {
4776                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4777                    }
4778                }
4779            }
4780
4781            // Lastly, measure CPU usage.
4782            if (processCpuTracker != null) {
4783                processCpuTracker.init();
4784                System.gc();
4785                processCpuTracker.update();
4786                try {
4787                    synchronized (processCpuTracker) {
4788                        processCpuTracker.wait(500); // measure over 1/2 second.
4789                    }
4790                } catch (InterruptedException e) {
4791                }
4792                processCpuTracker.update();
4793
4794                // We'll take the stack crawls of just the top apps using CPU.
4795                final int N = processCpuTracker.countWorkingStats();
4796                int numProcs = 0;
4797                for (int i=0; i<N && numProcs<5; i++) {
4798                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4799                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4800                        numProcs++;
4801                        try {
4802                            synchronized (observer) {
4803                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4804                                observer.wait(200);  // Wait for write-close, give up after 200msec
4805                            }
4806                        } catch (InterruptedException e) {
4807                            Slog.wtf(TAG, e);
4808                        }
4809
4810                    }
4811                }
4812            }
4813        } finally {
4814            observer.stopWatching();
4815        }
4816    }
4817
4818    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4819        if (true || IS_USER_BUILD) {
4820            return;
4821        }
4822        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4823        if (tracesPath == null || tracesPath.length() == 0) {
4824            return;
4825        }
4826
4827        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4828        StrictMode.allowThreadDiskWrites();
4829        try {
4830            final File tracesFile = new File(tracesPath);
4831            final File tracesDir = tracesFile.getParentFile();
4832            final File tracesTmp = new File(tracesDir, "__tmp__");
4833            try {
4834                if (!tracesDir.exists()) {
4835                    tracesDir.mkdirs();
4836                    if (!SELinux.restorecon(tracesDir.getPath())) {
4837                        return;
4838                    }
4839                }
4840                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4841
4842                if (tracesFile.exists()) {
4843                    tracesTmp.delete();
4844                    tracesFile.renameTo(tracesTmp);
4845                }
4846                StringBuilder sb = new StringBuilder();
4847                Time tobj = new Time();
4848                tobj.set(System.currentTimeMillis());
4849                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4850                sb.append(": ");
4851                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4852                sb.append(" since ");
4853                sb.append(msg);
4854                FileOutputStream fos = new FileOutputStream(tracesFile);
4855                fos.write(sb.toString().getBytes());
4856                if (app == null) {
4857                    fos.write("\n*** No application process!".getBytes());
4858                }
4859                fos.close();
4860                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4861            } catch (IOException e) {
4862                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4863                return;
4864            }
4865
4866            if (app != null) {
4867                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4868                firstPids.add(app.pid);
4869                dumpStackTraces(tracesPath, firstPids, null, null, null);
4870            }
4871
4872            File lastTracesFile = null;
4873            File curTracesFile = null;
4874            for (int i=9; i>=0; i--) {
4875                String name = String.format(Locale.US, "slow%02d.txt", i);
4876                curTracesFile = new File(tracesDir, name);
4877                if (curTracesFile.exists()) {
4878                    if (lastTracesFile != null) {
4879                        curTracesFile.renameTo(lastTracesFile);
4880                    } else {
4881                        curTracesFile.delete();
4882                    }
4883                }
4884                lastTracesFile = curTracesFile;
4885            }
4886            tracesFile.renameTo(curTracesFile);
4887            if (tracesTmp.exists()) {
4888                tracesTmp.renameTo(tracesFile);
4889            }
4890        } finally {
4891            StrictMode.setThreadPolicy(oldPolicy);
4892        }
4893    }
4894
4895    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4896            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4897        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4898        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4899
4900        if (mController != null) {
4901            try {
4902                // 0 == continue, -1 = kill process immediately
4903                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4904                if (res < 0 && app.pid != MY_PID) {
4905                    app.kill("anr", true);
4906                }
4907            } catch (RemoteException e) {
4908                mController = null;
4909                Watchdog.getInstance().setActivityController(null);
4910            }
4911        }
4912
4913        long anrTime = SystemClock.uptimeMillis();
4914        if (MONITOR_CPU_USAGE) {
4915            updateCpuStatsNow();
4916        }
4917
4918        synchronized (this) {
4919            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4920            if (mShuttingDown) {
4921                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4922                return;
4923            } else if (app.notResponding) {
4924                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4925                return;
4926            } else if (app.crashing) {
4927                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4928                return;
4929            }
4930
4931            // In case we come through here for the same app before completing
4932            // this one, mark as anring now so we will bail out.
4933            app.notResponding = true;
4934
4935            // Log the ANR to the event log.
4936            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4937                    app.processName, app.info.flags, annotation);
4938
4939            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4940            firstPids.add(app.pid);
4941
4942            int parentPid = app.pid;
4943            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4944            if (parentPid != app.pid) firstPids.add(parentPid);
4945
4946            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4947
4948            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4949                ProcessRecord r = mLruProcesses.get(i);
4950                if (r != null && r.thread != null) {
4951                    int pid = r.pid;
4952                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4953                        if (r.persistent) {
4954                            firstPids.add(pid);
4955                        } else {
4956                            lastPids.put(pid, Boolean.TRUE);
4957                        }
4958                    }
4959                }
4960            }
4961        }
4962
4963        // Log the ANR to the main log.
4964        StringBuilder info = new StringBuilder();
4965        info.setLength(0);
4966        info.append("ANR in ").append(app.processName);
4967        if (activity != null && activity.shortComponentName != null) {
4968            info.append(" (").append(activity.shortComponentName).append(")");
4969        }
4970        info.append("\n");
4971        info.append("PID: ").append(app.pid).append("\n");
4972        if (annotation != null) {
4973            info.append("Reason: ").append(annotation).append("\n");
4974        }
4975        if (parent != null && parent != activity) {
4976            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4977        }
4978
4979        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4980
4981        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4982                NATIVE_STACKS_OF_INTEREST);
4983
4984        String cpuInfo = null;
4985        if (MONITOR_CPU_USAGE) {
4986            updateCpuStatsNow();
4987            synchronized (mProcessCpuTracker) {
4988                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4989            }
4990            info.append(processCpuTracker.printCurrentLoad());
4991            info.append(cpuInfo);
4992        }
4993
4994        info.append(processCpuTracker.printCurrentState(anrTime));
4995
4996        Slog.e(TAG, info.toString());
4997        if (tracesFile == null) {
4998            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4999            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5000        }
5001
5002        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5003                cpuInfo, tracesFile, null);
5004
5005        if (mController != null) {
5006            try {
5007                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5008                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5009                if (res != 0) {
5010                    if (res < 0 && app.pid != MY_PID) {
5011                        app.kill("anr", true);
5012                    } else {
5013                        synchronized (this) {
5014                            mServices.scheduleServiceTimeoutLocked(app);
5015                        }
5016                    }
5017                    return;
5018                }
5019            } catch (RemoteException e) {
5020                mController = null;
5021                Watchdog.getInstance().setActivityController(null);
5022            }
5023        }
5024
5025        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5026        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5027                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5028
5029        synchronized (this) {
5030            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5031
5032            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5033                app.kill("bg anr", true);
5034                return;
5035            }
5036
5037            // Set the app's notResponding state, and look up the errorReportReceiver
5038            makeAppNotRespondingLocked(app,
5039                    activity != null ? activity.shortComponentName : null,
5040                    annotation != null ? "ANR " + annotation : "ANR",
5041                    info.toString());
5042
5043            // Bring up the infamous App Not Responding dialog
5044            Message msg = Message.obtain();
5045            HashMap<String, Object> map = new HashMap<String, Object>();
5046            msg.what = SHOW_NOT_RESPONDING_MSG;
5047            msg.obj = map;
5048            msg.arg1 = aboveSystem ? 1 : 0;
5049            map.put("app", app);
5050            if (activity != null) {
5051                map.put("activity", activity);
5052            }
5053
5054            mHandler.sendMessage(msg);
5055        }
5056    }
5057
5058    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5059        if (!mLaunchWarningShown) {
5060            mLaunchWarningShown = true;
5061            mHandler.post(new Runnable() {
5062                @Override
5063                public void run() {
5064                    synchronized (ActivityManagerService.this) {
5065                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5066                        d.show();
5067                        mHandler.postDelayed(new Runnable() {
5068                            @Override
5069                            public void run() {
5070                                synchronized (ActivityManagerService.this) {
5071                                    d.dismiss();
5072                                    mLaunchWarningShown = false;
5073                                }
5074                            }
5075                        }, 4000);
5076                    }
5077                }
5078            });
5079        }
5080    }
5081
5082    @Override
5083    public boolean clearApplicationUserData(final String packageName,
5084            final IPackageDataObserver observer, int userId) {
5085        enforceNotIsolatedCaller("clearApplicationUserData");
5086        int uid = Binder.getCallingUid();
5087        int pid = Binder.getCallingPid();
5088        userId = handleIncomingUser(pid, uid,
5089                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5090        long callingId = Binder.clearCallingIdentity();
5091        try {
5092            IPackageManager pm = AppGlobals.getPackageManager();
5093            int pkgUid = -1;
5094            synchronized(this) {
5095                try {
5096                    pkgUid = pm.getPackageUid(packageName, userId);
5097                } catch (RemoteException e) {
5098                }
5099                if (pkgUid == -1) {
5100                    Slog.w(TAG, "Invalid packageName: " + packageName);
5101                    if (observer != null) {
5102                        try {
5103                            observer.onRemoveCompleted(packageName, false);
5104                        } catch (RemoteException e) {
5105                            Slog.i(TAG, "Observer no longer exists.");
5106                        }
5107                    }
5108                    return false;
5109                }
5110                if (uid == pkgUid || checkComponentPermission(
5111                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5112                        pid, uid, -1, true)
5113                        == PackageManager.PERMISSION_GRANTED) {
5114                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5115                } else {
5116                    throw new SecurityException("PID " + pid + " does not have permission "
5117                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5118                                    + " of package " + packageName);
5119                }
5120
5121                // Remove all tasks match the cleared application package and user
5122                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5123                    final TaskRecord tr = mRecentTasks.get(i);
5124                    final String taskPackageName =
5125                            tr.getBaseIntent().getComponent().getPackageName();
5126                    if (tr.userId != userId) continue;
5127                    if (!taskPackageName.equals(packageName)) continue;
5128                    removeTaskByIdLocked(tr.taskId, false);
5129                }
5130            }
5131
5132            try {
5133                // Clear application user data
5134                pm.clearApplicationUserData(packageName, observer, userId);
5135
5136                synchronized(this) {
5137                    // Remove all permissions granted from/to this package
5138                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5139                }
5140
5141                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5142                        Uri.fromParts("package", packageName, null));
5143                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5144                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5145                        null, null, 0, null, null, null, false, false, userId);
5146            } catch (RemoteException e) {
5147            }
5148        } finally {
5149            Binder.restoreCallingIdentity(callingId);
5150        }
5151        return true;
5152    }
5153
5154    @Override
5155    public void killBackgroundProcesses(final String packageName, int userId) {
5156        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5157                != PackageManager.PERMISSION_GRANTED &&
5158                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5159                        != PackageManager.PERMISSION_GRANTED) {
5160            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5161                    + Binder.getCallingPid()
5162                    + ", uid=" + Binder.getCallingUid()
5163                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5164            Slog.w(TAG, msg);
5165            throw new SecurityException(msg);
5166        }
5167
5168        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5169                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5170        long callingId = Binder.clearCallingIdentity();
5171        try {
5172            IPackageManager pm = AppGlobals.getPackageManager();
5173            synchronized(this) {
5174                int appId = -1;
5175                try {
5176                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5177                } catch (RemoteException e) {
5178                }
5179                if (appId == -1) {
5180                    Slog.w(TAG, "Invalid packageName: " + packageName);
5181                    return;
5182                }
5183                killPackageProcessesLocked(packageName, appId, userId,
5184                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5185            }
5186        } finally {
5187            Binder.restoreCallingIdentity(callingId);
5188        }
5189    }
5190
5191    @Override
5192    public void killAllBackgroundProcesses() {
5193        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5194                != PackageManager.PERMISSION_GRANTED) {
5195            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5196                    + Binder.getCallingPid()
5197                    + ", uid=" + Binder.getCallingUid()
5198                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5199            Slog.w(TAG, msg);
5200            throw new SecurityException(msg);
5201        }
5202
5203        long callingId = Binder.clearCallingIdentity();
5204        try {
5205            synchronized(this) {
5206                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5207                final int NP = mProcessNames.getMap().size();
5208                for (int ip=0; ip<NP; ip++) {
5209                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5210                    final int NA = apps.size();
5211                    for (int ia=0; ia<NA; ia++) {
5212                        ProcessRecord app = apps.valueAt(ia);
5213                        if (app.persistent) {
5214                            // we don't kill persistent processes
5215                            continue;
5216                        }
5217                        if (app.removed) {
5218                            procs.add(app);
5219                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5220                            app.removed = true;
5221                            procs.add(app);
5222                        }
5223                    }
5224                }
5225
5226                int N = procs.size();
5227                for (int i=0; i<N; i++) {
5228                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5229                }
5230                mAllowLowerMemLevel = true;
5231                updateOomAdjLocked();
5232                doLowMemReportIfNeededLocked(null);
5233            }
5234        } finally {
5235            Binder.restoreCallingIdentity(callingId);
5236        }
5237    }
5238
5239    @Override
5240    public void forceStopPackage(final String packageName, int userId) {
5241        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5242                != PackageManager.PERMISSION_GRANTED) {
5243            String msg = "Permission Denial: forceStopPackage() from pid="
5244                    + Binder.getCallingPid()
5245                    + ", uid=" + Binder.getCallingUid()
5246                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5247            Slog.w(TAG, msg);
5248            throw new SecurityException(msg);
5249        }
5250        final int callingPid = Binder.getCallingPid();
5251        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5252                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5253        long callingId = Binder.clearCallingIdentity();
5254        try {
5255            IPackageManager pm = AppGlobals.getPackageManager();
5256            synchronized(this) {
5257                int[] users = userId == UserHandle.USER_ALL
5258                        ? getUsersLocked() : new int[] { userId };
5259                for (int user : users) {
5260                    int pkgUid = -1;
5261                    try {
5262                        pkgUid = pm.getPackageUid(packageName, user);
5263                    } catch (RemoteException e) {
5264                    }
5265                    if (pkgUid == -1) {
5266                        Slog.w(TAG, "Invalid packageName: " + packageName);
5267                        continue;
5268                    }
5269                    try {
5270                        pm.setPackageStoppedState(packageName, true, user);
5271                    } catch (RemoteException e) {
5272                    } catch (IllegalArgumentException e) {
5273                        Slog.w(TAG, "Failed trying to unstop package "
5274                                + packageName + ": " + e);
5275                    }
5276                    if (isUserRunningLocked(user, false)) {
5277                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5278                    }
5279                }
5280            }
5281        } finally {
5282            Binder.restoreCallingIdentity(callingId);
5283        }
5284    }
5285
5286    @Override
5287    public void addPackageDependency(String packageName) {
5288        synchronized (this) {
5289            int callingPid = Binder.getCallingPid();
5290            if (callingPid == Process.myPid()) {
5291                //  Yeah, um, no.
5292                Slog.w(TAG, "Can't addPackageDependency on system process");
5293                return;
5294            }
5295            ProcessRecord proc;
5296            synchronized (mPidsSelfLocked) {
5297                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5298            }
5299            if (proc != null) {
5300                if (proc.pkgDeps == null) {
5301                    proc.pkgDeps = new ArraySet<String>(1);
5302                }
5303                proc.pkgDeps.add(packageName);
5304            }
5305        }
5306    }
5307
5308    /*
5309     * The pkg name and app id have to be specified.
5310     */
5311    @Override
5312    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5313        if (pkg == null) {
5314            return;
5315        }
5316        // Make sure the uid is valid.
5317        if (appid < 0) {
5318            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5319            return;
5320        }
5321        int callerUid = Binder.getCallingUid();
5322        // Only the system server can kill an application
5323        if (callerUid == Process.SYSTEM_UID) {
5324            // Post an aysnc message to kill the application
5325            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5326            msg.arg1 = appid;
5327            msg.arg2 = 0;
5328            Bundle bundle = new Bundle();
5329            bundle.putString("pkg", pkg);
5330            bundle.putString("reason", reason);
5331            msg.obj = bundle;
5332            mHandler.sendMessage(msg);
5333        } else {
5334            throw new SecurityException(callerUid + " cannot kill pkg: " +
5335                    pkg);
5336        }
5337    }
5338
5339    @Override
5340    public void closeSystemDialogs(String reason) {
5341        enforceNotIsolatedCaller("closeSystemDialogs");
5342
5343        final int pid = Binder.getCallingPid();
5344        final int uid = Binder.getCallingUid();
5345        final long origId = Binder.clearCallingIdentity();
5346        try {
5347            synchronized (this) {
5348                // Only allow this from foreground processes, so that background
5349                // applications can't abuse it to prevent system UI from being shown.
5350                if (uid >= Process.FIRST_APPLICATION_UID) {
5351                    ProcessRecord proc;
5352                    synchronized (mPidsSelfLocked) {
5353                        proc = mPidsSelfLocked.get(pid);
5354                    }
5355                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5356                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5357                                + " from background process " + proc);
5358                        return;
5359                    }
5360                }
5361                closeSystemDialogsLocked(reason);
5362            }
5363        } finally {
5364            Binder.restoreCallingIdentity(origId);
5365        }
5366    }
5367
5368    void closeSystemDialogsLocked(String reason) {
5369        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5370        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5371                | Intent.FLAG_RECEIVER_FOREGROUND);
5372        if (reason != null) {
5373            intent.putExtra("reason", reason);
5374        }
5375        mWindowManager.closeSystemDialogs(reason);
5376
5377        mStackSupervisor.closeSystemDialogsLocked();
5378
5379        broadcastIntentLocked(null, null, intent, null,
5380                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5381                Process.SYSTEM_UID, UserHandle.USER_ALL);
5382    }
5383
5384    @Override
5385    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5386        enforceNotIsolatedCaller("getProcessMemoryInfo");
5387        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5388        for (int i=pids.length-1; i>=0; i--) {
5389            ProcessRecord proc;
5390            int oomAdj;
5391            synchronized (this) {
5392                synchronized (mPidsSelfLocked) {
5393                    proc = mPidsSelfLocked.get(pids[i]);
5394                    oomAdj = proc != null ? proc.setAdj : 0;
5395                }
5396            }
5397            infos[i] = new Debug.MemoryInfo();
5398            Debug.getMemoryInfo(pids[i], infos[i]);
5399            if (proc != null) {
5400                synchronized (this) {
5401                    if (proc.thread != null && proc.setAdj == oomAdj) {
5402                        // Record this for posterity if the process has been stable.
5403                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5404                                infos[i].getTotalUss(), false, proc.pkgList);
5405                    }
5406                }
5407            }
5408        }
5409        return infos;
5410    }
5411
5412    @Override
5413    public long[] getProcessPss(int[] pids) {
5414        enforceNotIsolatedCaller("getProcessPss");
5415        long[] pss = new long[pids.length];
5416        for (int i=pids.length-1; i>=0; i--) {
5417            ProcessRecord proc;
5418            int oomAdj;
5419            synchronized (this) {
5420                synchronized (mPidsSelfLocked) {
5421                    proc = mPidsSelfLocked.get(pids[i]);
5422                    oomAdj = proc != null ? proc.setAdj : 0;
5423                }
5424            }
5425            long[] tmpUss = new long[1];
5426            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5427            if (proc != null) {
5428                synchronized (this) {
5429                    if (proc.thread != null && proc.setAdj == oomAdj) {
5430                        // Record this for posterity if the process has been stable.
5431                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5432                    }
5433                }
5434            }
5435        }
5436        return pss;
5437    }
5438
5439    @Override
5440    public void killApplicationProcess(String processName, int uid) {
5441        if (processName == null) {
5442            return;
5443        }
5444
5445        int callerUid = Binder.getCallingUid();
5446        // Only the system server can kill an application
5447        if (callerUid == Process.SYSTEM_UID) {
5448            synchronized (this) {
5449                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5450                if (app != null && app.thread != null) {
5451                    try {
5452                        app.thread.scheduleSuicide();
5453                    } catch (RemoteException e) {
5454                        // If the other end already died, then our work here is done.
5455                    }
5456                } else {
5457                    Slog.w(TAG, "Process/uid not found attempting kill of "
5458                            + processName + " / " + uid);
5459                }
5460            }
5461        } else {
5462            throw new SecurityException(callerUid + " cannot kill app process: " +
5463                    processName);
5464        }
5465    }
5466
5467    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5468        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5469                false, true, false, false, UserHandle.getUserId(uid), reason);
5470        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5471                Uri.fromParts("package", packageName, null));
5472        if (!mProcessesReady) {
5473            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5474                    | Intent.FLAG_RECEIVER_FOREGROUND);
5475        }
5476        intent.putExtra(Intent.EXTRA_UID, uid);
5477        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5478        broadcastIntentLocked(null, null, intent,
5479                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5480                false, false,
5481                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5482    }
5483
5484    private void forceStopUserLocked(int userId, String reason) {
5485        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5486        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5487        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5488                | Intent.FLAG_RECEIVER_FOREGROUND);
5489        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5490        broadcastIntentLocked(null, null, intent,
5491                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5492                false, false,
5493                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5494    }
5495
5496    private final boolean killPackageProcessesLocked(String packageName, int appId,
5497            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5498            boolean doit, boolean evenPersistent, String reason) {
5499        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5500
5501        // Remove all processes this package may have touched: all with the
5502        // same UID (except for the system or root user), and all whose name
5503        // matches the package name.
5504        final int NP = mProcessNames.getMap().size();
5505        for (int ip=0; ip<NP; ip++) {
5506            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5507            final int NA = apps.size();
5508            for (int ia=0; ia<NA; ia++) {
5509                ProcessRecord app = apps.valueAt(ia);
5510                if (app.persistent && !evenPersistent) {
5511                    // we don't kill persistent processes
5512                    continue;
5513                }
5514                if (app.removed) {
5515                    if (doit) {
5516                        procs.add(app);
5517                    }
5518                    continue;
5519                }
5520
5521                // Skip process if it doesn't meet our oom adj requirement.
5522                if (app.setAdj < minOomAdj) {
5523                    continue;
5524                }
5525
5526                // If no package is specified, we call all processes under the
5527                // give user id.
5528                if (packageName == null) {
5529                    if (app.userId != userId) {
5530                        continue;
5531                    }
5532                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5533                        continue;
5534                    }
5535                // Package has been specified, we want to hit all processes
5536                // that match it.  We need to qualify this by the processes
5537                // that are running under the specified app and user ID.
5538                } else {
5539                    final boolean isDep = app.pkgDeps != null
5540                            && app.pkgDeps.contains(packageName);
5541                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5542                        continue;
5543                    }
5544                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5545                        continue;
5546                    }
5547                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5548                        continue;
5549                    }
5550                }
5551
5552                // Process has passed all conditions, kill it!
5553                if (!doit) {
5554                    return true;
5555                }
5556                app.removed = true;
5557                procs.add(app);
5558            }
5559        }
5560
5561        int N = procs.size();
5562        for (int i=0; i<N; i++) {
5563            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5564        }
5565        updateOomAdjLocked();
5566        return N > 0;
5567    }
5568
5569    private final boolean forceStopPackageLocked(String name, int appId,
5570            boolean callerWillRestart, boolean purgeCache, boolean doit,
5571            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5572        int i;
5573        int N;
5574
5575        if (userId == UserHandle.USER_ALL && name == null) {
5576            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5577        }
5578
5579        if (appId < 0 && name != null) {
5580            try {
5581                appId = UserHandle.getAppId(
5582                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5583            } catch (RemoteException e) {
5584            }
5585        }
5586
5587        if (doit) {
5588            if (name != null) {
5589                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5590                        + " user=" + userId + ": " + reason);
5591            } else {
5592                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5593            }
5594
5595            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5596            for (int ip=pmap.size()-1; ip>=0; ip--) {
5597                SparseArray<Long> ba = pmap.valueAt(ip);
5598                for (i=ba.size()-1; i>=0; i--) {
5599                    boolean remove = false;
5600                    final int entUid = ba.keyAt(i);
5601                    if (name != null) {
5602                        if (userId == UserHandle.USER_ALL) {
5603                            if (UserHandle.getAppId(entUid) == appId) {
5604                                remove = true;
5605                            }
5606                        } else {
5607                            if (entUid == UserHandle.getUid(userId, appId)) {
5608                                remove = true;
5609                            }
5610                        }
5611                    } else if (UserHandle.getUserId(entUid) == userId) {
5612                        remove = true;
5613                    }
5614                    if (remove) {
5615                        ba.removeAt(i);
5616                    }
5617                }
5618                if (ba.size() == 0) {
5619                    pmap.removeAt(ip);
5620                }
5621            }
5622        }
5623
5624        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5625                -100, callerWillRestart, true, doit, evenPersistent,
5626                name == null ? ("stop user " + userId) : ("stop " + name));
5627
5628        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5629            if (!doit) {
5630                return true;
5631            }
5632            didSomething = true;
5633        }
5634
5635        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5636            if (!doit) {
5637                return true;
5638            }
5639            didSomething = true;
5640        }
5641
5642        if (name == null) {
5643            // Remove all sticky broadcasts from this user.
5644            mStickyBroadcasts.remove(userId);
5645        }
5646
5647        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5648        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5649                userId, providers)) {
5650            if (!doit) {
5651                return true;
5652            }
5653            didSomething = true;
5654        }
5655        N = providers.size();
5656        for (i=0; i<N; i++) {
5657            removeDyingProviderLocked(null, providers.get(i), true);
5658        }
5659
5660        // Remove transient permissions granted from/to this package/user
5661        removeUriPermissionsForPackageLocked(name, userId, false);
5662
5663        if (name == null || uninstalling) {
5664            // Remove pending intents.  For now we only do this when force
5665            // stopping users, because we have some problems when doing this
5666            // for packages -- app widgets are not currently cleaned up for
5667            // such packages, so they can be left with bad pending intents.
5668            if (mIntentSenderRecords.size() > 0) {
5669                Iterator<WeakReference<PendingIntentRecord>> it
5670                        = mIntentSenderRecords.values().iterator();
5671                while (it.hasNext()) {
5672                    WeakReference<PendingIntentRecord> wpir = it.next();
5673                    if (wpir == null) {
5674                        it.remove();
5675                        continue;
5676                    }
5677                    PendingIntentRecord pir = wpir.get();
5678                    if (pir == null) {
5679                        it.remove();
5680                        continue;
5681                    }
5682                    if (name == null) {
5683                        // Stopping user, remove all objects for the user.
5684                        if (pir.key.userId != userId) {
5685                            // Not the same user, skip it.
5686                            continue;
5687                        }
5688                    } else {
5689                        if (UserHandle.getAppId(pir.uid) != appId) {
5690                            // Different app id, skip it.
5691                            continue;
5692                        }
5693                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5694                            // Different user, skip it.
5695                            continue;
5696                        }
5697                        if (!pir.key.packageName.equals(name)) {
5698                            // Different package, skip it.
5699                            continue;
5700                        }
5701                    }
5702                    if (!doit) {
5703                        return true;
5704                    }
5705                    didSomething = true;
5706                    it.remove();
5707                    pir.canceled = true;
5708                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5709                        pir.key.activity.pendingResults.remove(pir.ref);
5710                    }
5711                }
5712            }
5713        }
5714
5715        if (doit) {
5716            if (purgeCache && name != null) {
5717                AttributeCache ac = AttributeCache.instance();
5718                if (ac != null) {
5719                    ac.removePackage(name);
5720                }
5721            }
5722            if (mBooted) {
5723                mStackSupervisor.resumeTopActivitiesLocked();
5724                mStackSupervisor.scheduleIdleLocked();
5725            }
5726        }
5727
5728        return didSomething;
5729    }
5730
5731    private final boolean removeProcessLocked(ProcessRecord app,
5732            boolean callerWillRestart, boolean allowRestart, String reason) {
5733        final String name = app.processName;
5734        final int uid = app.uid;
5735        if (DEBUG_PROCESSES) Slog.d(
5736            TAG, "Force removing proc " + app.toShortString() + " (" + name
5737            + "/" + uid + ")");
5738
5739        mProcessNames.remove(name, uid);
5740        mIsolatedProcesses.remove(app.uid);
5741        if (mHeavyWeightProcess == app) {
5742            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5743                    mHeavyWeightProcess.userId, 0));
5744            mHeavyWeightProcess = null;
5745        }
5746        boolean needRestart = false;
5747        if (app.pid > 0 && app.pid != MY_PID) {
5748            int pid = app.pid;
5749            synchronized (mPidsSelfLocked) {
5750                mPidsSelfLocked.remove(pid);
5751                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5752            }
5753            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5754            if (app.isolated) {
5755                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5756            }
5757            app.kill(reason, true);
5758            handleAppDiedLocked(app, true, allowRestart);
5759            removeLruProcessLocked(app);
5760
5761            if (app.persistent && !app.isolated) {
5762                if (!callerWillRestart) {
5763                    addAppLocked(app.info, false, null /* ABI override */);
5764                } else {
5765                    needRestart = true;
5766                }
5767            }
5768        } else {
5769            mRemovedProcesses.add(app);
5770        }
5771
5772        return needRestart;
5773    }
5774
5775    private final void processStartTimedOutLocked(ProcessRecord app) {
5776        final int pid = app.pid;
5777        boolean gone = false;
5778        synchronized (mPidsSelfLocked) {
5779            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5780            if (knownApp != null && knownApp.thread == null) {
5781                mPidsSelfLocked.remove(pid);
5782                gone = true;
5783            }
5784        }
5785
5786        if (gone) {
5787            Slog.w(TAG, "Process " + app + " failed to attach");
5788            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5789                    pid, app.uid, app.processName);
5790            mProcessNames.remove(app.processName, app.uid);
5791            mIsolatedProcesses.remove(app.uid);
5792            if (mHeavyWeightProcess == app) {
5793                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5794                        mHeavyWeightProcess.userId, 0));
5795                mHeavyWeightProcess = null;
5796            }
5797            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5798            if (app.isolated) {
5799                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5800            }
5801            // Take care of any launching providers waiting for this process.
5802            checkAppInLaunchingProvidersLocked(app, true);
5803            // Take care of any services that are waiting for the process.
5804            mServices.processStartTimedOutLocked(app);
5805            app.kill("start timeout", true);
5806            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5807                Slog.w(TAG, "Unattached app died before backup, skipping");
5808                try {
5809                    IBackupManager bm = IBackupManager.Stub.asInterface(
5810                            ServiceManager.getService(Context.BACKUP_SERVICE));
5811                    bm.agentDisconnected(app.info.packageName);
5812                } catch (RemoteException e) {
5813                    // Can't happen; the backup manager is local
5814                }
5815            }
5816            if (isPendingBroadcastProcessLocked(pid)) {
5817                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5818                skipPendingBroadcastLocked(pid);
5819            }
5820        } else {
5821            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5822        }
5823    }
5824
5825    private final boolean attachApplicationLocked(IApplicationThread thread,
5826            int pid) {
5827
5828        // Find the application record that is being attached...  either via
5829        // the pid if we are running in multiple processes, or just pull the
5830        // next app record if we are emulating process with anonymous threads.
5831        ProcessRecord app;
5832        if (pid != MY_PID && pid >= 0) {
5833            synchronized (mPidsSelfLocked) {
5834                app = mPidsSelfLocked.get(pid);
5835            }
5836        } else {
5837            app = null;
5838        }
5839
5840        if (app == null) {
5841            Slog.w(TAG, "No pending application record for pid " + pid
5842                    + " (IApplicationThread " + thread + "); dropping process");
5843            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5844            if (pid > 0 && pid != MY_PID) {
5845                Process.killProcessQuiet(pid);
5846                //TODO: Process.killProcessGroup(app.info.uid, pid);
5847            } else {
5848                try {
5849                    thread.scheduleExit();
5850                } catch (Exception e) {
5851                    // Ignore exceptions.
5852                }
5853            }
5854            return false;
5855        }
5856
5857        // If this application record is still attached to a previous
5858        // process, clean it up now.
5859        if (app.thread != null) {
5860            handleAppDiedLocked(app, true, true);
5861        }
5862
5863        // Tell the process all about itself.
5864
5865        if (localLOGV) Slog.v(
5866                TAG, "Binding process pid " + pid + " to record " + app);
5867
5868        final String processName = app.processName;
5869        try {
5870            AppDeathRecipient adr = new AppDeathRecipient(
5871                    app, pid, thread);
5872            thread.asBinder().linkToDeath(adr, 0);
5873            app.deathRecipient = adr;
5874        } catch (RemoteException e) {
5875            app.resetPackageList(mProcessStats);
5876            startProcessLocked(app, "link fail", processName);
5877            return false;
5878        }
5879
5880        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5881
5882        app.makeActive(thread, mProcessStats);
5883        app.curAdj = app.setAdj = -100;
5884        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5885        app.forcingToForeground = null;
5886        updateProcessForegroundLocked(app, false, false);
5887        app.hasShownUi = false;
5888        app.debugging = false;
5889        app.cached = false;
5890        app.killedByAm = false;
5891
5892        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5893
5894        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5895        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5896
5897        if (!normalMode) {
5898            Slog.i(TAG, "Launching preboot mode app: " + app);
5899        }
5900
5901        if (localLOGV) Slog.v(
5902            TAG, "New app record " + app
5903            + " thread=" + thread.asBinder() + " pid=" + pid);
5904        try {
5905            int testMode = IApplicationThread.DEBUG_OFF;
5906            if (mDebugApp != null && mDebugApp.equals(processName)) {
5907                testMode = mWaitForDebugger
5908                    ? IApplicationThread.DEBUG_WAIT
5909                    : IApplicationThread.DEBUG_ON;
5910                app.debugging = true;
5911                if (mDebugTransient) {
5912                    mDebugApp = mOrigDebugApp;
5913                    mWaitForDebugger = mOrigWaitForDebugger;
5914                }
5915            }
5916            String profileFile = app.instrumentationProfileFile;
5917            ParcelFileDescriptor profileFd = null;
5918            int samplingInterval = 0;
5919            boolean profileAutoStop = false;
5920            if (mProfileApp != null && mProfileApp.equals(processName)) {
5921                mProfileProc = app;
5922                profileFile = mProfileFile;
5923                profileFd = mProfileFd;
5924                samplingInterval = mSamplingInterval;
5925                profileAutoStop = mAutoStopProfiler;
5926            }
5927            boolean enableOpenGlTrace = false;
5928            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5929                enableOpenGlTrace = true;
5930                mOpenGlTraceApp = null;
5931            }
5932
5933            // If the app is being launched for restore or full backup, set it up specially
5934            boolean isRestrictedBackupMode = false;
5935            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5936                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5937                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5938                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5939            }
5940
5941            ensurePackageDexOpt(app.instrumentationInfo != null
5942                    ? app.instrumentationInfo.packageName
5943                    : app.info.packageName);
5944            if (app.instrumentationClass != null) {
5945                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5946            }
5947            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5948                    + processName + " with config " + mConfiguration);
5949            ApplicationInfo appInfo = app.instrumentationInfo != null
5950                    ? app.instrumentationInfo : app.info;
5951            app.compat = compatibilityInfoForPackageLocked(appInfo);
5952            if (profileFd != null) {
5953                profileFd = profileFd.dup();
5954            }
5955            ProfilerInfo profilerInfo = profileFile == null ? null
5956                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5957            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5958                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5959                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5960                    isRestrictedBackupMode || !normalMode, app.persistent,
5961                    new Configuration(mConfiguration), app.compat,
5962                    getCommonServicesLocked(app.isolated),
5963                    mCoreSettingsObserver.getCoreSettingsLocked());
5964            updateLruProcessLocked(app, false, null);
5965            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5966        } catch (Exception e) {
5967            // todo: Yikes!  What should we do?  For now we will try to
5968            // start another process, but that could easily get us in
5969            // an infinite loop of restarting processes...
5970            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5971
5972            app.resetPackageList(mProcessStats);
5973            app.unlinkDeathRecipient();
5974            startProcessLocked(app, "bind fail", processName);
5975            return false;
5976        }
5977
5978        // Remove this record from the list of starting applications.
5979        mPersistentStartingProcesses.remove(app);
5980        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5981                "Attach application locked removing on hold: " + app);
5982        mProcessesOnHold.remove(app);
5983
5984        boolean badApp = false;
5985        boolean didSomething = false;
5986
5987        // See if the top visible activity is waiting to run in this process...
5988        if (normalMode) {
5989            try {
5990                if (mStackSupervisor.attachApplicationLocked(app)) {
5991                    didSomething = true;
5992                }
5993            } catch (Exception e) {
5994                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5995                badApp = true;
5996            }
5997        }
5998
5999        // Find any services that should be running in this process...
6000        if (!badApp) {
6001            try {
6002                didSomething |= mServices.attachApplicationLocked(app, processName);
6003            } catch (Exception e) {
6004                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6005                badApp = true;
6006            }
6007        }
6008
6009        // Check if a next-broadcast receiver is in this process...
6010        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6011            try {
6012                didSomething |= sendPendingBroadcastsLocked(app);
6013            } catch (Exception e) {
6014                // If the app died trying to launch the receiver we declare it 'bad'
6015                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6016                badApp = true;
6017            }
6018        }
6019
6020        // Check whether the next backup agent is in this process...
6021        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6022            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6023            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6024            try {
6025                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6026                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6027                        mBackupTarget.backupMode);
6028            } catch (Exception e) {
6029                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6030                badApp = true;
6031            }
6032        }
6033
6034        if (badApp) {
6035            app.kill("error during init", true);
6036            handleAppDiedLocked(app, false, true);
6037            return false;
6038        }
6039
6040        if (!didSomething) {
6041            updateOomAdjLocked();
6042        }
6043
6044        return true;
6045    }
6046
6047    @Override
6048    public final void attachApplication(IApplicationThread thread) {
6049        synchronized (this) {
6050            int callingPid = Binder.getCallingPid();
6051            final long origId = Binder.clearCallingIdentity();
6052            attachApplicationLocked(thread, callingPid);
6053            Binder.restoreCallingIdentity(origId);
6054        }
6055    }
6056
6057    @Override
6058    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6059        final long origId = Binder.clearCallingIdentity();
6060        synchronized (this) {
6061            ActivityStack stack = ActivityRecord.getStackLocked(token);
6062            if (stack != null) {
6063                ActivityRecord r =
6064                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6065                if (stopProfiling) {
6066                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6067                        try {
6068                            mProfileFd.close();
6069                        } catch (IOException e) {
6070                        }
6071                        clearProfilerLocked();
6072                    }
6073                }
6074            }
6075        }
6076        Binder.restoreCallingIdentity(origId);
6077    }
6078
6079    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6080        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6081                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6082    }
6083
6084    void enableScreenAfterBoot() {
6085        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6086                SystemClock.uptimeMillis());
6087        mWindowManager.enableScreenAfterBoot();
6088
6089        synchronized (this) {
6090            updateEventDispatchingLocked();
6091        }
6092    }
6093
6094    @Override
6095    public void showBootMessage(final CharSequence msg, final boolean always) {
6096        enforceNotIsolatedCaller("showBootMessage");
6097        mWindowManager.showBootMessage(msg, always);
6098    }
6099
6100    @Override
6101    public void keyguardWaitingForActivityDrawn() {
6102        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6103        final long token = Binder.clearCallingIdentity();
6104        try {
6105            synchronized (this) {
6106                if (DEBUG_LOCKSCREEN) logLockScreen("");
6107                mWindowManager.keyguardWaitingForActivityDrawn();
6108                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6109                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6110                    updateSleepIfNeededLocked();
6111                }
6112            }
6113        } finally {
6114            Binder.restoreCallingIdentity(token);
6115        }
6116    }
6117
6118    final void finishBooting() {
6119        synchronized (this) {
6120            if (!mBootAnimationComplete) {
6121                mCallFinishBooting = true;
6122                return;
6123            }
6124            mCallFinishBooting = false;
6125        }
6126
6127        ArraySet<String> completedIsas = new ArraySet<String>();
6128        for (String abi : Build.SUPPORTED_ABIS) {
6129            Process.establishZygoteConnectionForAbi(abi);
6130            final String instructionSet = VMRuntime.getInstructionSet(abi);
6131            if (!completedIsas.contains(instructionSet)) {
6132                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6133                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6134                }
6135                completedIsas.add(instructionSet);
6136            }
6137        }
6138
6139        IntentFilter pkgFilter = new IntentFilter();
6140        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6141        pkgFilter.addDataScheme("package");
6142        mContext.registerReceiver(new BroadcastReceiver() {
6143            @Override
6144            public void onReceive(Context context, Intent intent) {
6145                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6146                if (pkgs != null) {
6147                    for (String pkg : pkgs) {
6148                        synchronized (ActivityManagerService.this) {
6149                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6150                                    0, "finished booting")) {
6151                                setResultCode(Activity.RESULT_OK);
6152                                return;
6153                            }
6154                        }
6155                    }
6156                }
6157            }
6158        }, pkgFilter);
6159
6160        // Let system services know.
6161        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6162
6163        synchronized (this) {
6164            // Ensure that any processes we had put on hold are now started
6165            // up.
6166            final int NP = mProcessesOnHold.size();
6167            if (NP > 0) {
6168                ArrayList<ProcessRecord> procs =
6169                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6170                for (int ip=0; ip<NP; ip++) {
6171                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6172                            + procs.get(ip));
6173                    startProcessLocked(procs.get(ip), "on-hold", null);
6174                }
6175            }
6176
6177            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6178                // Start looking for apps that are abusing wake locks.
6179                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6180                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6181                // Tell anyone interested that we are done booting!
6182                SystemProperties.set("sys.boot_completed", "1");
6183
6184                // And trigger dev.bootcomplete if we are not showing encryption progress
6185                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6186                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6187                    SystemProperties.set("dev.bootcomplete", "1");
6188                }
6189                for (int i=0; i<mStartedUsers.size(); i++) {
6190                    UserStartedState uss = mStartedUsers.valueAt(i);
6191                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6192                        uss.mState = UserStartedState.STATE_RUNNING;
6193                        final int userId = mStartedUsers.keyAt(i);
6194                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6195                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6196                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6197                        broadcastIntentLocked(null, null, intent, null,
6198                                new IIntentReceiver.Stub() {
6199                                    @Override
6200                                    public void performReceive(Intent intent, int resultCode,
6201                                            String data, Bundle extras, boolean ordered,
6202                                            boolean sticky, int sendingUser) {
6203                                        synchronized (ActivityManagerService.this) {
6204                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6205                                                    true, false);
6206                                        }
6207                                    }
6208                                },
6209                                0, null, null,
6210                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6211                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6212                                userId);
6213                    }
6214                }
6215                scheduleStartProfilesLocked();
6216            }
6217        }
6218    }
6219
6220    @Override
6221    public void bootAnimationComplete() {
6222        final boolean callFinishBooting;
6223        synchronized (this) {
6224            callFinishBooting = mCallFinishBooting;
6225            mBootAnimationComplete = true;
6226        }
6227        if (callFinishBooting) {
6228            finishBooting();
6229        }
6230    }
6231
6232    @Override
6233    public void systemBackupRestored() {
6234        synchronized (this) {
6235            if (mSystemReady) {
6236                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6237            } else {
6238                Slog.w(TAG, "System backup restored before system is ready");
6239            }
6240        }
6241    }
6242
6243    final void ensureBootCompleted() {
6244        boolean booting;
6245        boolean enableScreen;
6246        synchronized (this) {
6247            booting = mBooting;
6248            mBooting = false;
6249            enableScreen = !mBooted;
6250            mBooted = true;
6251        }
6252
6253        if (booting) {
6254            finishBooting();
6255        }
6256
6257        if (enableScreen) {
6258            enableScreenAfterBoot();
6259        }
6260    }
6261
6262    @Override
6263    public final void activityResumed(IBinder token) {
6264        final long origId = Binder.clearCallingIdentity();
6265        synchronized(this) {
6266            ActivityStack stack = ActivityRecord.getStackLocked(token);
6267            if (stack != null) {
6268                ActivityRecord.activityResumedLocked(token);
6269            }
6270        }
6271        Binder.restoreCallingIdentity(origId);
6272    }
6273
6274    @Override
6275    public final void activityPaused(IBinder token) {
6276        final long origId = Binder.clearCallingIdentity();
6277        synchronized(this) {
6278            ActivityStack stack = ActivityRecord.getStackLocked(token);
6279            if (stack != null) {
6280                stack.activityPausedLocked(token, false);
6281            }
6282        }
6283        Binder.restoreCallingIdentity(origId);
6284    }
6285
6286    @Override
6287    public final void activityStopped(IBinder token, Bundle icicle,
6288            PersistableBundle persistentState, CharSequence description) {
6289        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6290
6291        // Refuse possible leaked file descriptors
6292        if (icicle != null && icicle.hasFileDescriptors()) {
6293            throw new IllegalArgumentException("File descriptors passed in Bundle");
6294        }
6295
6296        final long origId = Binder.clearCallingIdentity();
6297
6298        synchronized (this) {
6299            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6300            if (r != null) {
6301                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6302            }
6303        }
6304
6305        trimApplications();
6306
6307        Binder.restoreCallingIdentity(origId);
6308    }
6309
6310    @Override
6311    public final void activityDestroyed(IBinder token) {
6312        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6313        synchronized (this) {
6314            ActivityStack stack = ActivityRecord.getStackLocked(token);
6315            if (stack != null) {
6316                stack.activityDestroyedLocked(token);
6317            }
6318        }
6319    }
6320
6321    @Override
6322    public final void backgroundResourcesReleased(IBinder token) {
6323        final long origId = Binder.clearCallingIdentity();
6324        try {
6325            synchronized (this) {
6326                ActivityStack stack = ActivityRecord.getStackLocked(token);
6327                if (stack != null) {
6328                    stack.backgroundResourcesReleased();
6329                }
6330            }
6331        } finally {
6332            Binder.restoreCallingIdentity(origId);
6333        }
6334    }
6335
6336    @Override
6337    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6338        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6339    }
6340
6341    @Override
6342    public final void notifyEnterAnimationComplete(IBinder token) {
6343        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6344    }
6345
6346    @Override
6347    public String getCallingPackage(IBinder token) {
6348        synchronized (this) {
6349            ActivityRecord r = getCallingRecordLocked(token);
6350            return r != null ? r.info.packageName : null;
6351        }
6352    }
6353
6354    @Override
6355    public ComponentName getCallingActivity(IBinder token) {
6356        synchronized (this) {
6357            ActivityRecord r = getCallingRecordLocked(token);
6358            return r != null ? r.intent.getComponent() : null;
6359        }
6360    }
6361
6362    private ActivityRecord getCallingRecordLocked(IBinder token) {
6363        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6364        if (r == null) {
6365            return null;
6366        }
6367        return r.resultTo;
6368    }
6369
6370    @Override
6371    public ComponentName getActivityClassForToken(IBinder token) {
6372        synchronized(this) {
6373            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6374            if (r == null) {
6375                return null;
6376            }
6377            return r.intent.getComponent();
6378        }
6379    }
6380
6381    @Override
6382    public String getPackageForToken(IBinder token) {
6383        synchronized(this) {
6384            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6385            if (r == null) {
6386                return null;
6387            }
6388            return r.packageName;
6389        }
6390    }
6391
6392    @Override
6393    public IIntentSender getIntentSender(int type,
6394            String packageName, IBinder token, String resultWho,
6395            int requestCode, Intent[] intents, String[] resolvedTypes,
6396            int flags, Bundle options, int userId) {
6397        enforceNotIsolatedCaller("getIntentSender");
6398        // Refuse possible leaked file descriptors
6399        if (intents != null) {
6400            if (intents.length < 1) {
6401                throw new IllegalArgumentException("Intents array length must be >= 1");
6402            }
6403            for (int i=0; i<intents.length; i++) {
6404                Intent intent = intents[i];
6405                if (intent != null) {
6406                    if (intent.hasFileDescriptors()) {
6407                        throw new IllegalArgumentException("File descriptors passed in Intent");
6408                    }
6409                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6410                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6411                        throw new IllegalArgumentException(
6412                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6413                    }
6414                    intents[i] = new Intent(intent);
6415                }
6416            }
6417            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6418                throw new IllegalArgumentException(
6419                        "Intent array length does not match resolvedTypes length");
6420            }
6421        }
6422        if (options != null) {
6423            if (options.hasFileDescriptors()) {
6424                throw new IllegalArgumentException("File descriptors passed in options");
6425            }
6426        }
6427
6428        synchronized(this) {
6429            int callingUid = Binder.getCallingUid();
6430            int origUserId = userId;
6431            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6432                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6433                    ALLOW_NON_FULL, "getIntentSender", null);
6434            if (origUserId == UserHandle.USER_CURRENT) {
6435                // We don't want to evaluate this until the pending intent is
6436                // actually executed.  However, we do want to always do the
6437                // security checking for it above.
6438                userId = UserHandle.USER_CURRENT;
6439            }
6440            try {
6441                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6442                    int uid = AppGlobals.getPackageManager()
6443                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6444                    if (!UserHandle.isSameApp(callingUid, uid)) {
6445                        String msg = "Permission Denial: getIntentSender() from pid="
6446                            + Binder.getCallingPid()
6447                            + ", uid=" + Binder.getCallingUid()
6448                            + ", (need uid=" + uid + ")"
6449                            + " is not allowed to send as package " + packageName;
6450                        Slog.w(TAG, msg);
6451                        throw new SecurityException(msg);
6452                    }
6453                }
6454
6455                return getIntentSenderLocked(type, packageName, callingUid, userId,
6456                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6457
6458            } catch (RemoteException e) {
6459                throw new SecurityException(e);
6460            }
6461        }
6462    }
6463
6464    IIntentSender getIntentSenderLocked(int type, String packageName,
6465            int callingUid, int userId, IBinder token, String resultWho,
6466            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6467            Bundle options) {
6468        if (DEBUG_MU)
6469            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6470        ActivityRecord activity = null;
6471        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6472            activity = ActivityRecord.isInStackLocked(token);
6473            if (activity == null) {
6474                return null;
6475            }
6476            if (activity.finishing) {
6477                return null;
6478            }
6479        }
6480
6481        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6482        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6483        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6484        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6485                |PendingIntent.FLAG_UPDATE_CURRENT);
6486
6487        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6488                type, packageName, activity, resultWho,
6489                requestCode, intents, resolvedTypes, flags, options, userId);
6490        WeakReference<PendingIntentRecord> ref;
6491        ref = mIntentSenderRecords.get(key);
6492        PendingIntentRecord rec = ref != null ? ref.get() : null;
6493        if (rec != null) {
6494            if (!cancelCurrent) {
6495                if (updateCurrent) {
6496                    if (rec.key.requestIntent != null) {
6497                        rec.key.requestIntent.replaceExtras(intents != null ?
6498                                intents[intents.length - 1] : null);
6499                    }
6500                    if (intents != null) {
6501                        intents[intents.length-1] = rec.key.requestIntent;
6502                        rec.key.allIntents = intents;
6503                        rec.key.allResolvedTypes = resolvedTypes;
6504                    } else {
6505                        rec.key.allIntents = null;
6506                        rec.key.allResolvedTypes = null;
6507                    }
6508                }
6509                return rec;
6510            }
6511            rec.canceled = true;
6512            mIntentSenderRecords.remove(key);
6513        }
6514        if (noCreate) {
6515            return rec;
6516        }
6517        rec = new PendingIntentRecord(this, key, callingUid);
6518        mIntentSenderRecords.put(key, rec.ref);
6519        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6520            if (activity.pendingResults == null) {
6521                activity.pendingResults
6522                        = new HashSet<WeakReference<PendingIntentRecord>>();
6523            }
6524            activity.pendingResults.add(rec.ref);
6525        }
6526        return rec;
6527    }
6528
6529    @Override
6530    public void cancelIntentSender(IIntentSender sender) {
6531        if (!(sender instanceof PendingIntentRecord)) {
6532            return;
6533        }
6534        synchronized(this) {
6535            PendingIntentRecord rec = (PendingIntentRecord)sender;
6536            try {
6537                int uid = AppGlobals.getPackageManager()
6538                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6539                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6540                    String msg = "Permission Denial: cancelIntentSender() from pid="
6541                        + Binder.getCallingPid()
6542                        + ", uid=" + Binder.getCallingUid()
6543                        + " is not allowed to cancel packges "
6544                        + rec.key.packageName;
6545                    Slog.w(TAG, msg);
6546                    throw new SecurityException(msg);
6547                }
6548            } catch (RemoteException e) {
6549                throw new SecurityException(e);
6550            }
6551            cancelIntentSenderLocked(rec, true);
6552        }
6553    }
6554
6555    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6556        rec.canceled = true;
6557        mIntentSenderRecords.remove(rec.key);
6558        if (cleanActivity && rec.key.activity != null) {
6559            rec.key.activity.pendingResults.remove(rec.ref);
6560        }
6561    }
6562
6563    @Override
6564    public String getPackageForIntentSender(IIntentSender pendingResult) {
6565        if (!(pendingResult instanceof PendingIntentRecord)) {
6566            return null;
6567        }
6568        try {
6569            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6570            return res.key.packageName;
6571        } catch (ClassCastException e) {
6572        }
6573        return null;
6574    }
6575
6576    @Override
6577    public int getUidForIntentSender(IIntentSender sender) {
6578        if (sender instanceof PendingIntentRecord) {
6579            try {
6580                PendingIntentRecord res = (PendingIntentRecord)sender;
6581                return res.uid;
6582            } catch (ClassCastException e) {
6583            }
6584        }
6585        return -1;
6586    }
6587
6588    @Override
6589    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6590        if (!(pendingResult instanceof PendingIntentRecord)) {
6591            return false;
6592        }
6593        try {
6594            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6595            if (res.key.allIntents == null) {
6596                return false;
6597            }
6598            for (int i=0; i<res.key.allIntents.length; i++) {
6599                Intent intent = res.key.allIntents[i];
6600                if (intent.getPackage() != null && intent.getComponent() != null) {
6601                    return false;
6602                }
6603            }
6604            return true;
6605        } catch (ClassCastException e) {
6606        }
6607        return false;
6608    }
6609
6610    @Override
6611    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6612        if (!(pendingResult instanceof PendingIntentRecord)) {
6613            return false;
6614        }
6615        try {
6616            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6617            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6618                return true;
6619            }
6620            return false;
6621        } catch (ClassCastException e) {
6622        }
6623        return false;
6624    }
6625
6626    @Override
6627    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6628        if (!(pendingResult instanceof PendingIntentRecord)) {
6629            return null;
6630        }
6631        try {
6632            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6633            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6634        } catch (ClassCastException e) {
6635        }
6636        return null;
6637    }
6638
6639    @Override
6640    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6641        if (!(pendingResult instanceof PendingIntentRecord)) {
6642            return null;
6643        }
6644        try {
6645            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6646            Intent intent = res.key.requestIntent;
6647            if (intent != null) {
6648                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6649                        || res.lastTagPrefix.equals(prefix))) {
6650                    return res.lastTag;
6651                }
6652                res.lastTagPrefix = prefix;
6653                StringBuilder sb = new StringBuilder(128);
6654                if (prefix != null) {
6655                    sb.append(prefix);
6656                }
6657                if (intent.getAction() != null) {
6658                    sb.append(intent.getAction());
6659                } else if (intent.getComponent() != null) {
6660                    intent.getComponent().appendShortString(sb);
6661                } else {
6662                    sb.append("?");
6663                }
6664                return res.lastTag = sb.toString();
6665            }
6666        } catch (ClassCastException e) {
6667        }
6668        return null;
6669    }
6670
6671    @Override
6672    public void setProcessLimit(int max) {
6673        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6674                "setProcessLimit()");
6675        synchronized (this) {
6676            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6677            mProcessLimitOverride = max;
6678        }
6679        trimApplications();
6680    }
6681
6682    @Override
6683    public int getProcessLimit() {
6684        synchronized (this) {
6685            return mProcessLimitOverride;
6686        }
6687    }
6688
6689    void foregroundTokenDied(ForegroundToken token) {
6690        synchronized (ActivityManagerService.this) {
6691            synchronized (mPidsSelfLocked) {
6692                ForegroundToken cur
6693                    = mForegroundProcesses.get(token.pid);
6694                if (cur != token) {
6695                    return;
6696                }
6697                mForegroundProcesses.remove(token.pid);
6698                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6699                if (pr == null) {
6700                    return;
6701                }
6702                pr.forcingToForeground = null;
6703                updateProcessForegroundLocked(pr, false, false);
6704            }
6705            updateOomAdjLocked();
6706        }
6707    }
6708
6709    @Override
6710    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6711        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6712                "setProcessForeground()");
6713        synchronized(this) {
6714            boolean changed = false;
6715
6716            synchronized (mPidsSelfLocked) {
6717                ProcessRecord pr = mPidsSelfLocked.get(pid);
6718                if (pr == null && isForeground) {
6719                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6720                    return;
6721                }
6722                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6723                if (oldToken != null) {
6724                    oldToken.token.unlinkToDeath(oldToken, 0);
6725                    mForegroundProcesses.remove(pid);
6726                    if (pr != null) {
6727                        pr.forcingToForeground = null;
6728                    }
6729                    changed = true;
6730                }
6731                if (isForeground && token != null) {
6732                    ForegroundToken newToken = new ForegroundToken() {
6733                        @Override
6734                        public void binderDied() {
6735                            foregroundTokenDied(this);
6736                        }
6737                    };
6738                    newToken.pid = pid;
6739                    newToken.token = token;
6740                    try {
6741                        token.linkToDeath(newToken, 0);
6742                        mForegroundProcesses.put(pid, newToken);
6743                        pr.forcingToForeground = token;
6744                        changed = true;
6745                    } catch (RemoteException e) {
6746                        // If the process died while doing this, we will later
6747                        // do the cleanup with the process death link.
6748                    }
6749                }
6750            }
6751
6752            if (changed) {
6753                updateOomAdjLocked();
6754            }
6755        }
6756    }
6757
6758    // =========================================================
6759    // PERMISSIONS
6760    // =========================================================
6761
6762    static class PermissionController extends IPermissionController.Stub {
6763        ActivityManagerService mActivityManagerService;
6764        PermissionController(ActivityManagerService activityManagerService) {
6765            mActivityManagerService = activityManagerService;
6766        }
6767
6768        @Override
6769        public boolean checkPermission(String permission, int pid, int uid) {
6770            return mActivityManagerService.checkPermission(permission, pid,
6771                    uid) == PackageManager.PERMISSION_GRANTED;
6772        }
6773    }
6774
6775    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6776        @Override
6777        public int checkComponentPermission(String permission, int pid, int uid,
6778                int owningUid, boolean exported) {
6779            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6780                    owningUid, exported);
6781        }
6782
6783        @Override
6784        public Object getAMSLock() {
6785            return ActivityManagerService.this;
6786        }
6787    }
6788
6789    /**
6790     * This can be called with or without the global lock held.
6791     */
6792    int checkComponentPermission(String permission, int pid, int uid,
6793            int owningUid, boolean exported) {
6794        if (pid == MY_PID) {
6795            return PackageManager.PERMISSION_GRANTED;
6796        }
6797        return ActivityManager.checkComponentPermission(permission, uid,
6798                owningUid, exported);
6799    }
6800
6801    /**
6802     * As the only public entry point for permissions checking, this method
6803     * can enforce the semantic that requesting a check on a null global
6804     * permission is automatically denied.  (Internally a null permission
6805     * string is used when calling {@link #checkComponentPermission} in cases
6806     * when only uid-based security is needed.)
6807     *
6808     * This can be called with or without the global lock held.
6809     */
6810    @Override
6811    public int checkPermission(String permission, int pid, int uid) {
6812        if (permission == null) {
6813            return PackageManager.PERMISSION_DENIED;
6814        }
6815        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6816    }
6817
6818    @Override
6819    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6820        if (permission == null) {
6821            return PackageManager.PERMISSION_DENIED;
6822        }
6823
6824        // We might be performing an operation on behalf of an indirect binder
6825        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6826        // client identity accordingly before proceeding.
6827        Identity tlsIdentity = sCallerIdentity.get();
6828        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6829            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6830                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6831            uid = tlsIdentity.uid;
6832            pid = tlsIdentity.pid;
6833        }
6834
6835        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6836    }
6837
6838    /**
6839     * Binder IPC calls go through the public entry point.
6840     * This can be called with or without the global lock held.
6841     */
6842    int checkCallingPermission(String permission) {
6843        return checkPermission(permission,
6844                Binder.getCallingPid(),
6845                UserHandle.getAppId(Binder.getCallingUid()));
6846    }
6847
6848    /**
6849     * This can be called with or without the global lock held.
6850     */
6851    void enforceCallingPermission(String permission, String func) {
6852        if (checkCallingPermission(permission)
6853                == PackageManager.PERMISSION_GRANTED) {
6854            return;
6855        }
6856
6857        String msg = "Permission Denial: " + func + " from pid="
6858                + Binder.getCallingPid()
6859                + ", uid=" + Binder.getCallingUid()
6860                + " requires " + permission;
6861        Slog.w(TAG, msg);
6862        throw new SecurityException(msg);
6863    }
6864
6865    /**
6866     * Determine if UID is holding permissions required to access {@link Uri} in
6867     * the given {@link ProviderInfo}. Final permission checking is always done
6868     * in {@link ContentProvider}.
6869     */
6870    private final boolean checkHoldingPermissionsLocked(
6871            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6872        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6873                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6874        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6875            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6876                    != PERMISSION_GRANTED) {
6877                return false;
6878            }
6879        }
6880        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6881    }
6882
6883    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6884            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6885        if (pi.applicationInfo.uid == uid) {
6886            return true;
6887        } else if (!pi.exported) {
6888            return false;
6889        }
6890
6891        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6892        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6893        try {
6894            // check if target holds top-level <provider> permissions
6895            if (!readMet && pi.readPermission != null && considerUidPermissions
6896                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6897                readMet = true;
6898            }
6899            if (!writeMet && pi.writePermission != null && considerUidPermissions
6900                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6901                writeMet = true;
6902            }
6903
6904            // track if unprotected read/write is allowed; any denied
6905            // <path-permission> below removes this ability
6906            boolean allowDefaultRead = pi.readPermission == null;
6907            boolean allowDefaultWrite = pi.writePermission == null;
6908
6909            // check if target holds any <path-permission> that match uri
6910            final PathPermission[] pps = pi.pathPermissions;
6911            if (pps != null) {
6912                final String path = grantUri.uri.getPath();
6913                int i = pps.length;
6914                while (i > 0 && (!readMet || !writeMet)) {
6915                    i--;
6916                    PathPermission pp = pps[i];
6917                    if (pp.match(path)) {
6918                        if (!readMet) {
6919                            final String pprperm = pp.getReadPermission();
6920                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6921                                    + pprperm + " for " + pp.getPath()
6922                                    + ": match=" + pp.match(path)
6923                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6924                            if (pprperm != null) {
6925                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6926                                        == PERMISSION_GRANTED) {
6927                                    readMet = true;
6928                                } else {
6929                                    allowDefaultRead = false;
6930                                }
6931                            }
6932                        }
6933                        if (!writeMet) {
6934                            final String ppwperm = pp.getWritePermission();
6935                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6936                                    + ppwperm + " for " + pp.getPath()
6937                                    + ": match=" + pp.match(path)
6938                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6939                            if (ppwperm != null) {
6940                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6941                                        == PERMISSION_GRANTED) {
6942                                    writeMet = true;
6943                                } else {
6944                                    allowDefaultWrite = false;
6945                                }
6946                            }
6947                        }
6948                    }
6949                }
6950            }
6951
6952            // grant unprotected <provider> read/write, if not blocked by
6953            // <path-permission> above
6954            if (allowDefaultRead) readMet = true;
6955            if (allowDefaultWrite) writeMet = true;
6956
6957        } catch (RemoteException e) {
6958            return false;
6959        }
6960
6961        return readMet && writeMet;
6962    }
6963
6964    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6965        ProviderInfo pi = null;
6966        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6967        if (cpr != null) {
6968            pi = cpr.info;
6969        } else {
6970            try {
6971                pi = AppGlobals.getPackageManager().resolveContentProvider(
6972                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6973            } catch (RemoteException ex) {
6974            }
6975        }
6976        return pi;
6977    }
6978
6979    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6980        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6981        if (targetUris != null) {
6982            return targetUris.get(grantUri);
6983        }
6984        return null;
6985    }
6986
6987    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6988            String targetPkg, int targetUid, GrantUri grantUri) {
6989        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6990        if (targetUris == null) {
6991            targetUris = Maps.newArrayMap();
6992            mGrantedUriPermissions.put(targetUid, targetUris);
6993        }
6994
6995        UriPermission perm = targetUris.get(grantUri);
6996        if (perm == null) {
6997            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6998            targetUris.put(grantUri, perm);
6999        }
7000
7001        return perm;
7002    }
7003
7004    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7005            final int modeFlags) {
7006        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7007        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7008                : UriPermission.STRENGTH_OWNED;
7009
7010        // Root gets to do everything.
7011        if (uid == 0) {
7012            return true;
7013        }
7014
7015        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7016        if (perms == null) return false;
7017
7018        // First look for exact match
7019        final UriPermission exactPerm = perms.get(grantUri);
7020        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7021            return true;
7022        }
7023
7024        // No exact match, look for prefixes
7025        final int N = perms.size();
7026        for (int i = 0; i < N; i++) {
7027            final UriPermission perm = perms.valueAt(i);
7028            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7029                    && perm.getStrength(modeFlags) >= minStrength) {
7030                return true;
7031            }
7032        }
7033
7034        return false;
7035    }
7036
7037    /**
7038     * @param uri This uri must NOT contain an embedded userId.
7039     * @param userId The userId in which the uri is to be resolved.
7040     */
7041    @Override
7042    public int checkUriPermission(Uri uri, int pid, int uid,
7043            final int modeFlags, int userId, IBinder callerToken) {
7044        enforceNotIsolatedCaller("checkUriPermission");
7045
7046        // Another redirected-binder-call permissions check as in
7047        // {@link checkPermissionWithToken}.
7048        Identity tlsIdentity = sCallerIdentity.get();
7049        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7050            uid = tlsIdentity.uid;
7051            pid = tlsIdentity.pid;
7052        }
7053
7054        // Our own process gets to do everything.
7055        if (pid == MY_PID) {
7056            return PackageManager.PERMISSION_GRANTED;
7057        }
7058        synchronized (this) {
7059            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7060                    ? PackageManager.PERMISSION_GRANTED
7061                    : PackageManager.PERMISSION_DENIED;
7062        }
7063    }
7064
7065    /**
7066     * Check if the targetPkg can be granted permission to access uri by
7067     * the callingUid using the given modeFlags.  Throws a security exception
7068     * if callingUid is not allowed to do this.  Returns the uid of the target
7069     * if the URI permission grant should be performed; returns -1 if it is not
7070     * needed (for example targetPkg already has permission to access the URI).
7071     * If you already know the uid of the target, you can supply it in
7072     * lastTargetUid else set that to -1.
7073     */
7074    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7075            final int modeFlags, int lastTargetUid) {
7076        if (!Intent.isAccessUriMode(modeFlags)) {
7077            return -1;
7078        }
7079
7080        if (targetPkg != null) {
7081            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7082                    "Checking grant " + targetPkg + " permission to " + grantUri);
7083        }
7084
7085        final IPackageManager pm = AppGlobals.getPackageManager();
7086
7087        // If this is not a content: uri, we can't do anything with it.
7088        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7089            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7090                    "Can't grant URI permission for non-content URI: " + grantUri);
7091            return -1;
7092        }
7093
7094        final String authority = grantUri.uri.getAuthority();
7095        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7096        if (pi == null) {
7097            Slog.w(TAG, "No content provider found for permission check: " +
7098                    grantUri.uri.toSafeString());
7099            return -1;
7100        }
7101
7102        int targetUid = lastTargetUid;
7103        if (targetUid < 0 && targetPkg != null) {
7104            try {
7105                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7106                if (targetUid < 0) {
7107                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7108                            "Can't grant URI permission no uid for: " + targetPkg);
7109                    return -1;
7110                }
7111            } catch (RemoteException ex) {
7112                return -1;
7113            }
7114        }
7115
7116        if (targetUid >= 0) {
7117            // First...  does the target actually need this permission?
7118            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7119                // No need to grant the target this permission.
7120                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7121                        "Target " + targetPkg + " already has full permission to " + grantUri);
7122                return -1;
7123            }
7124        } else {
7125            // First...  there is no target package, so can anyone access it?
7126            boolean allowed = pi.exported;
7127            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7128                if (pi.readPermission != null) {
7129                    allowed = false;
7130                }
7131            }
7132            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7133                if (pi.writePermission != null) {
7134                    allowed = false;
7135                }
7136            }
7137            if (allowed) {
7138                return -1;
7139            }
7140        }
7141
7142        /* There is a special cross user grant if:
7143         * - The target is on another user.
7144         * - Apps on the current user can access the uri without any uid permissions.
7145         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7146         * grant uri permissions.
7147         */
7148        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7149                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7150                modeFlags, false /*without considering the uid permissions*/);
7151
7152        // Second...  is the provider allowing granting of URI permissions?
7153        if (!specialCrossUserGrant) {
7154            if (!pi.grantUriPermissions) {
7155                throw new SecurityException("Provider " + pi.packageName
7156                        + "/" + pi.name
7157                        + " does not allow granting of Uri permissions (uri "
7158                        + grantUri + ")");
7159            }
7160            if (pi.uriPermissionPatterns != null) {
7161                final int N = pi.uriPermissionPatterns.length;
7162                boolean allowed = false;
7163                for (int i=0; i<N; i++) {
7164                    if (pi.uriPermissionPatterns[i] != null
7165                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7166                        allowed = true;
7167                        break;
7168                    }
7169                }
7170                if (!allowed) {
7171                    throw new SecurityException("Provider " + pi.packageName
7172                            + "/" + pi.name
7173                            + " does not allow granting of permission to path of Uri "
7174                            + grantUri);
7175                }
7176            }
7177        }
7178
7179        // Third...  does the caller itself have permission to access
7180        // this uri?
7181        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7182            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7183                // Require they hold a strong enough Uri permission
7184                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7185                    throw new SecurityException("Uid " + callingUid
7186                            + " does not have permission to uri " + grantUri);
7187                }
7188            }
7189        }
7190        return targetUid;
7191    }
7192
7193    /**
7194     * @param uri This uri must NOT contain an embedded userId.
7195     * @param userId The userId in which the uri is to be resolved.
7196     */
7197    @Override
7198    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7199            final int modeFlags, int userId) {
7200        enforceNotIsolatedCaller("checkGrantUriPermission");
7201        synchronized(this) {
7202            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7203                    new GrantUri(userId, uri, false), modeFlags, -1);
7204        }
7205    }
7206
7207    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7208            final int modeFlags, UriPermissionOwner owner) {
7209        if (!Intent.isAccessUriMode(modeFlags)) {
7210            return;
7211        }
7212
7213        // So here we are: the caller has the assumed permission
7214        // to the uri, and the target doesn't.  Let's now give this to
7215        // the target.
7216
7217        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7218                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7219
7220        final String authority = grantUri.uri.getAuthority();
7221        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7222        if (pi == null) {
7223            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7224            return;
7225        }
7226
7227        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7228            grantUri.prefix = true;
7229        }
7230        final UriPermission perm = findOrCreateUriPermissionLocked(
7231                pi.packageName, targetPkg, targetUid, grantUri);
7232        perm.grantModes(modeFlags, owner);
7233    }
7234
7235    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7236            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7237        if (targetPkg == null) {
7238            throw new NullPointerException("targetPkg");
7239        }
7240        int targetUid;
7241        final IPackageManager pm = AppGlobals.getPackageManager();
7242        try {
7243            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7244        } catch (RemoteException ex) {
7245            return;
7246        }
7247
7248        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7249                targetUid);
7250        if (targetUid < 0) {
7251            return;
7252        }
7253
7254        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7255                owner);
7256    }
7257
7258    static class NeededUriGrants extends ArrayList<GrantUri> {
7259        final String targetPkg;
7260        final int targetUid;
7261        final int flags;
7262
7263        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7264            this.targetPkg = targetPkg;
7265            this.targetUid = targetUid;
7266            this.flags = flags;
7267        }
7268    }
7269
7270    /**
7271     * Like checkGrantUriPermissionLocked, but takes an Intent.
7272     */
7273    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7274            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7275        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7276                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7277                + " clip=" + (intent != null ? intent.getClipData() : null)
7278                + " from " + intent + "; flags=0x"
7279                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7280
7281        if (targetPkg == null) {
7282            throw new NullPointerException("targetPkg");
7283        }
7284
7285        if (intent == null) {
7286            return null;
7287        }
7288        Uri data = intent.getData();
7289        ClipData clip = intent.getClipData();
7290        if (data == null && clip == null) {
7291            return null;
7292        }
7293        // Default userId for uris in the intent (if they don't specify it themselves)
7294        int contentUserHint = intent.getContentUserHint();
7295        if (contentUserHint == UserHandle.USER_CURRENT) {
7296            contentUserHint = UserHandle.getUserId(callingUid);
7297        }
7298        final IPackageManager pm = AppGlobals.getPackageManager();
7299        int targetUid;
7300        if (needed != null) {
7301            targetUid = needed.targetUid;
7302        } else {
7303            try {
7304                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7305            } catch (RemoteException ex) {
7306                return null;
7307            }
7308            if (targetUid < 0) {
7309                if (DEBUG_URI_PERMISSION) {
7310                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7311                            + " on user " + targetUserId);
7312                }
7313                return null;
7314            }
7315        }
7316        if (data != null) {
7317            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7318            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7319                    targetUid);
7320            if (targetUid > 0) {
7321                if (needed == null) {
7322                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7323                }
7324                needed.add(grantUri);
7325            }
7326        }
7327        if (clip != null) {
7328            for (int i=0; i<clip.getItemCount(); i++) {
7329                Uri uri = clip.getItemAt(i).getUri();
7330                if (uri != null) {
7331                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7332                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7333                            targetUid);
7334                    if (targetUid > 0) {
7335                        if (needed == null) {
7336                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7337                        }
7338                        needed.add(grantUri);
7339                    }
7340                } else {
7341                    Intent clipIntent = clip.getItemAt(i).getIntent();
7342                    if (clipIntent != null) {
7343                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7344                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7345                        if (newNeeded != null) {
7346                            needed = newNeeded;
7347                        }
7348                    }
7349                }
7350            }
7351        }
7352
7353        return needed;
7354    }
7355
7356    /**
7357     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7358     */
7359    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7360            UriPermissionOwner owner) {
7361        if (needed != null) {
7362            for (int i=0; i<needed.size(); i++) {
7363                GrantUri grantUri = needed.get(i);
7364                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7365                        grantUri, needed.flags, owner);
7366            }
7367        }
7368    }
7369
7370    void grantUriPermissionFromIntentLocked(int callingUid,
7371            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7372        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7373                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7374        if (needed == null) {
7375            return;
7376        }
7377
7378        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7379    }
7380
7381    /**
7382     * @param uri This uri must NOT contain an embedded userId.
7383     * @param userId The userId in which the uri is to be resolved.
7384     */
7385    @Override
7386    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7387            final int modeFlags, int userId) {
7388        enforceNotIsolatedCaller("grantUriPermission");
7389        GrantUri grantUri = new GrantUri(userId, uri, false);
7390        synchronized(this) {
7391            final ProcessRecord r = getRecordForAppLocked(caller);
7392            if (r == null) {
7393                throw new SecurityException("Unable to find app for caller "
7394                        + caller
7395                        + " when granting permission to uri " + grantUri);
7396            }
7397            if (targetPkg == null) {
7398                throw new IllegalArgumentException("null target");
7399            }
7400            if (grantUri == null) {
7401                throw new IllegalArgumentException("null uri");
7402            }
7403
7404            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7405                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7406                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7407                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7408
7409            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7410                    UserHandle.getUserId(r.uid));
7411        }
7412    }
7413
7414    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7415        if (perm.modeFlags == 0) {
7416            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7417                    perm.targetUid);
7418            if (perms != null) {
7419                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7420                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7421
7422                perms.remove(perm.uri);
7423                if (perms.isEmpty()) {
7424                    mGrantedUriPermissions.remove(perm.targetUid);
7425                }
7426            }
7427        }
7428    }
7429
7430    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7431        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7432
7433        final IPackageManager pm = AppGlobals.getPackageManager();
7434        final String authority = grantUri.uri.getAuthority();
7435        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7436        if (pi == null) {
7437            Slog.w(TAG, "No content provider found for permission revoke: "
7438                    + grantUri.toSafeString());
7439            return;
7440        }
7441
7442        // Does the caller have this permission on the URI?
7443        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7444            // If they don't have direct access to the URI, then revoke any
7445            // ownerless URI permissions that have been granted to them.
7446            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7447            if (perms != null) {
7448                boolean persistChanged = false;
7449                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7450                    final UriPermission perm = it.next();
7451                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7452                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7453                        if (DEBUG_URI_PERMISSION)
7454                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7455                                    " permission to " + perm.uri);
7456                        persistChanged |= perm.revokeModes(
7457                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7458                        if (perm.modeFlags == 0) {
7459                            it.remove();
7460                        }
7461                    }
7462                }
7463                if (perms.isEmpty()) {
7464                    mGrantedUriPermissions.remove(callingUid);
7465                }
7466                if (persistChanged) {
7467                    schedulePersistUriGrants();
7468                }
7469            }
7470            return;
7471        }
7472
7473        boolean persistChanged = false;
7474
7475        // Go through all of the permissions and remove any that match.
7476        int N = mGrantedUriPermissions.size();
7477        for (int i = 0; i < N; i++) {
7478            final int targetUid = mGrantedUriPermissions.keyAt(i);
7479            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7480
7481            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7482                final UriPermission perm = it.next();
7483                if (perm.uri.sourceUserId == grantUri.sourceUserId
7484                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7485                    if (DEBUG_URI_PERMISSION)
7486                        Slog.v(TAG,
7487                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7488                    persistChanged |= perm.revokeModes(
7489                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7490                    if (perm.modeFlags == 0) {
7491                        it.remove();
7492                    }
7493                }
7494            }
7495
7496            if (perms.isEmpty()) {
7497                mGrantedUriPermissions.remove(targetUid);
7498                N--;
7499                i--;
7500            }
7501        }
7502
7503        if (persistChanged) {
7504            schedulePersistUriGrants();
7505        }
7506    }
7507
7508    /**
7509     * @param uri This uri must NOT contain an embedded userId.
7510     * @param userId The userId in which the uri is to be resolved.
7511     */
7512    @Override
7513    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7514            int userId) {
7515        enforceNotIsolatedCaller("revokeUriPermission");
7516        synchronized(this) {
7517            final ProcessRecord r = getRecordForAppLocked(caller);
7518            if (r == null) {
7519                throw new SecurityException("Unable to find app for caller "
7520                        + caller
7521                        + " when revoking permission to uri " + uri);
7522            }
7523            if (uri == null) {
7524                Slog.w(TAG, "revokeUriPermission: null uri");
7525                return;
7526            }
7527
7528            if (!Intent.isAccessUriMode(modeFlags)) {
7529                return;
7530            }
7531
7532            final IPackageManager pm = AppGlobals.getPackageManager();
7533            final String authority = uri.getAuthority();
7534            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7535            if (pi == null) {
7536                Slog.w(TAG, "No content provider found for permission revoke: "
7537                        + uri.toSafeString());
7538                return;
7539            }
7540
7541            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7542        }
7543    }
7544
7545    /**
7546     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7547     * given package.
7548     *
7549     * @param packageName Package name to match, or {@code null} to apply to all
7550     *            packages.
7551     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7552     *            to all users.
7553     * @param persistable If persistable grants should be removed.
7554     */
7555    private void removeUriPermissionsForPackageLocked(
7556            String packageName, int userHandle, boolean persistable) {
7557        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7558            throw new IllegalArgumentException("Must narrow by either package or user");
7559        }
7560
7561        boolean persistChanged = false;
7562
7563        int N = mGrantedUriPermissions.size();
7564        for (int i = 0; i < N; i++) {
7565            final int targetUid = mGrantedUriPermissions.keyAt(i);
7566            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7567
7568            // Only inspect grants matching user
7569            if (userHandle == UserHandle.USER_ALL
7570                    || userHandle == UserHandle.getUserId(targetUid)) {
7571                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7572                    final UriPermission perm = it.next();
7573
7574                    // Only inspect grants matching package
7575                    if (packageName == null || perm.sourcePkg.equals(packageName)
7576                            || perm.targetPkg.equals(packageName)) {
7577                        persistChanged |= perm.revokeModes(persistable
7578                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7579
7580                        // Only remove when no modes remain; any persisted grants
7581                        // will keep this alive.
7582                        if (perm.modeFlags == 0) {
7583                            it.remove();
7584                        }
7585                    }
7586                }
7587
7588                if (perms.isEmpty()) {
7589                    mGrantedUriPermissions.remove(targetUid);
7590                    N--;
7591                    i--;
7592                }
7593            }
7594        }
7595
7596        if (persistChanged) {
7597            schedulePersistUriGrants();
7598        }
7599    }
7600
7601    @Override
7602    public IBinder newUriPermissionOwner(String name) {
7603        enforceNotIsolatedCaller("newUriPermissionOwner");
7604        synchronized(this) {
7605            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7606            return owner.getExternalTokenLocked();
7607        }
7608    }
7609
7610    /**
7611     * @param uri This uri must NOT contain an embedded userId.
7612     * @param sourceUserId The userId in which the uri is to be resolved.
7613     * @param targetUserId The userId of the app that receives the grant.
7614     */
7615    @Override
7616    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7617            final int modeFlags, int sourceUserId, int targetUserId) {
7618        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7619                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7620        synchronized(this) {
7621            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7622            if (owner == null) {
7623                throw new IllegalArgumentException("Unknown owner: " + token);
7624            }
7625            if (fromUid != Binder.getCallingUid()) {
7626                if (Binder.getCallingUid() != Process.myUid()) {
7627                    // Only system code can grant URI permissions on behalf
7628                    // of other users.
7629                    throw new SecurityException("nice try");
7630                }
7631            }
7632            if (targetPkg == null) {
7633                throw new IllegalArgumentException("null target");
7634            }
7635            if (uri == null) {
7636                throw new IllegalArgumentException("null uri");
7637            }
7638
7639            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7640                    modeFlags, owner, targetUserId);
7641        }
7642    }
7643
7644    /**
7645     * @param uri This uri must NOT contain an embedded userId.
7646     * @param userId The userId in which the uri is to be resolved.
7647     */
7648    @Override
7649    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7650        synchronized(this) {
7651            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7652            if (owner == null) {
7653                throw new IllegalArgumentException("Unknown owner: " + token);
7654            }
7655
7656            if (uri == null) {
7657                owner.removeUriPermissionsLocked(mode);
7658            } else {
7659                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7660            }
7661        }
7662    }
7663
7664    private void schedulePersistUriGrants() {
7665        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7666            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7667                    10 * DateUtils.SECOND_IN_MILLIS);
7668        }
7669    }
7670
7671    private void writeGrantedUriPermissions() {
7672        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7673
7674        // Snapshot permissions so we can persist without lock
7675        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7676        synchronized (this) {
7677            final int size = mGrantedUriPermissions.size();
7678            for (int i = 0; i < size; i++) {
7679                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7680                for (UriPermission perm : perms.values()) {
7681                    if (perm.persistedModeFlags != 0) {
7682                        persist.add(perm.snapshot());
7683                    }
7684                }
7685            }
7686        }
7687
7688        FileOutputStream fos = null;
7689        try {
7690            fos = mGrantFile.startWrite();
7691
7692            XmlSerializer out = new FastXmlSerializer();
7693            out.setOutput(fos, "utf-8");
7694            out.startDocument(null, true);
7695            out.startTag(null, TAG_URI_GRANTS);
7696            for (UriPermission.Snapshot perm : persist) {
7697                out.startTag(null, TAG_URI_GRANT);
7698                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7699                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7700                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7701                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7702                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7703                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7704                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7705                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7706                out.endTag(null, TAG_URI_GRANT);
7707            }
7708            out.endTag(null, TAG_URI_GRANTS);
7709            out.endDocument();
7710
7711            mGrantFile.finishWrite(fos);
7712        } catch (IOException e) {
7713            if (fos != null) {
7714                mGrantFile.failWrite(fos);
7715            }
7716        }
7717    }
7718
7719    private void readGrantedUriPermissionsLocked() {
7720        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7721
7722        final long now = System.currentTimeMillis();
7723
7724        FileInputStream fis = null;
7725        try {
7726            fis = mGrantFile.openRead();
7727            final XmlPullParser in = Xml.newPullParser();
7728            in.setInput(fis, null);
7729
7730            int type;
7731            while ((type = in.next()) != END_DOCUMENT) {
7732                final String tag = in.getName();
7733                if (type == START_TAG) {
7734                    if (TAG_URI_GRANT.equals(tag)) {
7735                        final int sourceUserId;
7736                        final int targetUserId;
7737                        final int userHandle = readIntAttribute(in,
7738                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7739                        if (userHandle != UserHandle.USER_NULL) {
7740                            // For backwards compatibility.
7741                            sourceUserId = userHandle;
7742                            targetUserId = userHandle;
7743                        } else {
7744                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7745                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7746                        }
7747                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7748                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7749                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7750                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7751                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7752                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7753
7754                        // Sanity check that provider still belongs to source package
7755                        final ProviderInfo pi = getProviderInfoLocked(
7756                                uri.getAuthority(), sourceUserId);
7757                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7758                            int targetUid = -1;
7759                            try {
7760                                targetUid = AppGlobals.getPackageManager()
7761                                        .getPackageUid(targetPkg, targetUserId);
7762                            } catch (RemoteException e) {
7763                            }
7764                            if (targetUid != -1) {
7765                                final UriPermission perm = findOrCreateUriPermissionLocked(
7766                                        sourcePkg, targetPkg, targetUid,
7767                                        new GrantUri(sourceUserId, uri, prefix));
7768                                perm.initPersistedModes(modeFlags, createdTime);
7769                            }
7770                        } else {
7771                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7772                                    + " but instead found " + pi);
7773                        }
7774                    }
7775                }
7776            }
7777        } catch (FileNotFoundException e) {
7778            // Missing grants is okay
7779        } catch (IOException e) {
7780            Slog.wtf(TAG, "Failed reading Uri grants", e);
7781        } catch (XmlPullParserException e) {
7782            Slog.wtf(TAG, "Failed reading Uri grants", e);
7783        } finally {
7784            IoUtils.closeQuietly(fis);
7785        }
7786    }
7787
7788    /**
7789     * @param uri This uri must NOT contain an embedded userId.
7790     * @param userId The userId in which the uri is to be resolved.
7791     */
7792    @Override
7793    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7794        enforceNotIsolatedCaller("takePersistableUriPermission");
7795
7796        Preconditions.checkFlagsArgument(modeFlags,
7797                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7798
7799        synchronized (this) {
7800            final int callingUid = Binder.getCallingUid();
7801            boolean persistChanged = false;
7802            GrantUri grantUri = new GrantUri(userId, uri, false);
7803
7804            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7805                    new GrantUri(userId, uri, false));
7806            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7807                    new GrantUri(userId, uri, true));
7808
7809            final boolean exactValid = (exactPerm != null)
7810                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7811            final boolean prefixValid = (prefixPerm != null)
7812                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7813
7814            if (!(exactValid || prefixValid)) {
7815                throw new SecurityException("No persistable permission grants found for UID "
7816                        + callingUid + " and Uri " + grantUri.toSafeString());
7817            }
7818
7819            if (exactValid) {
7820                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7821            }
7822            if (prefixValid) {
7823                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7824            }
7825
7826            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7827
7828            if (persistChanged) {
7829                schedulePersistUriGrants();
7830            }
7831        }
7832    }
7833
7834    /**
7835     * @param uri This uri must NOT contain an embedded userId.
7836     * @param userId The userId in which the uri is to be resolved.
7837     */
7838    @Override
7839    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7840        enforceNotIsolatedCaller("releasePersistableUriPermission");
7841
7842        Preconditions.checkFlagsArgument(modeFlags,
7843                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7844
7845        synchronized (this) {
7846            final int callingUid = Binder.getCallingUid();
7847            boolean persistChanged = false;
7848
7849            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7850                    new GrantUri(userId, uri, false));
7851            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7852                    new GrantUri(userId, uri, true));
7853            if (exactPerm == null && prefixPerm == null) {
7854                throw new SecurityException("No permission grants found for UID " + callingUid
7855                        + " and Uri " + uri.toSafeString());
7856            }
7857
7858            if (exactPerm != null) {
7859                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7860                removeUriPermissionIfNeededLocked(exactPerm);
7861            }
7862            if (prefixPerm != null) {
7863                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7864                removeUriPermissionIfNeededLocked(prefixPerm);
7865            }
7866
7867            if (persistChanged) {
7868                schedulePersistUriGrants();
7869            }
7870        }
7871    }
7872
7873    /**
7874     * Prune any older {@link UriPermission} for the given UID until outstanding
7875     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7876     *
7877     * @return if any mutations occured that require persisting.
7878     */
7879    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7880        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7881        if (perms == null) return false;
7882        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7883
7884        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7885        for (UriPermission perm : perms.values()) {
7886            if (perm.persistedModeFlags != 0) {
7887                persisted.add(perm);
7888            }
7889        }
7890
7891        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7892        if (trimCount <= 0) return false;
7893
7894        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7895        for (int i = 0; i < trimCount; i++) {
7896            final UriPermission perm = persisted.get(i);
7897
7898            if (DEBUG_URI_PERMISSION) {
7899                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7900            }
7901
7902            perm.releasePersistableModes(~0);
7903            removeUriPermissionIfNeededLocked(perm);
7904        }
7905
7906        return true;
7907    }
7908
7909    @Override
7910    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7911            String packageName, boolean incoming) {
7912        enforceNotIsolatedCaller("getPersistedUriPermissions");
7913        Preconditions.checkNotNull(packageName, "packageName");
7914
7915        final int callingUid = Binder.getCallingUid();
7916        final IPackageManager pm = AppGlobals.getPackageManager();
7917        try {
7918            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7919            if (packageUid != callingUid) {
7920                throw new SecurityException(
7921                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7922            }
7923        } catch (RemoteException e) {
7924            throw new SecurityException("Failed to verify package name ownership");
7925        }
7926
7927        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7928        synchronized (this) {
7929            if (incoming) {
7930                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7931                        callingUid);
7932                if (perms == null) {
7933                    Slog.w(TAG, "No permission grants found for " + packageName);
7934                } else {
7935                    for (UriPermission perm : perms.values()) {
7936                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7937                            result.add(perm.buildPersistedPublicApiObject());
7938                        }
7939                    }
7940                }
7941            } else {
7942                final int size = mGrantedUriPermissions.size();
7943                for (int i = 0; i < size; i++) {
7944                    final ArrayMap<GrantUri, UriPermission> perms =
7945                            mGrantedUriPermissions.valueAt(i);
7946                    for (UriPermission perm : perms.values()) {
7947                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7948                            result.add(perm.buildPersistedPublicApiObject());
7949                        }
7950                    }
7951                }
7952            }
7953        }
7954        return new ParceledListSlice<android.content.UriPermission>(result);
7955    }
7956
7957    @Override
7958    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7959        synchronized (this) {
7960            ProcessRecord app =
7961                who != null ? getRecordForAppLocked(who) : null;
7962            if (app == null) return;
7963
7964            Message msg = Message.obtain();
7965            msg.what = WAIT_FOR_DEBUGGER_MSG;
7966            msg.obj = app;
7967            msg.arg1 = waiting ? 1 : 0;
7968            mHandler.sendMessage(msg);
7969        }
7970    }
7971
7972    @Override
7973    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7974        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7975        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7976        outInfo.availMem = Process.getFreeMemory();
7977        outInfo.totalMem = Process.getTotalMemory();
7978        outInfo.threshold = homeAppMem;
7979        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7980        outInfo.hiddenAppThreshold = cachedAppMem;
7981        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7982                ProcessList.SERVICE_ADJ);
7983        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7984                ProcessList.VISIBLE_APP_ADJ);
7985        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7986                ProcessList.FOREGROUND_APP_ADJ);
7987    }
7988
7989    // =========================================================
7990    // TASK MANAGEMENT
7991    // =========================================================
7992
7993    @Override
7994    public List<IAppTask> getAppTasks(String callingPackage) {
7995        int callingUid = Binder.getCallingUid();
7996        long ident = Binder.clearCallingIdentity();
7997
7998        synchronized(this) {
7999            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8000            try {
8001                if (localLOGV) Slog.v(TAG, "getAppTasks");
8002
8003                final int N = mRecentTasks.size();
8004                for (int i = 0; i < N; i++) {
8005                    TaskRecord tr = mRecentTasks.get(i);
8006                    // Skip tasks that do not match the caller.  We don't need to verify
8007                    // callingPackage, because we are also limiting to callingUid and know
8008                    // that will limit to the correct security sandbox.
8009                    if (tr.effectiveUid != callingUid) {
8010                        continue;
8011                    }
8012                    Intent intent = tr.getBaseIntent();
8013                    if (intent == null ||
8014                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8015                        continue;
8016                    }
8017                    ActivityManager.RecentTaskInfo taskInfo =
8018                            createRecentTaskInfoFromTaskRecord(tr);
8019                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8020                    list.add(taskImpl);
8021                }
8022            } finally {
8023                Binder.restoreCallingIdentity(ident);
8024            }
8025            return list;
8026        }
8027    }
8028
8029    @Override
8030    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8031        final int callingUid = Binder.getCallingUid();
8032        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8033
8034        synchronized(this) {
8035            if (localLOGV) Slog.v(
8036                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8037
8038            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8039                    callingUid);
8040
8041            // TODO: Improve with MRU list from all ActivityStacks.
8042            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8043        }
8044
8045        return list;
8046    }
8047
8048    /**
8049     * Creates a new RecentTaskInfo from a TaskRecord.
8050     */
8051    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8052        // Update the task description to reflect any changes in the task stack
8053        tr.updateTaskDescription();
8054
8055        // Compose the recent task info
8056        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8057        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8058        rti.persistentId = tr.taskId;
8059        rti.baseIntent = new Intent(tr.getBaseIntent());
8060        rti.origActivity = tr.origActivity;
8061        rti.description = tr.lastDescription;
8062        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8063        rti.userId = tr.userId;
8064        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8065        rti.firstActiveTime = tr.firstActiveTime;
8066        rti.lastActiveTime = tr.lastActiveTime;
8067        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8068        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8069        return rti;
8070    }
8071
8072    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8073        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8074                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8075        if (!allowed) {
8076            if (checkPermission(android.Manifest.permission.GET_TASKS,
8077                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8078                // Temporary compatibility: some existing apps on the system image may
8079                // still be requesting the old permission and not switched to the new
8080                // one; if so, we'll still allow them full access.  This means we need
8081                // to see if they are holding the old permission and are a system app.
8082                try {
8083                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8084                        allowed = true;
8085                        Slog.w(TAG, caller + ": caller " + callingUid
8086                                + " is using old GET_TASKS but privileged; allowing");
8087                    }
8088                } catch (RemoteException e) {
8089                }
8090            }
8091        }
8092        if (!allowed) {
8093            Slog.w(TAG, caller + ": caller " + callingUid
8094                    + " does not hold GET_TASKS; limiting output");
8095        }
8096        return allowed;
8097    }
8098
8099    @Override
8100    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8101        final int callingUid = Binder.getCallingUid();
8102        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8103                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8104
8105        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8106        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8107        synchronized (this) {
8108            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8109                    callingUid);
8110            final boolean detailed = checkCallingPermission(
8111                    android.Manifest.permission.GET_DETAILED_TASKS)
8112                    == PackageManager.PERMISSION_GRANTED;
8113
8114            final int N = mRecentTasks.size();
8115            ArrayList<ActivityManager.RecentTaskInfo> res
8116                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8117                            maxNum < N ? maxNum : N);
8118
8119            final Set<Integer> includedUsers;
8120            if (includeProfiles) {
8121                includedUsers = getProfileIdsLocked(userId);
8122            } else {
8123                includedUsers = new HashSet<Integer>();
8124            }
8125            includedUsers.add(Integer.valueOf(userId));
8126
8127            for (int i=0; i<N && maxNum > 0; i++) {
8128                TaskRecord tr = mRecentTasks.get(i);
8129                // Only add calling user or related users recent tasks
8130                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8131                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8132                    continue;
8133                }
8134
8135                // Return the entry if desired by the caller.  We always return
8136                // the first entry, because callers always expect this to be the
8137                // foreground app.  We may filter others if the caller has
8138                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8139                // we should exclude the entry.
8140
8141                if (i == 0
8142                        || withExcluded
8143                        || (tr.intent == null)
8144                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8145                                == 0)) {
8146                    if (!allowed) {
8147                        // If the caller doesn't have the GET_TASKS permission, then only
8148                        // allow them to see a small subset of tasks -- their own and home.
8149                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8150                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8151                            continue;
8152                        }
8153                    }
8154                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8155                        if (tr.stack != null && tr.stack.isHomeStack()) {
8156                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8157                            continue;
8158                        }
8159                    }
8160                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8161                        // Don't include auto remove tasks that are finished or finishing.
8162                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8163                                + tr);
8164                        continue;
8165                    }
8166                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8167                            && !tr.isAvailable) {
8168                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8169                        continue;
8170                    }
8171
8172                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8173                    if (!detailed) {
8174                        rti.baseIntent.replaceExtras((Bundle)null);
8175                    }
8176
8177                    res.add(rti);
8178                    maxNum--;
8179                }
8180            }
8181            return res;
8182        }
8183    }
8184
8185    TaskRecord recentTaskForIdLocked(int id) {
8186        final int N = mRecentTasks.size();
8187            for (int i=0; i<N; i++) {
8188                TaskRecord tr = mRecentTasks.get(i);
8189                if (tr.taskId == id) {
8190                    return tr;
8191                }
8192            }
8193            return null;
8194    }
8195
8196    @Override
8197    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8198        synchronized (this) {
8199            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8200                    "getTaskThumbnail()");
8201            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8202            if (tr != null) {
8203                return tr.getTaskThumbnailLocked();
8204            }
8205        }
8206        return null;
8207    }
8208
8209    @Override
8210    public int addAppTask(IBinder activityToken, Intent intent,
8211            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8212        final int callingUid = Binder.getCallingUid();
8213        final long callingIdent = Binder.clearCallingIdentity();
8214
8215        try {
8216            synchronized (this) {
8217                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8218                if (r == null) {
8219                    throw new IllegalArgumentException("Activity does not exist; token="
8220                            + activityToken);
8221                }
8222                ComponentName comp = intent.getComponent();
8223                if (comp == null) {
8224                    throw new IllegalArgumentException("Intent " + intent
8225                            + " must specify explicit component");
8226                }
8227                if (thumbnail.getWidth() != mThumbnailWidth
8228                        || thumbnail.getHeight() != mThumbnailHeight) {
8229                    throw new IllegalArgumentException("Bad thumbnail size: got "
8230                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8231                            + mThumbnailWidth + "x" + mThumbnailHeight);
8232                }
8233                if (intent.getSelector() != null) {
8234                    intent.setSelector(null);
8235                }
8236                if (intent.getSourceBounds() != null) {
8237                    intent.setSourceBounds(null);
8238                }
8239                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8240                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8241                        // The caller has added this as an auto-remove task...  that makes no
8242                        // sense, so turn off auto-remove.
8243                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8244                    }
8245                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8246                    // Must be a new task.
8247                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8248                }
8249                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8250                    mLastAddedTaskActivity = null;
8251                }
8252                ActivityInfo ainfo = mLastAddedTaskActivity;
8253                if (ainfo == null) {
8254                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8255                            comp, 0, UserHandle.getUserId(callingUid));
8256                    if (ainfo.applicationInfo.uid != callingUid) {
8257                        throw new SecurityException(
8258                                "Can't add task for another application: target uid="
8259                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8260                    }
8261                }
8262
8263                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8264                        intent, description);
8265
8266                int trimIdx = trimRecentsForTaskLocked(task, false);
8267                if (trimIdx >= 0) {
8268                    // If this would have caused a trim, then we'll abort because that
8269                    // means it would be added at the end of the list but then just removed.
8270                    return INVALID_TASK_ID;
8271                }
8272
8273                final int N = mRecentTasks.size();
8274                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8275                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8276                    tr.removedFromRecents();
8277                }
8278
8279                task.inRecents = true;
8280                mRecentTasks.add(task);
8281                r.task.stack.addTask(task, false, false);
8282
8283                task.setLastThumbnail(thumbnail);
8284                task.freeLastThumbnail();
8285
8286                return task.taskId;
8287            }
8288        } finally {
8289            Binder.restoreCallingIdentity(callingIdent);
8290        }
8291    }
8292
8293    @Override
8294    public Point getAppTaskThumbnailSize() {
8295        synchronized (this) {
8296            return new Point(mThumbnailWidth,  mThumbnailHeight);
8297        }
8298    }
8299
8300    @Override
8301    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8302        synchronized (this) {
8303            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8304            if (r != null) {
8305                r.setTaskDescription(td);
8306                r.task.updateTaskDescription();
8307            }
8308        }
8309    }
8310
8311    @Override
8312    public Bitmap getTaskDescriptionIcon(String filename) {
8313        if (!FileUtils.isValidExtFilename(filename)
8314                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8315            throw new IllegalArgumentException("Bad filename: " + filename);
8316        }
8317        return mTaskPersister.getTaskDescriptionIcon(filename);
8318    }
8319
8320    @Override
8321    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8322            throws RemoteException {
8323        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8324                opts.getCustomInPlaceResId() == 0) {
8325            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8326                    "with valid animation");
8327        }
8328        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8329        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8330                opts.getCustomInPlaceResId());
8331        mWindowManager.executeAppTransition();
8332    }
8333
8334    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8335        mRecentTasks.remove(tr);
8336        tr.removedFromRecents();
8337        ComponentName component = tr.getBaseIntent().getComponent();
8338        if (component == null) {
8339            Slog.w(TAG, "No component for base intent of task: " + tr);
8340            return;
8341        }
8342
8343        if (!killProcess) {
8344            return;
8345        }
8346
8347        // Determine if the process(es) for this task should be killed.
8348        final String pkg = component.getPackageName();
8349        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8350        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8351        for (int i = 0; i < pmap.size(); i++) {
8352
8353            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8354            for (int j = 0; j < uids.size(); j++) {
8355                ProcessRecord proc = uids.valueAt(j);
8356                if (proc.userId != tr.userId) {
8357                    // Don't kill process for a different user.
8358                    continue;
8359                }
8360                if (proc == mHomeProcess) {
8361                    // Don't kill the home process along with tasks from the same package.
8362                    continue;
8363                }
8364                if (!proc.pkgList.containsKey(pkg)) {
8365                    // Don't kill process that is not associated with this task.
8366                    continue;
8367                }
8368
8369                for (int k = 0; k < proc.activities.size(); k++) {
8370                    TaskRecord otherTask = proc.activities.get(k).task;
8371                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8372                        // Don't kill process(es) that has an activity in a different task that is
8373                        // also in recents.
8374                        return;
8375                    }
8376                }
8377
8378                // Add process to kill list.
8379                procsToKill.add(proc);
8380            }
8381        }
8382
8383        // Find any running services associated with this app and stop if needed.
8384        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8385
8386        // Kill the running processes.
8387        for (int i = 0; i < procsToKill.size(); i++) {
8388            ProcessRecord pr = procsToKill.get(i);
8389            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8390                pr.kill("remove task", true);
8391            } else {
8392                pr.waitingToKill = "remove task";
8393            }
8394        }
8395    }
8396
8397    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8398        // Remove all tasks with activities in the specified package from the list of recent tasks
8399        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8400            TaskRecord tr = mRecentTasks.get(i);
8401            if (tr.userId != userId) continue;
8402
8403            ComponentName cn = tr.intent.getComponent();
8404            if (cn != null && cn.getPackageName().equals(packageName)) {
8405                // If the package name matches, remove the task.
8406                removeTaskByIdLocked(tr.taskId, true);
8407            }
8408        }
8409    }
8410
8411    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8412        final IPackageManager pm = AppGlobals.getPackageManager();
8413        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8414
8415        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8416            TaskRecord tr = mRecentTasks.get(i);
8417            if (tr.userId != userId) continue;
8418
8419            ComponentName cn = tr.intent.getComponent();
8420            if (cn != null && cn.getPackageName().equals(packageName)) {
8421                // Skip if component still exists in the package.
8422                if (componentsKnownToExist.contains(cn)) continue;
8423
8424                try {
8425                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8426                    if (info != null) {
8427                        componentsKnownToExist.add(cn);
8428                    } else {
8429                        removeTaskByIdLocked(tr.taskId, false);
8430                    }
8431                } catch (RemoteException e) {
8432                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8433                }
8434            }
8435        }
8436    }
8437
8438    /**
8439     * Removes the task with the specified task id.
8440     *
8441     * @param taskId Identifier of the task to be removed.
8442     * @param killProcess Kill any process associated with the task if possible.
8443     * @return Returns true if the given task was found and removed.
8444     */
8445    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8446        TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8447        if (tr != null) {
8448            tr.removeTaskActivitiesLocked();
8449            cleanUpRemovedTaskLocked(tr, killProcess);
8450            if (tr.isPersistable) {
8451                notifyTaskPersisterLocked(null, true);
8452            }
8453            return true;
8454        }
8455        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8456        return false;
8457    }
8458
8459    @Override
8460    public boolean removeTask(int taskId) {
8461        synchronized (this) {
8462            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8463                    "removeTask()");
8464            long ident = Binder.clearCallingIdentity();
8465            try {
8466                return removeTaskByIdLocked(taskId, true);
8467            } finally {
8468                Binder.restoreCallingIdentity(ident);
8469            }
8470        }
8471    }
8472
8473    /**
8474     * TODO: Add mController hook
8475     */
8476    @Override
8477    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8478        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8479                "moveTaskToFront()");
8480
8481        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8482        synchronized(this) {
8483            moveTaskToFrontLocked(taskId, flags, options);
8484        }
8485    }
8486
8487    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8488        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8489                Binder.getCallingUid(), -1, -1, "Task to front")) {
8490            ActivityOptions.abort(options);
8491            return;
8492        }
8493        final long origId = Binder.clearCallingIdentity();
8494        try {
8495            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8496            if (task == null) {
8497                Slog.d(TAG, "Could not find task for id: "+ taskId);
8498                return;
8499            }
8500            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8501                mStackSupervisor.showLockTaskToast();
8502                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8503                return;
8504            }
8505            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8506            if (prev != null && prev.isRecentsActivity()) {
8507                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8508            }
8509            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8510        } finally {
8511            Binder.restoreCallingIdentity(origId);
8512        }
8513        ActivityOptions.abort(options);
8514    }
8515
8516    @Override
8517    public void moveTaskToBack(int taskId) {
8518        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8519                "moveTaskToBack()");
8520
8521        synchronized(this) {
8522            TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8523            if (tr != null) {
8524                if (tr == mStackSupervisor.mLockTaskModeTask) {
8525                    mStackSupervisor.showLockTaskToast();
8526                    return;
8527                }
8528                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8529                ActivityStack stack = tr.stack;
8530                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8531                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8532                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8533                        return;
8534                    }
8535                }
8536                final long origId = Binder.clearCallingIdentity();
8537                try {
8538                    stack.moveTaskToBackLocked(taskId, null);
8539                } finally {
8540                    Binder.restoreCallingIdentity(origId);
8541                }
8542            }
8543        }
8544    }
8545
8546    /**
8547     * Moves an activity, and all of the other activities within the same task, to the bottom
8548     * of the history stack.  The activity's order within the task is unchanged.
8549     *
8550     * @param token A reference to the activity we wish to move
8551     * @param nonRoot If false then this only works if the activity is the root
8552     *                of a task; if true it will work for any activity in a task.
8553     * @return Returns true if the move completed, false if not.
8554     */
8555    @Override
8556    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8557        enforceNotIsolatedCaller("moveActivityTaskToBack");
8558        synchronized(this) {
8559            final long origId = Binder.clearCallingIdentity();
8560            try {
8561                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8562                if (taskId >= 0) {
8563                    if ((mStackSupervisor.mLockTaskModeTask != null)
8564                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8565                        mStackSupervisor.showLockTaskToast();
8566                        return false;
8567                    }
8568                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8569                }
8570            } finally {
8571                Binder.restoreCallingIdentity(origId);
8572            }
8573        }
8574        return false;
8575    }
8576
8577    @Override
8578    public void moveTaskBackwards(int task) {
8579        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8580                "moveTaskBackwards()");
8581
8582        synchronized(this) {
8583            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8584                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8585                return;
8586            }
8587            final long origId = Binder.clearCallingIdentity();
8588            moveTaskBackwardsLocked(task);
8589            Binder.restoreCallingIdentity(origId);
8590        }
8591    }
8592
8593    private final void moveTaskBackwardsLocked(int task) {
8594        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8595    }
8596
8597    @Override
8598    public IBinder getHomeActivityToken() throws RemoteException {
8599        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8600                "getHomeActivityToken()");
8601        synchronized (this) {
8602            return mStackSupervisor.getHomeActivityToken();
8603        }
8604    }
8605
8606    @Override
8607    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8608            IActivityContainerCallback callback) throws RemoteException {
8609        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8610                "createActivityContainer()");
8611        synchronized (this) {
8612            if (parentActivityToken == null) {
8613                throw new IllegalArgumentException("parent token must not be null");
8614            }
8615            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8616            if (r == null) {
8617                return null;
8618            }
8619            if (callback == null) {
8620                throw new IllegalArgumentException("callback must not be null");
8621            }
8622            return mStackSupervisor.createActivityContainer(r, callback);
8623        }
8624    }
8625
8626    @Override
8627    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8628        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8629                "deleteActivityContainer()");
8630        synchronized (this) {
8631            mStackSupervisor.deleteActivityContainer(container);
8632        }
8633    }
8634
8635    @Override
8636    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8637            throws RemoteException {
8638        synchronized (this) {
8639            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8640            if (stack != null) {
8641                return stack.mActivityContainer;
8642            }
8643            return null;
8644        }
8645    }
8646
8647    @Override
8648    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8649        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8650                "moveTaskToStack()");
8651        if (stackId == HOME_STACK_ID) {
8652            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8653                    new RuntimeException("here").fillInStackTrace());
8654        }
8655        synchronized (this) {
8656            long ident = Binder.clearCallingIdentity();
8657            try {
8658                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8659                        + stackId + " toTop=" + toTop);
8660                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8661            } finally {
8662                Binder.restoreCallingIdentity(ident);
8663            }
8664        }
8665    }
8666
8667    @Override
8668    public void resizeStack(int stackBoxId, Rect bounds) {
8669        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8670                "resizeStackBox()");
8671        long ident = Binder.clearCallingIdentity();
8672        try {
8673            mWindowManager.resizeStack(stackBoxId, bounds);
8674        } finally {
8675            Binder.restoreCallingIdentity(ident);
8676        }
8677    }
8678
8679    @Override
8680    public List<StackInfo> getAllStackInfos() {
8681        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8682                "getAllStackInfos()");
8683        long ident = Binder.clearCallingIdentity();
8684        try {
8685            synchronized (this) {
8686                return mStackSupervisor.getAllStackInfosLocked();
8687            }
8688        } finally {
8689            Binder.restoreCallingIdentity(ident);
8690        }
8691    }
8692
8693    @Override
8694    public StackInfo getStackInfo(int stackId) {
8695        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8696                "getStackInfo()");
8697        long ident = Binder.clearCallingIdentity();
8698        try {
8699            synchronized (this) {
8700                return mStackSupervisor.getStackInfoLocked(stackId);
8701            }
8702        } finally {
8703            Binder.restoreCallingIdentity(ident);
8704        }
8705    }
8706
8707    @Override
8708    public boolean isInHomeStack(int taskId) {
8709        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8710                "getStackInfo()");
8711        long ident = Binder.clearCallingIdentity();
8712        try {
8713            synchronized (this) {
8714                TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8715                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8716            }
8717        } finally {
8718            Binder.restoreCallingIdentity(ident);
8719        }
8720    }
8721
8722    @Override
8723    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8724        synchronized(this) {
8725            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8726        }
8727    }
8728
8729    private boolean isLockTaskAuthorized(String pkg) {
8730        final DevicePolicyManager dpm = (DevicePolicyManager)
8731                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8732        try {
8733            int uid = mContext.getPackageManager().getPackageUid(pkg,
8734                    Binder.getCallingUserHandle().getIdentifier());
8735            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8736        } catch (NameNotFoundException e) {
8737            return false;
8738        }
8739    }
8740
8741    void startLockTaskMode(TaskRecord task) {
8742        final String pkg;
8743        synchronized (this) {
8744            pkg = task.intent.getComponent().getPackageName();
8745        }
8746        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8747        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8748            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8749                    StatusBarManagerInternal.class);
8750            if (statusBarManager != null) {
8751                statusBarManager.showScreenPinningRequest();
8752            }
8753            return;
8754        }
8755        long ident = Binder.clearCallingIdentity();
8756        try {
8757            synchronized (this) {
8758                // Since we lost lock on task, make sure it is still there.
8759                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8760                if (task != null) {
8761                    if (!isSystemInitiated
8762                            && ((mStackSupervisor.getFocusedStack() == null)
8763                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8764                        throw new IllegalArgumentException("Invalid task, not in foreground");
8765                    }
8766                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8767                }
8768            }
8769        } finally {
8770            Binder.restoreCallingIdentity(ident);
8771        }
8772    }
8773
8774    @Override
8775    public void startLockTaskMode(int taskId) {
8776        final TaskRecord task;
8777        long ident = Binder.clearCallingIdentity();
8778        try {
8779            synchronized (this) {
8780                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8781            }
8782        } finally {
8783            Binder.restoreCallingIdentity(ident);
8784        }
8785        if (task != null) {
8786            startLockTaskMode(task);
8787        }
8788    }
8789
8790    @Override
8791    public void startLockTaskMode(IBinder token) {
8792        final TaskRecord task;
8793        long ident = Binder.clearCallingIdentity();
8794        try {
8795            synchronized (this) {
8796                final ActivityRecord r = ActivityRecord.forToken(token);
8797                if (r == null) {
8798                    return;
8799                }
8800                task = r.task;
8801            }
8802        } finally {
8803            Binder.restoreCallingIdentity(ident);
8804        }
8805        if (task != null) {
8806            startLockTaskMode(task);
8807        }
8808    }
8809
8810    @Override
8811    public void startLockTaskModeOnCurrent() throws RemoteException {
8812        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8813                "startLockTaskModeOnCurrent");
8814        long ident = Binder.clearCallingIdentity();
8815        try {
8816            ActivityRecord r = null;
8817            synchronized (this) {
8818                r = mStackSupervisor.topRunningActivityLocked();
8819            }
8820            startLockTaskMode(r.task);
8821        } finally {
8822            Binder.restoreCallingIdentity(ident);
8823        }
8824    }
8825
8826    @Override
8827    public void stopLockTaskMode() {
8828        // Verify that the user matches the package of the intent for the TaskRecord
8829        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8830        // and stopLockTaskMode.
8831        final int callingUid = Binder.getCallingUid();
8832        if (callingUid != Process.SYSTEM_UID) {
8833            try {
8834                String pkg =
8835                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8836                int uid = mContext.getPackageManager().getPackageUid(pkg,
8837                        Binder.getCallingUserHandle().getIdentifier());
8838                if (uid != callingUid) {
8839                    throw new SecurityException("Invalid uid, expected " + uid);
8840                }
8841            } catch (NameNotFoundException e) {
8842                Log.d(TAG, "stopLockTaskMode " + e);
8843                return;
8844            }
8845        }
8846        long ident = Binder.clearCallingIdentity();
8847        try {
8848            Log.d(TAG, "stopLockTaskMode");
8849            // Stop lock task
8850            synchronized (this) {
8851                mStackSupervisor.setLockTaskModeLocked(null, false);
8852            }
8853        } finally {
8854            Binder.restoreCallingIdentity(ident);
8855        }
8856    }
8857
8858    @Override
8859    public void stopLockTaskModeOnCurrent() throws RemoteException {
8860        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8861                "stopLockTaskModeOnCurrent");
8862        long ident = Binder.clearCallingIdentity();
8863        try {
8864            stopLockTaskMode();
8865        } finally {
8866            Binder.restoreCallingIdentity(ident);
8867        }
8868    }
8869
8870    @Override
8871    public boolean isInLockTaskMode() {
8872        synchronized (this) {
8873            return mStackSupervisor.isInLockTaskMode();
8874        }
8875    }
8876
8877    // =========================================================
8878    // CONTENT PROVIDERS
8879    // =========================================================
8880
8881    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8882        List<ProviderInfo> providers = null;
8883        try {
8884            providers = AppGlobals.getPackageManager().
8885                queryContentProviders(app.processName, app.uid,
8886                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8887        } catch (RemoteException ex) {
8888        }
8889        if (DEBUG_MU)
8890            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8891        int userId = app.userId;
8892        if (providers != null) {
8893            int N = providers.size();
8894            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8895            for (int i=0; i<N; i++) {
8896                ProviderInfo cpi =
8897                    (ProviderInfo)providers.get(i);
8898                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8899                        cpi.name, cpi.flags);
8900                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8901                    // This is a singleton provider, but a user besides the
8902                    // default user is asking to initialize a process it runs
8903                    // in...  well, no, it doesn't actually run in this process,
8904                    // it runs in the process of the default user.  Get rid of it.
8905                    providers.remove(i);
8906                    N--;
8907                    i--;
8908                    continue;
8909                }
8910
8911                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8912                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8913                if (cpr == null) {
8914                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8915                    mProviderMap.putProviderByClass(comp, cpr);
8916                }
8917                if (DEBUG_MU)
8918                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8919                app.pubProviders.put(cpi.name, cpr);
8920                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8921                    // Don't add this if it is a platform component that is marked
8922                    // to run in multiple processes, because this is actually
8923                    // part of the framework so doesn't make sense to track as a
8924                    // separate apk in the process.
8925                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8926                            mProcessStats);
8927                }
8928                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8929            }
8930        }
8931        return providers;
8932    }
8933
8934    /**
8935     * Check if {@link ProcessRecord} has a possible chance at accessing the
8936     * given {@link ProviderInfo}. Final permission checking is always done
8937     * in {@link ContentProvider}.
8938     */
8939    private final String checkContentProviderPermissionLocked(
8940            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8941        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8942        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8943        boolean checkedGrants = false;
8944        if (checkUser) {
8945            // Looking for cross-user grants before enforcing the typical cross-users permissions
8946            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8947            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8948                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8949                    return null;
8950                }
8951                checkedGrants = true;
8952            }
8953            userId = handleIncomingUser(callingPid, callingUid, userId,
8954                    false, ALLOW_NON_FULL,
8955                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8956            if (userId != tmpTargetUserId) {
8957                // When we actually went to determine the final targer user ID, this ended
8958                // up different than our initial check for the authority.  This is because
8959                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8960                // SELF.  So we need to re-check the grants again.
8961                checkedGrants = false;
8962            }
8963        }
8964        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8965                cpi.applicationInfo.uid, cpi.exported)
8966                == PackageManager.PERMISSION_GRANTED) {
8967            return null;
8968        }
8969        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8970                cpi.applicationInfo.uid, cpi.exported)
8971                == PackageManager.PERMISSION_GRANTED) {
8972            return null;
8973        }
8974
8975        PathPermission[] pps = cpi.pathPermissions;
8976        if (pps != null) {
8977            int i = pps.length;
8978            while (i > 0) {
8979                i--;
8980                PathPermission pp = pps[i];
8981                String pprperm = pp.getReadPermission();
8982                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8983                        cpi.applicationInfo.uid, cpi.exported)
8984                        == PackageManager.PERMISSION_GRANTED) {
8985                    return null;
8986                }
8987                String ppwperm = pp.getWritePermission();
8988                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8989                        cpi.applicationInfo.uid, cpi.exported)
8990                        == PackageManager.PERMISSION_GRANTED) {
8991                    return null;
8992                }
8993            }
8994        }
8995        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8996            return null;
8997        }
8998
8999        String msg;
9000        if (!cpi.exported) {
9001            msg = "Permission Denial: opening provider " + cpi.name
9002                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9003                    + ", uid=" + callingUid + ") that is not exported from uid "
9004                    + cpi.applicationInfo.uid;
9005        } else {
9006            msg = "Permission Denial: opening provider " + cpi.name
9007                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9008                    + ", uid=" + callingUid + ") requires "
9009                    + cpi.readPermission + " or " + cpi.writePermission;
9010        }
9011        Slog.w(TAG, msg);
9012        return msg;
9013    }
9014
9015    /**
9016     * Returns if the ContentProvider has granted a uri to callingUid
9017     */
9018    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9019        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9020        if (perms != null) {
9021            for (int i=perms.size()-1; i>=0; i--) {
9022                GrantUri grantUri = perms.keyAt(i);
9023                if (grantUri.sourceUserId == userId || !checkUser) {
9024                    if (matchesProvider(grantUri.uri, cpi)) {
9025                        return true;
9026                    }
9027                }
9028            }
9029        }
9030        return false;
9031    }
9032
9033    /**
9034     * Returns true if the uri authority is one of the authorities specified in the provider.
9035     */
9036    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9037        String uriAuth = uri.getAuthority();
9038        String cpiAuth = cpi.authority;
9039        if (cpiAuth.indexOf(';') == -1) {
9040            return cpiAuth.equals(uriAuth);
9041        }
9042        String[] cpiAuths = cpiAuth.split(";");
9043        int length = cpiAuths.length;
9044        for (int i = 0; i < length; i++) {
9045            if (cpiAuths[i].equals(uriAuth)) return true;
9046        }
9047        return false;
9048    }
9049
9050    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9051            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9052        if (r != null) {
9053            for (int i=0; i<r.conProviders.size(); i++) {
9054                ContentProviderConnection conn = r.conProviders.get(i);
9055                if (conn.provider == cpr) {
9056                    if (DEBUG_PROVIDER) Slog.v(TAG,
9057                            "Adding provider requested by "
9058                            + r.processName + " from process "
9059                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9060                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9061                    if (stable) {
9062                        conn.stableCount++;
9063                        conn.numStableIncs++;
9064                    } else {
9065                        conn.unstableCount++;
9066                        conn.numUnstableIncs++;
9067                    }
9068                    return conn;
9069                }
9070            }
9071            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9072            if (stable) {
9073                conn.stableCount = 1;
9074                conn.numStableIncs = 1;
9075            } else {
9076                conn.unstableCount = 1;
9077                conn.numUnstableIncs = 1;
9078            }
9079            cpr.connections.add(conn);
9080            r.conProviders.add(conn);
9081            return conn;
9082        }
9083        cpr.addExternalProcessHandleLocked(externalProcessToken);
9084        return null;
9085    }
9086
9087    boolean decProviderCountLocked(ContentProviderConnection conn,
9088            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9089        if (conn != null) {
9090            cpr = conn.provider;
9091            if (DEBUG_PROVIDER) Slog.v(TAG,
9092                    "Removing provider requested by "
9093                    + conn.client.processName + " from process "
9094                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9095                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9096            if (stable) {
9097                conn.stableCount--;
9098            } else {
9099                conn.unstableCount--;
9100            }
9101            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9102                cpr.connections.remove(conn);
9103                conn.client.conProviders.remove(conn);
9104                return true;
9105            }
9106            return false;
9107        }
9108        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9109        return false;
9110    }
9111
9112    private void checkTime(long startTime, String where) {
9113        long now = SystemClock.elapsedRealtime();
9114        if ((now-startTime) > 1000) {
9115            // If we are taking more than a second, log about it.
9116            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9117        }
9118    }
9119
9120    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9121            String name, IBinder token, boolean stable, int userId) {
9122        ContentProviderRecord cpr;
9123        ContentProviderConnection conn = null;
9124        ProviderInfo cpi = null;
9125
9126        synchronized(this) {
9127            long startTime = SystemClock.elapsedRealtime();
9128
9129            ProcessRecord r = null;
9130            if (caller != null) {
9131                r = getRecordForAppLocked(caller);
9132                if (r == null) {
9133                    throw new SecurityException(
9134                            "Unable to find app for caller " + caller
9135                          + " (pid=" + Binder.getCallingPid()
9136                          + ") when getting content provider " + name);
9137                }
9138            }
9139
9140            boolean checkCrossUser = true;
9141
9142            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9143
9144            // First check if this content provider has been published...
9145            cpr = mProviderMap.getProviderByName(name, userId);
9146            // If that didn't work, check if it exists for user 0 and then
9147            // verify that it's a singleton provider before using it.
9148            if (cpr == null && userId != UserHandle.USER_OWNER) {
9149                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9150                if (cpr != null) {
9151                    cpi = cpr.info;
9152                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9153                            cpi.name, cpi.flags)
9154                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9155                        userId = UserHandle.USER_OWNER;
9156                        checkCrossUser = false;
9157                    } else {
9158                        cpr = null;
9159                        cpi = null;
9160                    }
9161                }
9162            }
9163
9164            boolean providerRunning = cpr != null;
9165            if (providerRunning) {
9166                cpi = cpr.info;
9167                String msg;
9168                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9169                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9170                        != null) {
9171                    throw new SecurityException(msg);
9172                }
9173                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9174
9175                if (r != null && cpr.canRunHere(r)) {
9176                    // This provider has been published or is in the process
9177                    // of being published...  but it is also allowed to run
9178                    // in the caller's process, so don't make a connection
9179                    // and just let the caller instantiate its own instance.
9180                    ContentProviderHolder holder = cpr.newHolder(null);
9181                    // don't give caller the provider object, it needs
9182                    // to make its own.
9183                    holder.provider = null;
9184                    return holder;
9185                }
9186
9187                final long origId = Binder.clearCallingIdentity();
9188
9189                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9190
9191                // In this case the provider instance already exists, so we can
9192                // return it right away.
9193                conn = incProviderCountLocked(r, cpr, token, stable);
9194                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9195                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9196                        // If this is a perceptible app accessing the provider,
9197                        // make sure to count it as being accessed and thus
9198                        // back up on the LRU list.  This is good because
9199                        // content providers are often expensive to start.
9200                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9201                        updateLruProcessLocked(cpr.proc, false, null);
9202                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9203                    }
9204                }
9205
9206                if (cpr.proc != null) {
9207                    if (false) {
9208                        if (cpr.name.flattenToShortString().equals(
9209                                "com.android.providers.calendar/.CalendarProvider2")) {
9210                            Slog.v(TAG, "****************** KILLING "
9211                                + cpr.name.flattenToShortString());
9212                            Process.killProcess(cpr.proc.pid);
9213                        }
9214                    }
9215                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9216                    boolean success = updateOomAdjLocked(cpr.proc);
9217                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9218                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9219                    // NOTE: there is still a race here where a signal could be
9220                    // pending on the process even though we managed to update its
9221                    // adj level.  Not sure what to do about this, but at least
9222                    // the race is now smaller.
9223                    if (!success) {
9224                        // Uh oh...  it looks like the provider's process
9225                        // has been killed on us.  We need to wait for a new
9226                        // process to be started, and make sure its death
9227                        // doesn't kill our process.
9228                        Slog.i(TAG,
9229                                "Existing provider " + cpr.name.flattenToShortString()
9230                                + " is crashing; detaching " + r);
9231                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9232                        checkTime(startTime, "getContentProviderImpl: before appDied");
9233                        appDiedLocked(cpr.proc);
9234                        checkTime(startTime, "getContentProviderImpl: after appDied");
9235                        if (!lastRef) {
9236                            // This wasn't the last ref our process had on
9237                            // the provider...  we have now been killed, bail.
9238                            return null;
9239                        }
9240                        providerRunning = false;
9241                        conn = null;
9242                    }
9243                }
9244
9245                Binder.restoreCallingIdentity(origId);
9246            }
9247
9248            boolean singleton;
9249            if (!providerRunning) {
9250                try {
9251                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9252                    cpi = AppGlobals.getPackageManager().
9253                        resolveContentProvider(name,
9254                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9255                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9256                } catch (RemoteException ex) {
9257                }
9258                if (cpi == null) {
9259                    return null;
9260                }
9261                // If the provider is a singleton AND
9262                // (it's a call within the same user || the provider is a
9263                // privileged app)
9264                // Then allow connecting to the singleton provider
9265                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9266                        cpi.name, cpi.flags)
9267                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9268                if (singleton) {
9269                    userId = UserHandle.USER_OWNER;
9270                }
9271                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9272                checkTime(startTime, "getContentProviderImpl: got app info for user");
9273
9274                String msg;
9275                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9276                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9277                        != null) {
9278                    throw new SecurityException(msg);
9279                }
9280                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9281
9282                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9283                        && !cpi.processName.equals("system")) {
9284                    // If this content provider does not run in the system
9285                    // process, and the system is not yet ready to run other
9286                    // processes, then fail fast instead of hanging.
9287                    throw new IllegalArgumentException(
9288                            "Attempt to launch content provider before system ready");
9289                }
9290
9291                // Make sure that the user who owns this provider is running.  If not,
9292                // we don't want to allow it to run.
9293                if (!isUserRunningLocked(userId, false)) {
9294                    Slog.w(TAG, "Unable to launch app "
9295                            + cpi.applicationInfo.packageName + "/"
9296                            + cpi.applicationInfo.uid + " for provider "
9297                            + name + ": user " + userId + " is stopped");
9298                    return null;
9299                }
9300
9301                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9302                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9303                cpr = mProviderMap.getProviderByClass(comp, userId);
9304                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9305                final boolean firstClass = cpr == null;
9306                if (firstClass) {
9307                    final long ident = Binder.clearCallingIdentity();
9308                    try {
9309                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9310                        ApplicationInfo ai =
9311                            AppGlobals.getPackageManager().
9312                                getApplicationInfo(
9313                                        cpi.applicationInfo.packageName,
9314                                        STOCK_PM_FLAGS, userId);
9315                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9316                        if (ai == null) {
9317                            Slog.w(TAG, "No package info for content provider "
9318                                    + cpi.name);
9319                            return null;
9320                        }
9321                        ai = getAppInfoForUser(ai, userId);
9322                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9323                    } catch (RemoteException ex) {
9324                        // pm is in same process, this will never happen.
9325                    } finally {
9326                        Binder.restoreCallingIdentity(ident);
9327                    }
9328                }
9329
9330                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9331
9332                if (r != null && cpr.canRunHere(r)) {
9333                    // If this is a multiprocess provider, then just return its
9334                    // info and allow the caller to instantiate it.  Only do
9335                    // this if the provider is the same user as the caller's
9336                    // process, or can run as root (so can be in any process).
9337                    return cpr.newHolder(null);
9338                }
9339
9340                if (DEBUG_PROVIDER) {
9341                    RuntimeException e = new RuntimeException("here");
9342                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9343                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9344                }
9345
9346                // This is single process, and our app is now connecting to it.
9347                // See if we are already in the process of launching this
9348                // provider.
9349                final int N = mLaunchingProviders.size();
9350                int i;
9351                for (i=0; i<N; i++) {
9352                    if (mLaunchingProviders.get(i) == cpr) {
9353                        break;
9354                    }
9355                }
9356
9357                // If the provider is not already being launched, then get it
9358                // started.
9359                if (i >= N) {
9360                    final long origId = Binder.clearCallingIdentity();
9361
9362                    try {
9363                        // Content provider is now in use, its package can't be stopped.
9364                        try {
9365                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9366                            AppGlobals.getPackageManager().setPackageStoppedState(
9367                                    cpr.appInfo.packageName, false, userId);
9368                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9369                        } catch (RemoteException e) {
9370                        } catch (IllegalArgumentException e) {
9371                            Slog.w(TAG, "Failed trying to unstop package "
9372                                    + cpr.appInfo.packageName + ": " + e);
9373                        }
9374
9375                        // Use existing process if already started
9376                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9377                        ProcessRecord proc = getProcessRecordLocked(
9378                                cpi.processName, cpr.appInfo.uid, false);
9379                        if (proc != null && proc.thread != null) {
9380                            if (DEBUG_PROVIDER) {
9381                                Slog.d(TAG, "Installing in existing process " + proc);
9382                            }
9383                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9384                            proc.pubProviders.put(cpi.name, cpr);
9385                            try {
9386                                proc.thread.scheduleInstallProvider(cpi);
9387                            } catch (RemoteException e) {
9388                            }
9389                        } else {
9390                            checkTime(startTime, "getContentProviderImpl: before start process");
9391                            proc = startProcessLocked(cpi.processName,
9392                                    cpr.appInfo, false, 0, "content provider",
9393                                    new ComponentName(cpi.applicationInfo.packageName,
9394                                            cpi.name), false, false, false);
9395                            checkTime(startTime, "getContentProviderImpl: after start process");
9396                            if (proc == null) {
9397                                Slog.w(TAG, "Unable to launch app "
9398                                        + cpi.applicationInfo.packageName + "/"
9399                                        + cpi.applicationInfo.uid + " for provider "
9400                                        + name + ": process is bad");
9401                                return null;
9402                            }
9403                        }
9404                        cpr.launchingApp = proc;
9405                        mLaunchingProviders.add(cpr);
9406                    } finally {
9407                        Binder.restoreCallingIdentity(origId);
9408                    }
9409                }
9410
9411                checkTime(startTime, "getContentProviderImpl: updating data structures");
9412
9413                // Make sure the provider is published (the same provider class
9414                // may be published under multiple names).
9415                if (firstClass) {
9416                    mProviderMap.putProviderByClass(comp, cpr);
9417                }
9418
9419                mProviderMap.putProviderByName(name, cpr);
9420                conn = incProviderCountLocked(r, cpr, token, stable);
9421                if (conn != null) {
9422                    conn.waiting = true;
9423                }
9424            }
9425            checkTime(startTime, "getContentProviderImpl: done!");
9426        }
9427
9428        // Wait for the provider to be published...
9429        synchronized (cpr) {
9430            while (cpr.provider == null) {
9431                if (cpr.launchingApp == null) {
9432                    Slog.w(TAG, "Unable to launch app "
9433                            + cpi.applicationInfo.packageName + "/"
9434                            + cpi.applicationInfo.uid + " for provider "
9435                            + name + ": launching app became null");
9436                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9437                            UserHandle.getUserId(cpi.applicationInfo.uid),
9438                            cpi.applicationInfo.packageName,
9439                            cpi.applicationInfo.uid, name);
9440                    return null;
9441                }
9442                try {
9443                    if (DEBUG_MU) {
9444                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9445                                + cpr.launchingApp);
9446                    }
9447                    if (conn != null) {
9448                        conn.waiting = true;
9449                    }
9450                    cpr.wait();
9451                } catch (InterruptedException ex) {
9452                } finally {
9453                    if (conn != null) {
9454                        conn.waiting = false;
9455                    }
9456                }
9457            }
9458        }
9459        return cpr != null ? cpr.newHolder(conn) : null;
9460    }
9461
9462    @Override
9463    public final ContentProviderHolder getContentProvider(
9464            IApplicationThread caller, String name, int userId, boolean stable) {
9465        enforceNotIsolatedCaller("getContentProvider");
9466        if (caller == null) {
9467            String msg = "null IApplicationThread when getting content provider "
9468                    + name;
9469            Slog.w(TAG, msg);
9470            throw new SecurityException(msg);
9471        }
9472        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9473        // with cross-user grant.
9474        return getContentProviderImpl(caller, name, null, stable, userId);
9475    }
9476
9477    public ContentProviderHolder getContentProviderExternal(
9478            String name, int userId, IBinder token) {
9479        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9480            "Do not have permission in call getContentProviderExternal()");
9481        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9482                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9483        return getContentProviderExternalUnchecked(name, token, userId);
9484    }
9485
9486    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9487            IBinder token, int userId) {
9488        return getContentProviderImpl(null, name, token, true, userId);
9489    }
9490
9491    /**
9492     * Drop a content provider from a ProcessRecord's bookkeeping
9493     */
9494    public void removeContentProvider(IBinder connection, boolean stable) {
9495        enforceNotIsolatedCaller("removeContentProvider");
9496        long ident = Binder.clearCallingIdentity();
9497        try {
9498            synchronized (this) {
9499                ContentProviderConnection conn;
9500                try {
9501                    conn = (ContentProviderConnection)connection;
9502                } catch (ClassCastException e) {
9503                    String msg ="removeContentProvider: " + connection
9504                            + " not a ContentProviderConnection";
9505                    Slog.w(TAG, msg);
9506                    throw new IllegalArgumentException(msg);
9507                }
9508                if (conn == null) {
9509                    throw new NullPointerException("connection is null");
9510                }
9511                if (decProviderCountLocked(conn, null, null, stable)) {
9512                    updateOomAdjLocked();
9513                }
9514            }
9515        } finally {
9516            Binder.restoreCallingIdentity(ident);
9517        }
9518    }
9519
9520    public void removeContentProviderExternal(String name, IBinder token) {
9521        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9522            "Do not have permission in call removeContentProviderExternal()");
9523        int userId = UserHandle.getCallingUserId();
9524        long ident = Binder.clearCallingIdentity();
9525        try {
9526            removeContentProviderExternalUnchecked(name, token, userId);
9527        } finally {
9528            Binder.restoreCallingIdentity(ident);
9529        }
9530    }
9531
9532    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9533        synchronized (this) {
9534            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9535            if(cpr == null) {
9536                //remove from mProvidersByClass
9537                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9538                return;
9539            }
9540
9541            //update content provider record entry info
9542            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9543            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9544            if (localCpr.hasExternalProcessHandles()) {
9545                if (localCpr.removeExternalProcessHandleLocked(token)) {
9546                    updateOomAdjLocked();
9547                } else {
9548                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9549                            + " with no external reference for token: "
9550                            + token + ".");
9551                }
9552            } else {
9553                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9554                        + " with no external references.");
9555            }
9556        }
9557    }
9558
9559    public final void publishContentProviders(IApplicationThread caller,
9560            List<ContentProviderHolder> providers) {
9561        if (providers == null) {
9562            return;
9563        }
9564
9565        enforceNotIsolatedCaller("publishContentProviders");
9566        synchronized (this) {
9567            final ProcessRecord r = getRecordForAppLocked(caller);
9568            if (DEBUG_MU)
9569                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9570            if (r == null) {
9571                throw new SecurityException(
9572                        "Unable to find app for caller " + caller
9573                      + " (pid=" + Binder.getCallingPid()
9574                      + ") when publishing content providers");
9575            }
9576
9577            final long origId = Binder.clearCallingIdentity();
9578
9579            final int N = providers.size();
9580            for (int i=0; i<N; i++) {
9581                ContentProviderHolder src = providers.get(i);
9582                if (src == null || src.info == null || src.provider == null) {
9583                    continue;
9584                }
9585                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9586                if (DEBUG_MU)
9587                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9588                if (dst != null) {
9589                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9590                    mProviderMap.putProviderByClass(comp, dst);
9591                    String names[] = dst.info.authority.split(";");
9592                    for (int j = 0; j < names.length; j++) {
9593                        mProviderMap.putProviderByName(names[j], dst);
9594                    }
9595
9596                    int NL = mLaunchingProviders.size();
9597                    int j;
9598                    for (j=0; j<NL; j++) {
9599                        if (mLaunchingProviders.get(j) == dst) {
9600                            mLaunchingProviders.remove(j);
9601                            j--;
9602                            NL--;
9603                        }
9604                    }
9605                    synchronized (dst) {
9606                        dst.provider = src.provider;
9607                        dst.proc = r;
9608                        dst.notifyAll();
9609                    }
9610                    updateOomAdjLocked(r);
9611                }
9612            }
9613
9614            Binder.restoreCallingIdentity(origId);
9615        }
9616    }
9617
9618    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9619        ContentProviderConnection conn;
9620        try {
9621            conn = (ContentProviderConnection)connection;
9622        } catch (ClassCastException e) {
9623            String msg ="refContentProvider: " + connection
9624                    + " not a ContentProviderConnection";
9625            Slog.w(TAG, msg);
9626            throw new IllegalArgumentException(msg);
9627        }
9628        if (conn == null) {
9629            throw new NullPointerException("connection is null");
9630        }
9631
9632        synchronized (this) {
9633            if (stable > 0) {
9634                conn.numStableIncs += stable;
9635            }
9636            stable = conn.stableCount + stable;
9637            if (stable < 0) {
9638                throw new IllegalStateException("stableCount < 0: " + stable);
9639            }
9640
9641            if (unstable > 0) {
9642                conn.numUnstableIncs += unstable;
9643            }
9644            unstable = conn.unstableCount + unstable;
9645            if (unstable < 0) {
9646                throw new IllegalStateException("unstableCount < 0: " + unstable);
9647            }
9648
9649            if ((stable+unstable) <= 0) {
9650                throw new IllegalStateException("ref counts can't go to zero here: stable="
9651                        + stable + " unstable=" + unstable);
9652            }
9653            conn.stableCount = stable;
9654            conn.unstableCount = unstable;
9655            return !conn.dead;
9656        }
9657    }
9658
9659    public void unstableProviderDied(IBinder connection) {
9660        ContentProviderConnection conn;
9661        try {
9662            conn = (ContentProviderConnection)connection;
9663        } catch (ClassCastException e) {
9664            String msg ="refContentProvider: " + connection
9665                    + " not a ContentProviderConnection";
9666            Slog.w(TAG, msg);
9667            throw new IllegalArgumentException(msg);
9668        }
9669        if (conn == null) {
9670            throw new NullPointerException("connection is null");
9671        }
9672
9673        // Safely retrieve the content provider associated with the connection.
9674        IContentProvider provider;
9675        synchronized (this) {
9676            provider = conn.provider.provider;
9677        }
9678
9679        if (provider == null) {
9680            // Um, yeah, we're way ahead of you.
9681            return;
9682        }
9683
9684        // Make sure the caller is being honest with us.
9685        if (provider.asBinder().pingBinder()) {
9686            // Er, no, still looks good to us.
9687            synchronized (this) {
9688                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9689                        + " says " + conn + " died, but we don't agree");
9690                return;
9691            }
9692        }
9693
9694        // Well look at that!  It's dead!
9695        synchronized (this) {
9696            if (conn.provider.provider != provider) {
9697                // But something changed...  good enough.
9698                return;
9699            }
9700
9701            ProcessRecord proc = conn.provider.proc;
9702            if (proc == null || proc.thread == null) {
9703                // Seems like the process is already cleaned up.
9704                return;
9705            }
9706
9707            // As far as we're concerned, this is just like receiving a
9708            // death notification...  just a bit prematurely.
9709            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9710                    + ") early provider death");
9711            final long ident = Binder.clearCallingIdentity();
9712            try {
9713                appDiedLocked(proc);
9714            } finally {
9715                Binder.restoreCallingIdentity(ident);
9716            }
9717        }
9718    }
9719
9720    @Override
9721    public void appNotRespondingViaProvider(IBinder connection) {
9722        enforceCallingPermission(
9723                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9724
9725        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9726        if (conn == null) {
9727            Slog.w(TAG, "ContentProviderConnection is null");
9728            return;
9729        }
9730
9731        final ProcessRecord host = conn.provider.proc;
9732        if (host == null) {
9733            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9734            return;
9735        }
9736
9737        final long token = Binder.clearCallingIdentity();
9738        try {
9739            appNotResponding(host, null, null, false, "ContentProvider not responding");
9740        } finally {
9741            Binder.restoreCallingIdentity(token);
9742        }
9743    }
9744
9745    public final void installSystemProviders() {
9746        List<ProviderInfo> providers;
9747        synchronized (this) {
9748            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9749            providers = generateApplicationProvidersLocked(app);
9750            if (providers != null) {
9751                for (int i=providers.size()-1; i>=0; i--) {
9752                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9753                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9754                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9755                                + ": not system .apk");
9756                        providers.remove(i);
9757                    }
9758                }
9759            }
9760        }
9761        if (providers != null) {
9762            mSystemThread.installSystemProviders(providers);
9763        }
9764
9765        mCoreSettingsObserver = new CoreSettingsObserver(this);
9766
9767        //mUsageStatsService.monitorPackages();
9768    }
9769
9770    /**
9771     * Allows apps to retrieve the MIME type of a URI.
9772     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9773     * users, then it does not need permission to access the ContentProvider.
9774     * Either, it needs cross-user uri grants.
9775     *
9776     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9777     *
9778     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9779     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9780     */
9781    public String getProviderMimeType(Uri uri, int userId) {
9782        enforceNotIsolatedCaller("getProviderMimeType");
9783        final String name = uri.getAuthority();
9784        int callingUid = Binder.getCallingUid();
9785        int callingPid = Binder.getCallingPid();
9786        long ident = 0;
9787        boolean clearedIdentity = false;
9788        userId = unsafeConvertIncomingUser(userId);
9789        if (canClearIdentity(callingPid, callingUid, userId)) {
9790            clearedIdentity = true;
9791            ident = Binder.clearCallingIdentity();
9792        }
9793        ContentProviderHolder holder = null;
9794        try {
9795            holder = getContentProviderExternalUnchecked(name, null, userId);
9796            if (holder != null) {
9797                return holder.provider.getType(uri);
9798            }
9799        } catch (RemoteException e) {
9800            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9801            return null;
9802        } finally {
9803            // We need to clear the identity to call removeContentProviderExternalUnchecked
9804            if (!clearedIdentity) {
9805                ident = Binder.clearCallingIdentity();
9806            }
9807            try {
9808                if (holder != null) {
9809                    removeContentProviderExternalUnchecked(name, null, userId);
9810                }
9811            } finally {
9812                Binder.restoreCallingIdentity(ident);
9813            }
9814        }
9815
9816        return null;
9817    }
9818
9819    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9820        if (UserHandle.getUserId(callingUid) == userId) {
9821            return true;
9822        }
9823        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9824                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9825                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9826                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9827                return true;
9828        }
9829        return false;
9830    }
9831
9832    // =========================================================
9833    // GLOBAL MANAGEMENT
9834    // =========================================================
9835
9836    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9837            boolean isolated, int isolatedUid) {
9838        String proc = customProcess != null ? customProcess : info.processName;
9839        BatteryStatsImpl.Uid.Proc ps = null;
9840        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9841        int uid = info.uid;
9842        if (isolated) {
9843            if (isolatedUid == 0) {
9844                int userId = UserHandle.getUserId(uid);
9845                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9846                while (true) {
9847                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9848                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9849                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9850                    }
9851                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9852                    mNextIsolatedProcessUid++;
9853                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9854                        // No process for this uid, use it.
9855                        break;
9856                    }
9857                    stepsLeft--;
9858                    if (stepsLeft <= 0) {
9859                        return null;
9860                    }
9861                }
9862            } else {
9863                // Special case for startIsolatedProcess (internal only), where
9864                // the uid of the isolated process is specified by the caller.
9865                uid = isolatedUid;
9866            }
9867        }
9868        return new ProcessRecord(stats, info, proc, uid);
9869    }
9870
9871    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9872            String abiOverride) {
9873        ProcessRecord app;
9874        if (!isolated) {
9875            app = getProcessRecordLocked(info.processName, info.uid, true);
9876        } else {
9877            app = null;
9878        }
9879
9880        if (app == null) {
9881            app = newProcessRecordLocked(info, null, isolated, 0);
9882            mProcessNames.put(info.processName, app.uid, app);
9883            if (isolated) {
9884                mIsolatedProcesses.put(app.uid, app);
9885            }
9886            updateLruProcessLocked(app, false, null);
9887            updateOomAdjLocked();
9888        }
9889
9890        // This package really, really can not be stopped.
9891        try {
9892            AppGlobals.getPackageManager().setPackageStoppedState(
9893                    info.packageName, false, UserHandle.getUserId(app.uid));
9894        } catch (RemoteException e) {
9895        } catch (IllegalArgumentException e) {
9896            Slog.w(TAG, "Failed trying to unstop package "
9897                    + info.packageName + ": " + e);
9898        }
9899
9900        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9901                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9902            app.persistent = true;
9903            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9904        }
9905        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9906            mPersistentStartingProcesses.add(app);
9907            startProcessLocked(app, "added application", app.processName, abiOverride,
9908                    null /* entryPoint */, null /* entryPointArgs */);
9909        }
9910
9911        return app;
9912    }
9913
9914    public void unhandledBack() {
9915        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9916                "unhandledBack()");
9917
9918        synchronized(this) {
9919            final long origId = Binder.clearCallingIdentity();
9920            try {
9921                getFocusedStack().unhandledBackLocked();
9922            } finally {
9923                Binder.restoreCallingIdentity(origId);
9924            }
9925        }
9926    }
9927
9928    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9929        enforceNotIsolatedCaller("openContentUri");
9930        final int userId = UserHandle.getCallingUserId();
9931        String name = uri.getAuthority();
9932        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9933        ParcelFileDescriptor pfd = null;
9934        if (cph != null) {
9935            // We record the binder invoker's uid in thread-local storage before
9936            // going to the content provider to open the file.  Later, in the code
9937            // that handles all permissions checks, we look for this uid and use
9938            // that rather than the Activity Manager's own uid.  The effect is that
9939            // we do the check against the caller's permissions even though it looks
9940            // to the content provider like the Activity Manager itself is making
9941            // the request.
9942            Binder token = new Binder();
9943            sCallerIdentity.set(new Identity(
9944                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9945            try {
9946                pfd = cph.provider.openFile(null, uri, "r", null, token);
9947            } catch (FileNotFoundException e) {
9948                // do nothing; pfd will be returned null
9949            } finally {
9950                // Ensure that whatever happens, we clean up the identity state
9951                sCallerIdentity.remove();
9952            }
9953
9954            // We've got the fd now, so we're done with the provider.
9955            removeContentProviderExternalUnchecked(name, null, userId);
9956        } else {
9957            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9958        }
9959        return pfd;
9960    }
9961
9962    // Actually is sleeping or shutting down or whatever else in the future
9963    // is an inactive state.
9964    public boolean isSleepingOrShuttingDown() {
9965        return isSleeping() || mShuttingDown;
9966    }
9967
9968    public boolean isSleeping() {
9969        return mSleeping;
9970    }
9971
9972    void onWakefulnessChanged(int wakefulness) {
9973        synchronized(this) {
9974            mWakefulness = wakefulness;
9975            updateSleepIfNeededLocked();
9976        }
9977    }
9978
9979    void finishRunningVoiceLocked() {
9980        if (mRunningVoice) {
9981            mRunningVoice = false;
9982            updateSleepIfNeededLocked();
9983        }
9984    }
9985
9986    void updateSleepIfNeededLocked() {
9987        if (mSleeping && !shouldSleepLocked()) {
9988            mSleeping = false;
9989            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9990        } else if (!mSleeping && shouldSleepLocked()) {
9991            mSleeping = true;
9992            mStackSupervisor.goingToSleepLocked();
9993
9994            // Initialize the wake times of all processes.
9995            checkExcessivePowerUsageLocked(false);
9996            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9997            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9998            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9999        }
10000    }
10001
10002    private boolean shouldSleepLocked() {
10003        // Resume applications while running a voice interactor.
10004        if (mRunningVoice) {
10005            return false;
10006        }
10007
10008        switch (mWakefulness) {
10009            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10010            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10011                // If we're interactive but applications are already paused then defer
10012                // resuming them until the lock screen is hidden.
10013                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10014            case PowerManagerInternal.WAKEFULNESS_DOZING:
10015                // If we're dozing then pause applications whenever the lock screen is shown.
10016                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10017            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10018            default:
10019                // If we're asleep then pause applications unconditionally.
10020                return true;
10021        }
10022    }
10023
10024    /** Pokes the task persister. */
10025    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10026        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10027            // Never persist the home stack.
10028            return;
10029        }
10030        mTaskPersister.wakeup(task, flush);
10031    }
10032
10033    /** Notifies all listeners when the task stack has changed. */
10034    void notifyTaskStackChangedLocked() {
10035        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10036        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10037        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10038    }
10039
10040    @Override
10041    public boolean shutdown(int timeout) {
10042        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10043                != PackageManager.PERMISSION_GRANTED) {
10044            throw new SecurityException("Requires permission "
10045                    + android.Manifest.permission.SHUTDOWN);
10046        }
10047
10048        boolean timedout = false;
10049
10050        synchronized(this) {
10051            mShuttingDown = true;
10052            updateEventDispatchingLocked();
10053            timedout = mStackSupervisor.shutdownLocked(timeout);
10054        }
10055
10056        mAppOpsService.shutdown();
10057        if (mUsageStatsService != null) {
10058            mUsageStatsService.prepareShutdown();
10059        }
10060        mBatteryStatsService.shutdown();
10061        synchronized (this) {
10062            mProcessStats.shutdownLocked();
10063            notifyTaskPersisterLocked(null, true);
10064        }
10065
10066        return timedout;
10067    }
10068
10069    public final void activitySlept(IBinder token) {
10070        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10071
10072        final long origId = Binder.clearCallingIdentity();
10073
10074        synchronized (this) {
10075            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10076            if (r != null) {
10077                mStackSupervisor.activitySleptLocked(r);
10078            }
10079        }
10080
10081        Binder.restoreCallingIdentity(origId);
10082    }
10083
10084    private String lockScreenShownToString() {
10085        switch (mLockScreenShown) {
10086            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10087            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10088            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10089            default: return "Unknown=" + mLockScreenShown;
10090        }
10091    }
10092
10093    void logLockScreen(String msg) {
10094        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10095                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10096                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10097                + " mSleeping=" + mSleeping);
10098    }
10099
10100    void startRunningVoiceLocked() {
10101        if (!mRunningVoice) {
10102            mRunningVoice = true;
10103            updateSleepIfNeededLocked();
10104        }
10105    }
10106
10107    private void updateEventDispatchingLocked() {
10108        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10109    }
10110
10111    public void setLockScreenShown(boolean shown) {
10112        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10113                != PackageManager.PERMISSION_GRANTED) {
10114            throw new SecurityException("Requires permission "
10115                    + android.Manifest.permission.DEVICE_POWER);
10116        }
10117
10118        synchronized(this) {
10119            long ident = Binder.clearCallingIdentity();
10120            try {
10121                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10122                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10123                updateSleepIfNeededLocked();
10124            } finally {
10125                Binder.restoreCallingIdentity(ident);
10126            }
10127        }
10128    }
10129
10130    @Override
10131    public void stopAppSwitches() {
10132        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10133                != PackageManager.PERMISSION_GRANTED) {
10134            throw new SecurityException("Requires permission "
10135                    + android.Manifest.permission.STOP_APP_SWITCHES);
10136        }
10137
10138        synchronized(this) {
10139            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10140                    + APP_SWITCH_DELAY_TIME;
10141            mDidAppSwitch = false;
10142            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10143            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10144            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10145        }
10146    }
10147
10148    public void resumeAppSwitches() {
10149        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10150                != PackageManager.PERMISSION_GRANTED) {
10151            throw new SecurityException("Requires permission "
10152                    + android.Manifest.permission.STOP_APP_SWITCHES);
10153        }
10154
10155        synchronized(this) {
10156            // Note that we don't execute any pending app switches... we will
10157            // let those wait until either the timeout, or the next start
10158            // activity request.
10159            mAppSwitchesAllowedTime = 0;
10160        }
10161    }
10162
10163    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10164            int callingPid, int callingUid, String name) {
10165        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10166            return true;
10167        }
10168
10169        int perm = checkComponentPermission(
10170                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10171                sourceUid, -1, true);
10172        if (perm == PackageManager.PERMISSION_GRANTED) {
10173            return true;
10174        }
10175
10176        // If the actual IPC caller is different from the logical source, then
10177        // also see if they are allowed to control app switches.
10178        if (callingUid != -1 && callingUid != sourceUid) {
10179            perm = checkComponentPermission(
10180                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10181                    callingUid, -1, true);
10182            if (perm == PackageManager.PERMISSION_GRANTED) {
10183                return true;
10184            }
10185        }
10186
10187        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10188        return false;
10189    }
10190
10191    public void setDebugApp(String packageName, boolean waitForDebugger,
10192            boolean persistent) {
10193        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10194                "setDebugApp()");
10195
10196        long ident = Binder.clearCallingIdentity();
10197        try {
10198            // Note that this is not really thread safe if there are multiple
10199            // callers into it at the same time, but that's not a situation we
10200            // care about.
10201            if (persistent) {
10202                final ContentResolver resolver = mContext.getContentResolver();
10203                Settings.Global.putString(
10204                    resolver, Settings.Global.DEBUG_APP,
10205                    packageName);
10206                Settings.Global.putInt(
10207                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10208                    waitForDebugger ? 1 : 0);
10209            }
10210
10211            synchronized (this) {
10212                if (!persistent) {
10213                    mOrigDebugApp = mDebugApp;
10214                    mOrigWaitForDebugger = mWaitForDebugger;
10215                }
10216                mDebugApp = packageName;
10217                mWaitForDebugger = waitForDebugger;
10218                mDebugTransient = !persistent;
10219                if (packageName != null) {
10220                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10221                            false, UserHandle.USER_ALL, "set debug app");
10222                }
10223            }
10224        } finally {
10225            Binder.restoreCallingIdentity(ident);
10226        }
10227    }
10228
10229    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10230        synchronized (this) {
10231            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10232            if (!isDebuggable) {
10233                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10234                    throw new SecurityException("Process not debuggable: " + app.packageName);
10235                }
10236            }
10237
10238            mOpenGlTraceApp = processName;
10239        }
10240    }
10241
10242    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10243        synchronized (this) {
10244            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10245            if (!isDebuggable) {
10246                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10247                    throw new SecurityException("Process not debuggable: " + app.packageName);
10248                }
10249            }
10250            mProfileApp = processName;
10251            mProfileFile = profilerInfo.profileFile;
10252            if (mProfileFd != null) {
10253                try {
10254                    mProfileFd.close();
10255                } catch (IOException e) {
10256                }
10257                mProfileFd = null;
10258            }
10259            mProfileFd = profilerInfo.profileFd;
10260            mSamplingInterval = profilerInfo.samplingInterval;
10261            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10262            mProfileType = 0;
10263        }
10264    }
10265
10266    @Override
10267    public void setAlwaysFinish(boolean enabled) {
10268        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10269                "setAlwaysFinish()");
10270
10271        Settings.Global.putInt(
10272                mContext.getContentResolver(),
10273                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10274
10275        synchronized (this) {
10276            mAlwaysFinishActivities = enabled;
10277        }
10278    }
10279
10280    @Override
10281    public void setActivityController(IActivityController controller) {
10282        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10283                "setActivityController()");
10284        synchronized (this) {
10285            mController = controller;
10286            Watchdog.getInstance().setActivityController(controller);
10287        }
10288    }
10289
10290    @Override
10291    public void setUserIsMonkey(boolean userIsMonkey) {
10292        synchronized (this) {
10293            synchronized (mPidsSelfLocked) {
10294                final int callingPid = Binder.getCallingPid();
10295                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10296                if (precessRecord == null) {
10297                    throw new SecurityException("Unknown process: " + callingPid);
10298                }
10299                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10300                    throw new SecurityException("Only an instrumentation process "
10301                            + "with a UiAutomation can call setUserIsMonkey");
10302                }
10303            }
10304            mUserIsMonkey = userIsMonkey;
10305        }
10306    }
10307
10308    @Override
10309    public boolean isUserAMonkey() {
10310        synchronized (this) {
10311            // If there is a controller also implies the user is a monkey.
10312            return (mUserIsMonkey || mController != null);
10313        }
10314    }
10315
10316    public void requestBugReport() {
10317        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10318        SystemProperties.set("ctl.start", "bugreport");
10319    }
10320
10321    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10322        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10323    }
10324
10325    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10326        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10327            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10328        }
10329        return KEY_DISPATCHING_TIMEOUT;
10330    }
10331
10332    @Override
10333    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10334        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10335                != PackageManager.PERMISSION_GRANTED) {
10336            throw new SecurityException("Requires permission "
10337                    + android.Manifest.permission.FILTER_EVENTS);
10338        }
10339        ProcessRecord proc;
10340        long timeout;
10341        synchronized (this) {
10342            synchronized (mPidsSelfLocked) {
10343                proc = mPidsSelfLocked.get(pid);
10344            }
10345            timeout = getInputDispatchingTimeoutLocked(proc);
10346        }
10347
10348        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10349            return -1;
10350        }
10351
10352        return timeout;
10353    }
10354
10355    /**
10356     * Handle input dispatching timeouts.
10357     * Returns whether input dispatching should be aborted or not.
10358     */
10359    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10360            final ActivityRecord activity, final ActivityRecord parent,
10361            final boolean aboveSystem, String reason) {
10362        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10363                != PackageManager.PERMISSION_GRANTED) {
10364            throw new SecurityException("Requires permission "
10365                    + android.Manifest.permission.FILTER_EVENTS);
10366        }
10367
10368        final String annotation;
10369        if (reason == null) {
10370            annotation = "Input dispatching timed out";
10371        } else {
10372            annotation = "Input dispatching timed out (" + reason + ")";
10373        }
10374
10375        if (proc != null) {
10376            synchronized (this) {
10377                if (proc.debugging) {
10378                    return false;
10379                }
10380
10381                if (mDidDexOpt) {
10382                    // Give more time since we were dexopting.
10383                    mDidDexOpt = false;
10384                    return false;
10385                }
10386
10387                if (proc.instrumentationClass != null) {
10388                    Bundle info = new Bundle();
10389                    info.putString("shortMsg", "keyDispatchingTimedOut");
10390                    info.putString("longMsg", annotation);
10391                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10392                    return true;
10393                }
10394            }
10395            mHandler.post(new Runnable() {
10396                @Override
10397                public void run() {
10398                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10399                }
10400            });
10401        }
10402
10403        return true;
10404    }
10405
10406    public Bundle getAssistContextExtras(int requestType) {
10407        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10408                UserHandle.getCallingUserId());
10409        if (pae == null) {
10410            return null;
10411        }
10412        synchronized (pae) {
10413            while (!pae.haveResult) {
10414                try {
10415                    pae.wait();
10416                } catch (InterruptedException e) {
10417                }
10418            }
10419            if (pae.result != null) {
10420                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10421            }
10422        }
10423        synchronized (this) {
10424            mPendingAssistExtras.remove(pae);
10425            mHandler.removeCallbacks(pae);
10426        }
10427        return pae.extras;
10428    }
10429
10430    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10431            int userHandle) {
10432        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10433                "getAssistContextExtras()");
10434        PendingAssistExtras pae;
10435        Bundle extras = new Bundle();
10436        synchronized (this) {
10437            ActivityRecord activity = getFocusedStack().mResumedActivity;
10438            if (activity == null) {
10439                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10440                return null;
10441            }
10442            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10443            if (activity.app == null || activity.app.thread == null) {
10444                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10445                return null;
10446            }
10447            if (activity.app.pid == Binder.getCallingPid()) {
10448                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10449                return null;
10450            }
10451            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10452            try {
10453                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10454                        requestType);
10455                mPendingAssistExtras.add(pae);
10456                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10457            } catch (RemoteException e) {
10458                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10459                return null;
10460            }
10461            return pae;
10462        }
10463    }
10464
10465    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10466        PendingAssistExtras pae = (PendingAssistExtras)token;
10467        synchronized (pae) {
10468            pae.result = extras;
10469            pae.haveResult = true;
10470            pae.notifyAll();
10471            if (pae.intent == null) {
10472                // Caller is just waiting for the result.
10473                return;
10474            }
10475        }
10476
10477        // We are now ready to launch the assist activity.
10478        synchronized (this) {
10479            boolean exists = mPendingAssistExtras.remove(pae);
10480            mHandler.removeCallbacks(pae);
10481            if (!exists) {
10482                // Timed out.
10483                return;
10484            }
10485        }
10486        pae.intent.replaceExtras(extras);
10487        if (pae.hint != null) {
10488            pae.intent.putExtra(pae.hint, true);
10489        }
10490        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10491                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10492                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10493        closeSystemDialogs("assist");
10494        try {
10495            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10496        } catch (ActivityNotFoundException e) {
10497            Slog.w(TAG, "No activity to handle assist action.", e);
10498        }
10499    }
10500
10501    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10502        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10503    }
10504
10505    public void registerProcessObserver(IProcessObserver observer) {
10506        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10507                "registerProcessObserver()");
10508        synchronized (this) {
10509            mProcessObservers.register(observer);
10510        }
10511    }
10512
10513    @Override
10514    public void unregisterProcessObserver(IProcessObserver observer) {
10515        synchronized (this) {
10516            mProcessObservers.unregister(observer);
10517        }
10518    }
10519
10520    @Override
10521    public boolean convertFromTranslucent(IBinder token) {
10522        final long origId = Binder.clearCallingIdentity();
10523        try {
10524            synchronized (this) {
10525                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10526                if (r == null) {
10527                    return false;
10528                }
10529                final boolean translucentChanged = r.changeWindowTranslucency(true);
10530                if (translucentChanged) {
10531                    r.task.stack.releaseBackgroundResources();
10532                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10533                }
10534                mWindowManager.setAppFullscreen(token, true);
10535                return translucentChanged;
10536            }
10537        } finally {
10538            Binder.restoreCallingIdentity(origId);
10539        }
10540    }
10541
10542    @Override
10543    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10544        final long origId = Binder.clearCallingIdentity();
10545        try {
10546            synchronized (this) {
10547                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10548                if (r == null) {
10549                    return false;
10550                }
10551                int index = r.task.mActivities.lastIndexOf(r);
10552                if (index > 0) {
10553                    ActivityRecord under = r.task.mActivities.get(index - 1);
10554                    under.returningOptions = options;
10555                }
10556                final boolean translucentChanged = r.changeWindowTranslucency(false);
10557                if (translucentChanged) {
10558                    r.task.stack.convertToTranslucent(r);
10559                }
10560                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10561                mWindowManager.setAppFullscreen(token, false);
10562                return translucentChanged;
10563            }
10564        } finally {
10565            Binder.restoreCallingIdentity(origId);
10566        }
10567    }
10568
10569    @Override
10570    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10571        final long origId = Binder.clearCallingIdentity();
10572        try {
10573            synchronized (this) {
10574                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10575                if (r != null) {
10576                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10577                }
10578            }
10579            return false;
10580        } finally {
10581            Binder.restoreCallingIdentity(origId);
10582        }
10583    }
10584
10585    @Override
10586    public boolean isBackgroundVisibleBehind(IBinder token) {
10587        final long origId = Binder.clearCallingIdentity();
10588        try {
10589            synchronized (this) {
10590                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10591                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10592                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10593                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10594                return visible;
10595            }
10596        } finally {
10597            Binder.restoreCallingIdentity(origId);
10598        }
10599    }
10600
10601    @Override
10602    public ActivityOptions getActivityOptions(IBinder token) {
10603        final long origId = Binder.clearCallingIdentity();
10604        try {
10605            synchronized (this) {
10606                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10607                if (r != null) {
10608                    final ActivityOptions activityOptions = r.pendingOptions;
10609                    r.pendingOptions = null;
10610                    return activityOptions;
10611                }
10612                return null;
10613            }
10614        } finally {
10615            Binder.restoreCallingIdentity(origId);
10616        }
10617    }
10618
10619    @Override
10620    public void setImmersive(IBinder token, boolean immersive) {
10621        synchronized(this) {
10622            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10623            if (r == null) {
10624                throw new IllegalArgumentException();
10625            }
10626            r.immersive = immersive;
10627
10628            // update associated state if we're frontmost
10629            if (r == mFocusedActivity) {
10630                if (DEBUG_IMMERSIVE) {
10631                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10632                }
10633                applyUpdateLockStateLocked(r);
10634            }
10635        }
10636    }
10637
10638    @Override
10639    public boolean isImmersive(IBinder token) {
10640        synchronized (this) {
10641            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10642            if (r == null) {
10643                throw new IllegalArgumentException();
10644            }
10645            return r.immersive;
10646        }
10647    }
10648
10649    public boolean isTopActivityImmersive() {
10650        enforceNotIsolatedCaller("startActivity");
10651        synchronized (this) {
10652            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10653            return (r != null) ? r.immersive : false;
10654        }
10655    }
10656
10657    @Override
10658    public boolean isTopOfTask(IBinder token) {
10659        synchronized (this) {
10660            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10661            if (r == null) {
10662                throw new IllegalArgumentException();
10663            }
10664            return r.task.getTopActivity() == r;
10665        }
10666    }
10667
10668    public final void enterSafeMode() {
10669        synchronized(this) {
10670            // It only makes sense to do this before the system is ready
10671            // and started launching other packages.
10672            if (!mSystemReady) {
10673                try {
10674                    AppGlobals.getPackageManager().enterSafeMode();
10675                } catch (RemoteException e) {
10676                }
10677            }
10678
10679            mSafeMode = true;
10680        }
10681    }
10682
10683    public final void showSafeModeOverlay() {
10684        View v = LayoutInflater.from(mContext).inflate(
10685                com.android.internal.R.layout.safe_mode, null);
10686        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10687        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10688        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10689        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10690        lp.gravity = Gravity.BOTTOM | Gravity.START;
10691        lp.format = v.getBackground().getOpacity();
10692        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10693                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10694        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10695        ((WindowManager)mContext.getSystemService(
10696                Context.WINDOW_SERVICE)).addView(v, lp);
10697    }
10698
10699    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10700        if (!(sender instanceof PendingIntentRecord)) {
10701            return;
10702        }
10703        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10704        synchronized (stats) {
10705            if (mBatteryStatsService.isOnBattery()) {
10706                mBatteryStatsService.enforceCallingPermission();
10707                PendingIntentRecord rec = (PendingIntentRecord)sender;
10708                int MY_UID = Binder.getCallingUid();
10709                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10710                BatteryStatsImpl.Uid.Pkg pkg =
10711                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10712                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10713                pkg.incWakeupsLocked();
10714            }
10715        }
10716    }
10717
10718    public boolean killPids(int[] pids, String pReason, boolean secure) {
10719        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10720            throw new SecurityException("killPids only available to the system");
10721        }
10722        String reason = (pReason == null) ? "Unknown" : pReason;
10723        // XXX Note: don't acquire main activity lock here, because the window
10724        // manager calls in with its locks held.
10725
10726        boolean killed = false;
10727        synchronized (mPidsSelfLocked) {
10728            int[] types = new int[pids.length];
10729            int worstType = 0;
10730            for (int i=0; i<pids.length; i++) {
10731                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10732                if (proc != null) {
10733                    int type = proc.setAdj;
10734                    types[i] = type;
10735                    if (type > worstType) {
10736                        worstType = type;
10737                    }
10738                }
10739            }
10740
10741            // If the worst oom_adj is somewhere in the cached proc LRU range,
10742            // then constrain it so we will kill all cached procs.
10743            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10744                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10745                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10746            }
10747
10748            // If this is not a secure call, don't let it kill processes that
10749            // are important.
10750            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10751                worstType = ProcessList.SERVICE_ADJ;
10752            }
10753
10754            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10755            for (int i=0; i<pids.length; i++) {
10756                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10757                if (proc == null) {
10758                    continue;
10759                }
10760                int adj = proc.setAdj;
10761                if (adj >= worstType && !proc.killedByAm) {
10762                    proc.kill(reason, true);
10763                    killed = true;
10764                }
10765            }
10766        }
10767        return killed;
10768    }
10769
10770    @Override
10771    public void killUid(int uid, String reason) {
10772        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10773            throw new SecurityException("killUid only available to the system");
10774        }
10775        synchronized (this) {
10776            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10777                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10778                    reason != null ? reason : "kill uid");
10779        }
10780    }
10781
10782    @Override
10783    public boolean killProcessesBelowForeground(String reason) {
10784        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10785            throw new SecurityException("killProcessesBelowForeground() only available to system");
10786        }
10787
10788        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10789    }
10790
10791    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10792        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10793            throw new SecurityException("killProcessesBelowAdj() only available to system");
10794        }
10795
10796        boolean killed = false;
10797        synchronized (mPidsSelfLocked) {
10798            final int size = mPidsSelfLocked.size();
10799            for (int i = 0; i < size; i++) {
10800                final int pid = mPidsSelfLocked.keyAt(i);
10801                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10802                if (proc == null) continue;
10803
10804                final int adj = proc.setAdj;
10805                if (adj > belowAdj && !proc.killedByAm) {
10806                    proc.kill(reason, true);
10807                    killed = true;
10808                }
10809            }
10810        }
10811        return killed;
10812    }
10813
10814    @Override
10815    public void hang(final IBinder who, boolean allowRestart) {
10816        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10817                != PackageManager.PERMISSION_GRANTED) {
10818            throw new SecurityException("Requires permission "
10819                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10820        }
10821
10822        final IBinder.DeathRecipient death = new DeathRecipient() {
10823            @Override
10824            public void binderDied() {
10825                synchronized (this) {
10826                    notifyAll();
10827                }
10828            }
10829        };
10830
10831        try {
10832            who.linkToDeath(death, 0);
10833        } catch (RemoteException e) {
10834            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10835            return;
10836        }
10837
10838        synchronized (this) {
10839            Watchdog.getInstance().setAllowRestart(allowRestart);
10840            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10841            synchronized (death) {
10842                while (who.isBinderAlive()) {
10843                    try {
10844                        death.wait();
10845                    } catch (InterruptedException e) {
10846                    }
10847                }
10848            }
10849            Watchdog.getInstance().setAllowRestart(true);
10850        }
10851    }
10852
10853    @Override
10854    public void restart() {
10855        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10856                != PackageManager.PERMISSION_GRANTED) {
10857            throw new SecurityException("Requires permission "
10858                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10859        }
10860
10861        Log.i(TAG, "Sending shutdown broadcast...");
10862
10863        BroadcastReceiver br = new BroadcastReceiver() {
10864            @Override public void onReceive(Context context, Intent intent) {
10865                // Now the broadcast is done, finish up the low-level shutdown.
10866                Log.i(TAG, "Shutting down activity manager...");
10867                shutdown(10000);
10868                Log.i(TAG, "Shutdown complete, restarting!");
10869                Process.killProcess(Process.myPid());
10870                System.exit(10);
10871            }
10872        };
10873
10874        // First send the high-level shut down broadcast.
10875        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10876        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10877        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10878        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10879        mContext.sendOrderedBroadcastAsUser(intent,
10880                UserHandle.ALL, null, br, mHandler, 0, null, null);
10881        */
10882        br.onReceive(mContext, intent);
10883    }
10884
10885    private long getLowRamTimeSinceIdle(long now) {
10886        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10887    }
10888
10889    @Override
10890    public void performIdleMaintenance() {
10891        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10892                != PackageManager.PERMISSION_GRANTED) {
10893            throw new SecurityException("Requires permission "
10894                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10895        }
10896
10897        synchronized (this) {
10898            final long now = SystemClock.uptimeMillis();
10899            final long timeSinceLastIdle = now - mLastIdleTime;
10900            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10901            mLastIdleTime = now;
10902            mLowRamTimeSinceLastIdle = 0;
10903            if (mLowRamStartTime != 0) {
10904                mLowRamStartTime = now;
10905            }
10906
10907            StringBuilder sb = new StringBuilder(128);
10908            sb.append("Idle maintenance over ");
10909            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10910            sb.append(" low RAM for ");
10911            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10912            Slog.i(TAG, sb.toString());
10913
10914            // If at least 1/3 of our time since the last idle period has been spent
10915            // with RAM low, then we want to kill processes.
10916            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10917
10918            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10919                ProcessRecord proc = mLruProcesses.get(i);
10920                if (proc.notCachedSinceIdle) {
10921                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10922                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10923                        if (doKilling && proc.initialIdlePss != 0
10924                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10925                            sb = new StringBuilder(128);
10926                            sb.append("Kill");
10927                            sb.append(proc.processName);
10928                            sb.append(" in idle maint: pss=");
10929                            sb.append(proc.lastPss);
10930                            sb.append(", initialPss=");
10931                            sb.append(proc.initialIdlePss);
10932                            sb.append(", period=");
10933                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10934                            sb.append(", lowRamPeriod=");
10935                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10936                            Slog.wtfQuiet(TAG, sb.toString());
10937                            proc.kill("idle maint (pss " + proc.lastPss
10938                                    + " from " + proc.initialIdlePss + ")", true);
10939                        }
10940                    }
10941                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10942                    proc.notCachedSinceIdle = true;
10943                    proc.initialIdlePss = 0;
10944                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10945                            mTestPssMode, isSleeping(), now);
10946                }
10947            }
10948
10949            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10950            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10951        }
10952    }
10953
10954    private void retrieveSettings() {
10955        final ContentResolver resolver = mContext.getContentResolver();
10956        String debugApp = Settings.Global.getString(
10957            resolver, Settings.Global.DEBUG_APP);
10958        boolean waitForDebugger = Settings.Global.getInt(
10959            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10960        boolean alwaysFinishActivities = Settings.Global.getInt(
10961            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10962        boolean forceRtl = Settings.Global.getInt(
10963                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10964        // Transfer any global setting for forcing RTL layout, into a System Property
10965        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10966
10967        Configuration configuration = new Configuration();
10968        Settings.System.getConfiguration(resolver, configuration);
10969        if (forceRtl) {
10970            // This will take care of setting the correct layout direction flags
10971            configuration.setLayoutDirection(configuration.locale);
10972        }
10973
10974        synchronized (this) {
10975            mDebugApp = mOrigDebugApp = debugApp;
10976            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10977            mAlwaysFinishActivities = alwaysFinishActivities;
10978            // This happens before any activities are started, so we can
10979            // change mConfiguration in-place.
10980            updateConfigurationLocked(configuration, null, false, true);
10981            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10982        }
10983    }
10984
10985    /** Loads resources after the current configuration has been set. */
10986    private void loadResourcesOnSystemReady() {
10987        final Resources res = mContext.getResources();
10988        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10989        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10990        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10991    }
10992
10993    public boolean testIsSystemReady() {
10994        // no need to synchronize(this) just to read & return the value
10995        return mSystemReady;
10996    }
10997
10998    private static File getCalledPreBootReceiversFile() {
10999        File dataDir = Environment.getDataDirectory();
11000        File systemDir = new File(dataDir, "system");
11001        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11002        return fname;
11003    }
11004
11005    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11006        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11007        File file = getCalledPreBootReceiversFile();
11008        FileInputStream fis = null;
11009        try {
11010            fis = new FileInputStream(file);
11011            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11012            int fvers = dis.readInt();
11013            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11014                String vers = dis.readUTF();
11015                String codename = dis.readUTF();
11016                String build = dis.readUTF();
11017                if (android.os.Build.VERSION.RELEASE.equals(vers)
11018                        && android.os.Build.VERSION.CODENAME.equals(codename)
11019                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11020                    int num = dis.readInt();
11021                    while (num > 0) {
11022                        num--;
11023                        String pkg = dis.readUTF();
11024                        String cls = dis.readUTF();
11025                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11026                    }
11027                }
11028            }
11029        } catch (FileNotFoundException e) {
11030        } catch (IOException e) {
11031            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11032        } finally {
11033            if (fis != null) {
11034                try {
11035                    fis.close();
11036                } catch (IOException e) {
11037                }
11038            }
11039        }
11040        return lastDoneReceivers;
11041    }
11042
11043    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11044        File file = getCalledPreBootReceiversFile();
11045        FileOutputStream fos = null;
11046        DataOutputStream dos = null;
11047        try {
11048            fos = new FileOutputStream(file);
11049            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11050            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11051            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11052            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11053            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11054            dos.writeInt(list.size());
11055            for (int i=0; i<list.size(); i++) {
11056                dos.writeUTF(list.get(i).getPackageName());
11057                dos.writeUTF(list.get(i).getClassName());
11058            }
11059        } catch (IOException e) {
11060            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11061            file.delete();
11062        } finally {
11063            FileUtils.sync(fos);
11064            if (dos != null) {
11065                try {
11066                    dos.close();
11067                } catch (IOException e) {
11068                    // TODO Auto-generated catch block
11069                    e.printStackTrace();
11070                }
11071            }
11072        }
11073    }
11074
11075    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11076            ArrayList<ComponentName> doneReceivers, int userId) {
11077        boolean waitingUpdate = false;
11078        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11079        List<ResolveInfo> ris = null;
11080        try {
11081            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11082                    intent, null, 0, userId);
11083        } catch (RemoteException e) {
11084        }
11085        if (ris != null) {
11086            for (int i=ris.size()-1; i>=0; i--) {
11087                if ((ris.get(i).activityInfo.applicationInfo.flags
11088                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11089                    ris.remove(i);
11090                }
11091            }
11092            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11093
11094            // For User 0, load the version number. When delivering to a new user, deliver
11095            // to all receivers.
11096            if (userId == UserHandle.USER_OWNER) {
11097                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11098                for (int i=0; i<ris.size(); i++) {
11099                    ActivityInfo ai = ris.get(i).activityInfo;
11100                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11101                    if (lastDoneReceivers.contains(comp)) {
11102                        // We already did the pre boot receiver for this app with the current
11103                        // platform version, so don't do it again...
11104                        ris.remove(i);
11105                        i--;
11106                        // ...however, do keep it as one that has been done, so we don't
11107                        // forget about it when rewriting the file of last done receivers.
11108                        doneReceivers.add(comp);
11109                    }
11110                }
11111            }
11112
11113            // If primary user, send broadcast to all available users, else just to userId
11114            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11115                    : new int[] { userId };
11116            for (int i = 0; i < ris.size(); i++) {
11117                ActivityInfo ai = ris.get(i).activityInfo;
11118                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11119                doneReceivers.add(comp);
11120                intent.setComponent(comp);
11121                for (int j=0; j<users.length; j++) {
11122                    IIntentReceiver finisher = null;
11123                    // On last receiver and user, set up a completion callback
11124                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11125                        finisher = new IIntentReceiver.Stub() {
11126                            public void performReceive(Intent intent, int resultCode,
11127                                    String data, Bundle extras, boolean ordered,
11128                                    boolean sticky, int sendingUser) {
11129                                // The raw IIntentReceiver interface is called
11130                                // with the AM lock held, so redispatch to
11131                                // execute our code without the lock.
11132                                mHandler.post(onFinishCallback);
11133                            }
11134                        };
11135                    }
11136                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11137                            + " for user " + users[j]);
11138                    broadcastIntentLocked(null, null, intent, null, finisher,
11139                            0, null, null, null, AppOpsManager.OP_NONE,
11140                            true, false, MY_PID, Process.SYSTEM_UID,
11141                            users[j]);
11142                    if (finisher != null) {
11143                        waitingUpdate = true;
11144                    }
11145                }
11146            }
11147        }
11148
11149        return waitingUpdate;
11150    }
11151
11152    public void systemReady(final Runnable goingCallback) {
11153        synchronized(this) {
11154            if (mSystemReady) {
11155                // If we're done calling all the receivers, run the next "boot phase" passed in
11156                // by the SystemServer
11157                if (goingCallback != null) {
11158                    goingCallback.run();
11159                }
11160                return;
11161            }
11162
11163            // Make sure we have the current profile info, since it is needed for
11164            // security checks.
11165            updateCurrentProfileIdsLocked();
11166
11167            if (mRecentTasks == null) {
11168                mRecentTasks = mTaskPersister.restoreTasksLocked();
11169                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11170                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11171                mTaskPersister.startPersisting();
11172            }
11173
11174            // Check to see if there are any update receivers to run.
11175            if (!mDidUpdate) {
11176                if (mWaitingUpdate) {
11177                    return;
11178                }
11179                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11180                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11181                    public void run() {
11182                        synchronized (ActivityManagerService.this) {
11183                            mDidUpdate = true;
11184                        }
11185                        writeLastDonePreBootReceivers(doneReceivers);
11186                        showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11187                                false);
11188                        systemReady(goingCallback);
11189                    }
11190                }, doneReceivers, UserHandle.USER_OWNER);
11191
11192                if (mWaitingUpdate) {
11193                    return;
11194                }
11195                mDidUpdate = true;
11196            }
11197
11198            mAppOpsService.systemReady();
11199            mSystemReady = true;
11200        }
11201
11202        ArrayList<ProcessRecord> procsToKill = null;
11203        synchronized(mPidsSelfLocked) {
11204            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11205                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11206                if (!isAllowedWhileBooting(proc.info)){
11207                    if (procsToKill == null) {
11208                        procsToKill = new ArrayList<ProcessRecord>();
11209                    }
11210                    procsToKill.add(proc);
11211                }
11212            }
11213        }
11214
11215        synchronized(this) {
11216            if (procsToKill != null) {
11217                for (int i=procsToKill.size()-1; i>=0; i--) {
11218                    ProcessRecord proc = procsToKill.get(i);
11219                    Slog.i(TAG, "Removing system update proc: " + proc);
11220                    removeProcessLocked(proc, true, false, "system update done");
11221                }
11222            }
11223
11224            // Now that we have cleaned up any update processes, we
11225            // are ready to start launching real processes and know that
11226            // we won't trample on them any more.
11227            mProcessesReady = true;
11228        }
11229
11230        Slog.i(TAG, "System now ready");
11231        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11232            SystemClock.uptimeMillis());
11233
11234        synchronized(this) {
11235            // Make sure we have no pre-ready processes sitting around.
11236
11237            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11238                ResolveInfo ri = mContext.getPackageManager()
11239                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11240                                STOCK_PM_FLAGS);
11241                CharSequence errorMsg = null;
11242                if (ri != null) {
11243                    ActivityInfo ai = ri.activityInfo;
11244                    ApplicationInfo app = ai.applicationInfo;
11245                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11246                        mTopAction = Intent.ACTION_FACTORY_TEST;
11247                        mTopData = null;
11248                        mTopComponent = new ComponentName(app.packageName,
11249                                ai.name);
11250                    } else {
11251                        errorMsg = mContext.getResources().getText(
11252                                com.android.internal.R.string.factorytest_not_system);
11253                    }
11254                } else {
11255                    errorMsg = mContext.getResources().getText(
11256                            com.android.internal.R.string.factorytest_no_action);
11257                }
11258                if (errorMsg != null) {
11259                    mTopAction = null;
11260                    mTopData = null;
11261                    mTopComponent = null;
11262                    Message msg = Message.obtain();
11263                    msg.what = SHOW_FACTORY_ERROR_MSG;
11264                    msg.getData().putCharSequence("msg", errorMsg);
11265                    mHandler.sendMessage(msg);
11266                }
11267            }
11268        }
11269
11270        retrieveSettings();
11271        loadResourcesOnSystemReady();
11272
11273        synchronized (this) {
11274            readGrantedUriPermissionsLocked();
11275        }
11276
11277        if (goingCallback != null) goingCallback.run();
11278
11279        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11280                Integer.toString(mCurrentUserId), mCurrentUserId);
11281        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11282                Integer.toString(mCurrentUserId), mCurrentUserId);
11283        mSystemServiceManager.startUser(mCurrentUserId);
11284
11285        synchronized (this) {
11286            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11287                try {
11288                    List apps = AppGlobals.getPackageManager().
11289                        getPersistentApplications(STOCK_PM_FLAGS);
11290                    if (apps != null) {
11291                        int N = apps.size();
11292                        int i;
11293                        for (i=0; i<N; i++) {
11294                            ApplicationInfo info
11295                                = (ApplicationInfo)apps.get(i);
11296                            if (info != null &&
11297                                    !info.packageName.equals("android")) {
11298                                addAppLocked(info, false, null /* ABI override */);
11299                            }
11300                        }
11301                    }
11302                } catch (RemoteException ex) {
11303                    // pm is in same process, this will never happen.
11304                }
11305            }
11306
11307            // Start up initial activity.
11308            mBooting = true;
11309            startHomeActivityLocked(mCurrentUserId);
11310
11311            try {
11312                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11313                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11314                            + " data partition or your device will be unstable.");
11315                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11316                }
11317            } catch (RemoteException e) {
11318            }
11319
11320            if (!Build.isFingerprintConsistent()) {
11321                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11322                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11323            }
11324
11325            long ident = Binder.clearCallingIdentity();
11326            try {
11327                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11328                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11329                        | Intent.FLAG_RECEIVER_FOREGROUND);
11330                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11331                broadcastIntentLocked(null, null, intent,
11332                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11333                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11334                intent = new Intent(Intent.ACTION_USER_STARTING);
11335                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11336                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11337                broadcastIntentLocked(null, null, intent,
11338                        null, new IIntentReceiver.Stub() {
11339                            @Override
11340                            public void performReceive(Intent intent, int resultCode, String data,
11341                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11342                                    throws RemoteException {
11343                            }
11344                        }, 0, null, null,
11345                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11346                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11347            } catch (Throwable t) {
11348                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11349            } finally {
11350                Binder.restoreCallingIdentity(ident);
11351            }
11352            mStackSupervisor.resumeTopActivitiesLocked();
11353            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11354        }
11355    }
11356
11357    private boolean makeAppCrashingLocked(ProcessRecord app,
11358            String shortMsg, String longMsg, String stackTrace) {
11359        app.crashing = true;
11360        app.crashingReport = generateProcessError(app,
11361                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11362        startAppProblemLocked(app);
11363        app.stopFreezingAllLocked();
11364        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11365    }
11366
11367    private void makeAppNotRespondingLocked(ProcessRecord app,
11368            String activity, String shortMsg, String longMsg) {
11369        app.notResponding = true;
11370        app.notRespondingReport = generateProcessError(app,
11371                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11372                activity, shortMsg, longMsg, null);
11373        startAppProblemLocked(app);
11374        app.stopFreezingAllLocked();
11375    }
11376
11377    /**
11378     * Generate a process error record, suitable for attachment to a ProcessRecord.
11379     *
11380     * @param app The ProcessRecord in which the error occurred.
11381     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11382     *                      ActivityManager.AppErrorStateInfo
11383     * @param activity The activity associated with the crash, if known.
11384     * @param shortMsg Short message describing the crash.
11385     * @param longMsg Long message describing the crash.
11386     * @param stackTrace Full crash stack trace, may be null.
11387     *
11388     * @return Returns a fully-formed AppErrorStateInfo record.
11389     */
11390    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11391            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11392        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11393
11394        report.condition = condition;
11395        report.processName = app.processName;
11396        report.pid = app.pid;
11397        report.uid = app.info.uid;
11398        report.tag = activity;
11399        report.shortMsg = shortMsg;
11400        report.longMsg = longMsg;
11401        report.stackTrace = stackTrace;
11402
11403        return report;
11404    }
11405
11406    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11407        synchronized (this) {
11408            app.crashing = false;
11409            app.crashingReport = null;
11410            app.notResponding = false;
11411            app.notRespondingReport = null;
11412            if (app.anrDialog == fromDialog) {
11413                app.anrDialog = null;
11414            }
11415            if (app.waitDialog == fromDialog) {
11416                app.waitDialog = null;
11417            }
11418            if (app.pid > 0 && app.pid != MY_PID) {
11419                handleAppCrashLocked(app, null, null, null);
11420                app.kill("user request after error", true);
11421            }
11422        }
11423    }
11424
11425    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11426            String stackTrace) {
11427        long now = SystemClock.uptimeMillis();
11428
11429        Long crashTime;
11430        if (!app.isolated) {
11431            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11432        } else {
11433            crashTime = null;
11434        }
11435        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11436            // This process loses!
11437            Slog.w(TAG, "Process " + app.info.processName
11438                    + " has crashed too many times: killing!");
11439            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11440                    app.userId, app.info.processName, app.uid);
11441            mStackSupervisor.handleAppCrashLocked(app);
11442            if (!app.persistent) {
11443                // We don't want to start this process again until the user
11444                // explicitly does so...  but for persistent process, we really
11445                // need to keep it running.  If a persistent process is actually
11446                // repeatedly crashing, then badness for everyone.
11447                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11448                        app.info.processName);
11449                if (!app.isolated) {
11450                    // XXX We don't have a way to mark isolated processes
11451                    // as bad, since they don't have a peristent identity.
11452                    mBadProcesses.put(app.info.processName, app.uid,
11453                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11454                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11455                }
11456                app.bad = true;
11457                app.removed = true;
11458                // Don't let services in this process be restarted and potentially
11459                // annoy the user repeatedly.  Unless it is persistent, since those
11460                // processes run critical code.
11461                removeProcessLocked(app, false, false, "crash");
11462                mStackSupervisor.resumeTopActivitiesLocked();
11463                return false;
11464            }
11465            mStackSupervisor.resumeTopActivitiesLocked();
11466        } else {
11467            mStackSupervisor.finishTopRunningActivityLocked(app);
11468        }
11469
11470        // Bump up the crash count of any services currently running in the proc.
11471        for (int i=app.services.size()-1; i>=0; i--) {
11472            // Any services running in the application need to be placed
11473            // back in the pending list.
11474            ServiceRecord sr = app.services.valueAt(i);
11475            sr.crashCount++;
11476        }
11477
11478        // If the crashing process is what we consider to be the "home process" and it has been
11479        // replaced by a third-party app, clear the package preferred activities from packages
11480        // with a home activity running in the process to prevent a repeatedly crashing app
11481        // from blocking the user to manually clear the list.
11482        final ArrayList<ActivityRecord> activities = app.activities;
11483        if (app == mHomeProcess && activities.size() > 0
11484                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11485            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11486                final ActivityRecord r = activities.get(activityNdx);
11487                if (r.isHomeActivity()) {
11488                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11489                    try {
11490                        ActivityThread.getPackageManager()
11491                                .clearPackagePreferredActivities(r.packageName);
11492                    } catch (RemoteException c) {
11493                        // pm is in same process, this will never happen.
11494                    }
11495                }
11496            }
11497        }
11498
11499        if (!app.isolated) {
11500            // XXX Can't keep track of crash times for isolated processes,
11501            // because they don't have a perisistent identity.
11502            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11503        }
11504
11505        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11506        return true;
11507    }
11508
11509    void startAppProblemLocked(ProcessRecord app) {
11510        // If this app is not running under the current user, then we
11511        // can't give it a report button because that would require
11512        // launching the report UI under a different user.
11513        app.errorReportReceiver = null;
11514
11515        for (int userId : mCurrentProfileIds) {
11516            if (app.userId == userId) {
11517                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11518                        mContext, app.info.packageName, app.info.flags);
11519            }
11520        }
11521        skipCurrentReceiverLocked(app);
11522    }
11523
11524    void skipCurrentReceiverLocked(ProcessRecord app) {
11525        for (BroadcastQueue queue : mBroadcastQueues) {
11526            queue.skipCurrentReceiverLocked(app);
11527        }
11528    }
11529
11530    /**
11531     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11532     * The application process will exit immediately after this call returns.
11533     * @param app object of the crashing app, null for the system server
11534     * @param crashInfo describing the exception
11535     */
11536    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11537        ProcessRecord r = findAppProcess(app, "Crash");
11538        final String processName = app == null ? "system_server"
11539                : (r == null ? "unknown" : r.processName);
11540
11541        handleApplicationCrashInner("crash", r, processName, crashInfo);
11542    }
11543
11544    /* Native crash reporting uses this inner version because it needs to be somewhat
11545     * decoupled from the AM-managed cleanup lifecycle
11546     */
11547    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11548            ApplicationErrorReport.CrashInfo crashInfo) {
11549        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11550                UserHandle.getUserId(Binder.getCallingUid()), processName,
11551                r == null ? -1 : r.info.flags,
11552                crashInfo.exceptionClassName,
11553                crashInfo.exceptionMessage,
11554                crashInfo.throwFileName,
11555                crashInfo.throwLineNumber);
11556
11557        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11558
11559        crashApplication(r, crashInfo);
11560    }
11561
11562    public void handleApplicationStrictModeViolation(
11563            IBinder app,
11564            int violationMask,
11565            StrictMode.ViolationInfo info) {
11566        ProcessRecord r = findAppProcess(app, "StrictMode");
11567        if (r == null) {
11568            return;
11569        }
11570
11571        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11572            Integer stackFingerprint = info.hashCode();
11573            boolean logIt = true;
11574            synchronized (mAlreadyLoggedViolatedStacks) {
11575                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11576                    logIt = false;
11577                    // TODO: sub-sample into EventLog for these, with
11578                    // the info.durationMillis?  Then we'd get
11579                    // the relative pain numbers, without logging all
11580                    // the stack traces repeatedly.  We'd want to do
11581                    // likewise in the client code, which also does
11582                    // dup suppression, before the Binder call.
11583                } else {
11584                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11585                        mAlreadyLoggedViolatedStacks.clear();
11586                    }
11587                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11588                }
11589            }
11590            if (logIt) {
11591                logStrictModeViolationToDropBox(r, info);
11592            }
11593        }
11594
11595        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11596            AppErrorResult result = new AppErrorResult();
11597            synchronized (this) {
11598                final long origId = Binder.clearCallingIdentity();
11599
11600                Message msg = Message.obtain();
11601                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11602                HashMap<String, Object> data = new HashMap<String, Object>();
11603                data.put("result", result);
11604                data.put("app", r);
11605                data.put("violationMask", violationMask);
11606                data.put("info", info);
11607                msg.obj = data;
11608                mHandler.sendMessage(msg);
11609
11610                Binder.restoreCallingIdentity(origId);
11611            }
11612            int res = result.get();
11613            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11614        }
11615    }
11616
11617    // Depending on the policy in effect, there could be a bunch of
11618    // these in quick succession so we try to batch these together to
11619    // minimize disk writes, number of dropbox entries, and maximize
11620    // compression, by having more fewer, larger records.
11621    private void logStrictModeViolationToDropBox(
11622            ProcessRecord process,
11623            StrictMode.ViolationInfo info) {
11624        if (info == null) {
11625            return;
11626        }
11627        final boolean isSystemApp = process == null ||
11628                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11629                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11630        final String processName = process == null ? "unknown" : process.processName;
11631        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11632        final DropBoxManager dbox = (DropBoxManager)
11633                mContext.getSystemService(Context.DROPBOX_SERVICE);
11634
11635        // Exit early if the dropbox isn't configured to accept this report type.
11636        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11637
11638        boolean bufferWasEmpty;
11639        boolean needsFlush;
11640        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11641        synchronized (sb) {
11642            bufferWasEmpty = sb.length() == 0;
11643            appendDropBoxProcessHeaders(process, processName, sb);
11644            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11645            sb.append("System-App: ").append(isSystemApp).append("\n");
11646            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11647            if (info.violationNumThisLoop != 0) {
11648                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11649            }
11650            if (info.numAnimationsRunning != 0) {
11651                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11652            }
11653            if (info.broadcastIntentAction != null) {
11654                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11655            }
11656            if (info.durationMillis != -1) {
11657                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11658            }
11659            if (info.numInstances != -1) {
11660                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11661            }
11662            if (info.tags != null) {
11663                for (String tag : info.tags) {
11664                    sb.append("Span-Tag: ").append(tag).append("\n");
11665                }
11666            }
11667            sb.append("\n");
11668            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11669                sb.append(info.crashInfo.stackTrace);
11670            }
11671            sb.append("\n");
11672
11673            // Only buffer up to ~64k.  Various logging bits truncate
11674            // things at 128k.
11675            needsFlush = (sb.length() > 64 * 1024);
11676        }
11677
11678        // Flush immediately if the buffer's grown too large, or this
11679        // is a non-system app.  Non-system apps are isolated with a
11680        // different tag & policy and not batched.
11681        //
11682        // Batching is useful during internal testing with
11683        // StrictMode settings turned up high.  Without batching,
11684        // thousands of separate files could be created on boot.
11685        if (!isSystemApp || needsFlush) {
11686            new Thread("Error dump: " + dropboxTag) {
11687                @Override
11688                public void run() {
11689                    String report;
11690                    synchronized (sb) {
11691                        report = sb.toString();
11692                        sb.delete(0, sb.length());
11693                        sb.trimToSize();
11694                    }
11695                    if (report.length() != 0) {
11696                        dbox.addText(dropboxTag, report);
11697                    }
11698                }
11699            }.start();
11700            return;
11701        }
11702
11703        // System app batching:
11704        if (!bufferWasEmpty) {
11705            // An existing dropbox-writing thread is outstanding, so
11706            // we don't need to start it up.  The existing thread will
11707            // catch the buffer appends we just did.
11708            return;
11709        }
11710
11711        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11712        // (After this point, we shouldn't access AMS internal data structures.)
11713        new Thread("Error dump: " + dropboxTag) {
11714            @Override
11715            public void run() {
11716                // 5 second sleep to let stacks arrive and be batched together
11717                try {
11718                    Thread.sleep(5000);  // 5 seconds
11719                } catch (InterruptedException e) {}
11720
11721                String errorReport;
11722                synchronized (mStrictModeBuffer) {
11723                    errorReport = mStrictModeBuffer.toString();
11724                    if (errorReport.length() == 0) {
11725                        return;
11726                    }
11727                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11728                    mStrictModeBuffer.trimToSize();
11729                }
11730                dbox.addText(dropboxTag, errorReport);
11731            }
11732        }.start();
11733    }
11734
11735    /**
11736     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11737     * @param app object of the crashing app, null for the system server
11738     * @param tag reported by the caller
11739     * @param system whether this wtf is coming from the system
11740     * @param crashInfo describing the context of the error
11741     * @return true if the process should exit immediately (WTF is fatal)
11742     */
11743    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11744            final ApplicationErrorReport.CrashInfo crashInfo) {
11745        final int callingUid = Binder.getCallingUid();
11746        final int callingPid = Binder.getCallingPid();
11747
11748        if (system) {
11749            // If this is coming from the system, we could very well have low-level
11750            // system locks held, so we want to do this all asynchronously.  And we
11751            // never want this to become fatal, so there is that too.
11752            mHandler.post(new Runnable() {
11753                @Override public void run() {
11754                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11755                }
11756            });
11757            return false;
11758        }
11759
11760        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11761                crashInfo);
11762
11763        if (r != null && r.pid != Process.myPid() &&
11764                Settings.Global.getInt(mContext.getContentResolver(),
11765                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11766            crashApplication(r, crashInfo);
11767            return true;
11768        } else {
11769            return false;
11770        }
11771    }
11772
11773    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11774            final ApplicationErrorReport.CrashInfo crashInfo) {
11775        final ProcessRecord r = findAppProcess(app, "WTF");
11776        final String processName = app == null ? "system_server"
11777                : (r == null ? "unknown" : r.processName);
11778
11779        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11780                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11781
11782        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11783
11784        return r;
11785    }
11786
11787    /**
11788     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11789     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11790     */
11791    private ProcessRecord findAppProcess(IBinder app, String reason) {
11792        if (app == null) {
11793            return null;
11794        }
11795
11796        synchronized (this) {
11797            final int NP = mProcessNames.getMap().size();
11798            for (int ip=0; ip<NP; ip++) {
11799                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11800                final int NA = apps.size();
11801                for (int ia=0; ia<NA; ia++) {
11802                    ProcessRecord p = apps.valueAt(ia);
11803                    if (p.thread != null && p.thread.asBinder() == app) {
11804                        return p;
11805                    }
11806                }
11807            }
11808
11809            Slog.w(TAG, "Can't find mystery application for " + reason
11810                    + " from pid=" + Binder.getCallingPid()
11811                    + " uid=" + Binder.getCallingUid() + ": " + app);
11812            return null;
11813        }
11814    }
11815
11816    /**
11817     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11818     * to append various headers to the dropbox log text.
11819     */
11820    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11821            StringBuilder sb) {
11822        // Watchdog thread ends up invoking this function (with
11823        // a null ProcessRecord) to add the stack file to dropbox.
11824        // Do not acquire a lock on this (am) in such cases, as it
11825        // could cause a potential deadlock, if and when watchdog
11826        // is invoked due to unavailability of lock on am and it
11827        // would prevent watchdog from killing system_server.
11828        if (process == null) {
11829            sb.append("Process: ").append(processName).append("\n");
11830            return;
11831        }
11832        // Note: ProcessRecord 'process' is guarded by the service
11833        // instance.  (notably process.pkgList, which could otherwise change
11834        // concurrently during execution of this method)
11835        synchronized (this) {
11836            sb.append("Process: ").append(processName).append("\n");
11837            int flags = process.info.flags;
11838            IPackageManager pm = AppGlobals.getPackageManager();
11839            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11840            for (int ip=0; ip<process.pkgList.size(); ip++) {
11841                String pkg = process.pkgList.keyAt(ip);
11842                sb.append("Package: ").append(pkg);
11843                try {
11844                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11845                    if (pi != null) {
11846                        sb.append(" v").append(pi.versionCode);
11847                        if (pi.versionName != null) {
11848                            sb.append(" (").append(pi.versionName).append(")");
11849                        }
11850                    }
11851                } catch (RemoteException e) {
11852                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11853                }
11854                sb.append("\n");
11855            }
11856        }
11857    }
11858
11859    private static String processClass(ProcessRecord process) {
11860        if (process == null || process.pid == MY_PID) {
11861            return "system_server";
11862        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11863            return "system_app";
11864        } else {
11865            return "data_app";
11866        }
11867    }
11868
11869    /**
11870     * Write a description of an error (crash, WTF, ANR) to the drop box.
11871     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11872     * @param process which caused the error, null means the system server
11873     * @param activity which triggered the error, null if unknown
11874     * @param parent activity related to the error, null if unknown
11875     * @param subject line related to the error, null if absent
11876     * @param report in long form describing the error, null if absent
11877     * @param logFile to include in the report, null if none
11878     * @param crashInfo giving an application stack trace, null if absent
11879     */
11880    public void addErrorToDropBox(String eventType,
11881            ProcessRecord process, String processName, ActivityRecord activity,
11882            ActivityRecord parent, String subject,
11883            final String report, final File logFile,
11884            final ApplicationErrorReport.CrashInfo crashInfo) {
11885        // NOTE -- this must never acquire the ActivityManagerService lock,
11886        // otherwise the watchdog may be prevented from resetting the system.
11887
11888        final String dropboxTag = processClass(process) + "_" + eventType;
11889        final DropBoxManager dbox = (DropBoxManager)
11890                mContext.getSystemService(Context.DROPBOX_SERVICE);
11891
11892        // Exit early if the dropbox isn't configured to accept this report type.
11893        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11894
11895        final StringBuilder sb = new StringBuilder(1024);
11896        appendDropBoxProcessHeaders(process, processName, sb);
11897        if (activity != null) {
11898            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11899        }
11900        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11901            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11902        }
11903        if (parent != null && parent != activity) {
11904            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11905        }
11906        if (subject != null) {
11907            sb.append("Subject: ").append(subject).append("\n");
11908        }
11909        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11910        if (Debug.isDebuggerConnected()) {
11911            sb.append("Debugger: Connected\n");
11912        }
11913        sb.append("\n");
11914
11915        // Do the rest in a worker thread to avoid blocking the caller on I/O
11916        // (After this point, we shouldn't access AMS internal data structures.)
11917        Thread worker = new Thread("Error dump: " + dropboxTag) {
11918            @Override
11919            public void run() {
11920                if (report != null) {
11921                    sb.append(report);
11922                }
11923                if (logFile != null) {
11924                    try {
11925                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11926                                    "\n\n[[TRUNCATED]]"));
11927                    } catch (IOException e) {
11928                        Slog.e(TAG, "Error reading " + logFile, e);
11929                    }
11930                }
11931                if (crashInfo != null && crashInfo.stackTrace != null) {
11932                    sb.append(crashInfo.stackTrace);
11933                }
11934
11935                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11936                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11937                if (lines > 0) {
11938                    sb.append("\n");
11939
11940                    // Merge several logcat streams, and take the last N lines
11941                    InputStreamReader input = null;
11942                    try {
11943                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11944                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11945                                "-b", "crash",
11946                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11947
11948                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11949                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11950                        input = new InputStreamReader(logcat.getInputStream());
11951
11952                        int num;
11953                        char[] buf = new char[8192];
11954                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11955                    } catch (IOException e) {
11956                        Slog.e(TAG, "Error running logcat", e);
11957                    } finally {
11958                        if (input != null) try { input.close(); } catch (IOException e) {}
11959                    }
11960                }
11961
11962                dbox.addText(dropboxTag, sb.toString());
11963            }
11964        };
11965
11966        if (process == null) {
11967            // If process is null, we are being called from some internal code
11968            // and may be about to die -- run this synchronously.
11969            worker.run();
11970        } else {
11971            worker.start();
11972        }
11973    }
11974
11975    /**
11976     * Bring up the "unexpected error" dialog box for a crashing app.
11977     * Deal with edge cases (intercepts from instrumented applications,
11978     * ActivityController, error intent receivers, that sort of thing).
11979     * @param r the application crashing
11980     * @param crashInfo describing the failure
11981     */
11982    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11983        long timeMillis = System.currentTimeMillis();
11984        String shortMsg = crashInfo.exceptionClassName;
11985        String longMsg = crashInfo.exceptionMessage;
11986        String stackTrace = crashInfo.stackTrace;
11987        if (shortMsg != null && longMsg != null) {
11988            longMsg = shortMsg + ": " + longMsg;
11989        } else if (shortMsg != null) {
11990            longMsg = shortMsg;
11991        }
11992
11993        AppErrorResult result = new AppErrorResult();
11994        synchronized (this) {
11995            if (mController != null) {
11996                try {
11997                    String name = r != null ? r.processName : null;
11998                    int pid = r != null ? r.pid : Binder.getCallingPid();
11999                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12000                    if (!mController.appCrashed(name, pid,
12001                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12002                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12003                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12004                            Slog.w(TAG, "Skip killing native crashed app " + name
12005                                    + "(" + pid + ") during testing");
12006                        } else {
12007                            Slog.w(TAG, "Force-killing crashed app " + name
12008                                    + " at watcher's request");
12009                            if (r != null) {
12010                                r.kill("crash", true);
12011                            } else {
12012                                // Huh.
12013                                Process.killProcess(pid);
12014                                Process.killProcessGroup(uid, pid);
12015                            }
12016                        }
12017                        return;
12018                    }
12019                } catch (RemoteException e) {
12020                    mController = null;
12021                    Watchdog.getInstance().setActivityController(null);
12022                }
12023            }
12024
12025            final long origId = Binder.clearCallingIdentity();
12026
12027            // If this process is running instrumentation, finish it.
12028            if (r != null && r.instrumentationClass != null) {
12029                Slog.w(TAG, "Error in app " + r.processName
12030                      + " running instrumentation " + r.instrumentationClass + ":");
12031                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12032                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12033                Bundle info = new Bundle();
12034                info.putString("shortMsg", shortMsg);
12035                info.putString("longMsg", longMsg);
12036                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12037                Binder.restoreCallingIdentity(origId);
12038                return;
12039            }
12040
12041            // Log crash in battery stats.
12042            if (r != null) {
12043                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12044            }
12045
12046            // If we can't identify the process or it's already exceeded its crash quota,
12047            // quit right away without showing a crash dialog.
12048            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12049                Binder.restoreCallingIdentity(origId);
12050                return;
12051            }
12052
12053            Message msg = Message.obtain();
12054            msg.what = SHOW_ERROR_MSG;
12055            HashMap data = new HashMap();
12056            data.put("result", result);
12057            data.put("app", r);
12058            msg.obj = data;
12059            mHandler.sendMessage(msg);
12060
12061            Binder.restoreCallingIdentity(origId);
12062        }
12063
12064        int res = result.get();
12065
12066        Intent appErrorIntent = null;
12067        synchronized (this) {
12068            if (r != null && !r.isolated) {
12069                // XXX Can't keep track of crash time for isolated processes,
12070                // since they don't have a persistent identity.
12071                mProcessCrashTimes.put(r.info.processName, r.uid,
12072                        SystemClock.uptimeMillis());
12073            }
12074            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12075                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12076            }
12077        }
12078
12079        if (appErrorIntent != null) {
12080            try {
12081                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12082            } catch (ActivityNotFoundException e) {
12083                Slog.w(TAG, "bug report receiver dissappeared", e);
12084            }
12085        }
12086    }
12087
12088    Intent createAppErrorIntentLocked(ProcessRecord r,
12089            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12090        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12091        if (report == null) {
12092            return null;
12093        }
12094        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12095        result.setComponent(r.errorReportReceiver);
12096        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12097        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12098        return result;
12099    }
12100
12101    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12102            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12103        if (r.errorReportReceiver == null) {
12104            return null;
12105        }
12106
12107        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12108            return null;
12109        }
12110
12111        ApplicationErrorReport report = new ApplicationErrorReport();
12112        report.packageName = r.info.packageName;
12113        report.installerPackageName = r.errorReportReceiver.getPackageName();
12114        report.processName = r.processName;
12115        report.time = timeMillis;
12116        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12117
12118        if (r.crashing || r.forceCrashReport) {
12119            report.type = ApplicationErrorReport.TYPE_CRASH;
12120            report.crashInfo = crashInfo;
12121        } else if (r.notResponding) {
12122            report.type = ApplicationErrorReport.TYPE_ANR;
12123            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12124
12125            report.anrInfo.activity = r.notRespondingReport.tag;
12126            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12127            report.anrInfo.info = r.notRespondingReport.longMsg;
12128        }
12129
12130        return report;
12131    }
12132
12133    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12134        enforceNotIsolatedCaller("getProcessesInErrorState");
12135        // assume our apps are happy - lazy create the list
12136        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12137
12138        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12139                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12140        int userId = UserHandle.getUserId(Binder.getCallingUid());
12141
12142        synchronized (this) {
12143
12144            // iterate across all processes
12145            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12146                ProcessRecord app = mLruProcesses.get(i);
12147                if (!allUsers && app.userId != userId) {
12148                    continue;
12149                }
12150                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12151                    // This one's in trouble, so we'll generate a report for it
12152                    // crashes are higher priority (in case there's a crash *and* an anr)
12153                    ActivityManager.ProcessErrorStateInfo report = null;
12154                    if (app.crashing) {
12155                        report = app.crashingReport;
12156                    } else if (app.notResponding) {
12157                        report = app.notRespondingReport;
12158                    }
12159
12160                    if (report != null) {
12161                        if (errList == null) {
12162                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12163                        }
12164                        errList.add(report);
12165                    } else {
12166                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12167                                " crashing = " + app.crashing +
12168                                " notResponding = " + app.notResponding);
12169                    }
12170                }
12171            }
12172        }
12173
12174        return errList;
12175    }
12176
12177    static int procStateToImportance(int procState, int memAdj,
12178            ActivityManager.RunningAppProcessInfo currApp) {
12179        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12180        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12181            currApp.lru = memAdj;
12182        } else {
12183            currApp.lru = 0;
12184        }
12185        return imp;
12186    }
12187
12188    private void fillInProcMemInfo(ProcessRecord app,
12189            ActivityManager.RunningAppProcessInfo outInfo) {
12190        outInfo.pid = app.pid;
12191        outInfo.uid = app.info.uid;
12192        if (mHeavyWeightProcess == app) {
12193            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12194        }
12195        if (app.persistent) {
12196            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12197        }
12198        if (app.activities.size() > 0) {
12199            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12200        }
12201        outInfo.lastTrimLevel = app.trimMemoryLevel;
12202        int adj = app.curAdj;
12203        int procState = app.curProcState;
12204        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12205        outInfo.importanceReasonCode = app.adjTypeCode;
12206        outInfo.processState = app.curProcState;
12207    }
12208
12209    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12210        enforceNotIsolatedCaller("getRunningAppProcesses");
12211        // Lazy instantiation of list
12212        List<ActivityManager.RunningAppProcessInfo> runList = null;
12213        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12214                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12215        int userId = UserHandle.getUserId(Binder.getCallingUid());
12216        synchronized (this) {
12217            // Iterate across all processes
12218            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12219                ProcessRecord app = mLruProcesses.get(i);
12220                if (!allUsers && app.userId != userId) {
12221                    continue;
12222                }
12223                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12224                    // Generate process state info for running application
12225                    ActivityManager.RunningAppProcessInfo currApp =
12226                        new ActivityManager.RunningAppProcessInfo(app.processName,
12227                                app.pid, app.getPackageList());
12228                    fillInProcMemInfo(app, currApp);
12229                    if (app.adjSource instanceof ProcessRecord) {
12230                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12231                        currApp.importanceReasonImportance =
12232                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12233                                        app.adjSourceProcState);
12234                    } else if (app.adjSource instanceof ActivityRecord) {
12235                        ActivityRecord r = (ActivityRecord)app.adjSource;
12236                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12237                    }
12238                    if (app.adjTarget instanceof ComponentName) {
12239                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12240                    }
12241                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12242                    //        + " lru=" + currApp.lru);
12243                    if (runList == null) {
12244                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12245                    }
12246                    runList.add(currApp);
12247                }
12248            }
12249        }
12250        return runList;
12251    }
12252
12253    public List<ApplicationInfo> getRunningExternalApplications() {
12254        enforceNotIsolatedCaller("getRunningExternalApplications");
12255        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12256        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12257        if (runningApps != null && runningApps.size() > 0) {
12258            Set<String> extList = new HashSet<String>();
12259            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12260                if (app.pkgList != null) {
12261                    for (String pkg : app.pkgList) {
12262                        extList.add(pkg);
12263                    }
12264                }
12265            }
12266            IPackageManager pm = AppGlobals.getPackageManager();
12267            for (String pkg : extList) {
12268                try {
12269                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12270                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12271                        retList.add(info);
12272                    }
12273                } catch (RemoteException e) {
12274                }
12275            }
12276        }
12277        return retList;
12278    }
12279
12280    @Override
12281    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12282        enforceNotIsolatedCaller("getMyMemoryState");
12283        synchronized (this) {
12284            ProcessRecord proc;
12285            synchronized (mPidsSelfLocked) {
12286                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12287            }
12288            fillInProcMemInfo(proc, outInfo);
12289        }
12290    }
12291
12292    @Override
12293    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12294        if (checkCallingPermission(android.Manifest.permission.DUMP)
12295                != PackageManager.PERMISSION_GRANTED) {
12296            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12297                    + Binder.getCallingPid()
12298                    + ", uid=" + Binder.getCallingUid()
12299                    + " without permission "
12300                    + android.Manifest.permission.DUMP);
12301            return;
12302        }
12303
12304        boolean dumpAll = false;
12305        boolean dumpClient = false;
12306        String dumpPackage = null;
12307
12308        int opti = 0;
12309        while (opti < args.length) {
12310            String opt = args[opti];
12311            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12312                break;
12313            }
12314            opti++;
12315            if ("-a".equals(opt)) {
12316                dumpAll = true;
12317            } else if ("-c".equals(opt)) {
12318                dumpClient = true;
12319            } else if ("-h".equals(opt)) {
12320                pw.println("Activity manager dump options:");
12321                pw.println("  [-a] [-c] [-h] [cmd] ...");
12322                pw.println("  cmd may be one of:");
12323                pw.println("    a[ctivities]: activity stack state");
12324                pw.println("    r[recents]: recent activities state");
12325                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12326                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12327                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12328                pw.println("    o[om]: out of memory management");
12329                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12330                pw.println("    provider [COMP_SPEC]: provider client-side state");
12331                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12332                pw.println("    service [COMP_SPEC]: service client-side state");
12333                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12334                pw.println("    all: dump all activities");
12335                pw.println("    top: dump the top activity");
12336                pw.println("    write: write all pending state to storage");
12337                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12338                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12339                pw.println("    a partial substring in a component name, a");
12340                pw.println("    hex object identifier.");
12341                pw.println("  -a: include all available server state.");
12342                pw.println("  -c: include client state.");
12343                return;
12344            } else {
12345                pw.println("Unknown argument: " + opt + "; use -h for help");
12346            }
12347        }
12348
12349        long origId = Binder.clearCallingIdentity();
12350        boolean more = false;
12351        // Is the caller requesting to dump a particular piece of data?
12352        if (opti < args.length) {
12353            String cmd = args[opti];
12354            opti++;
12355            if ("activities".equals(cmd) || "a".equals(cmd)) {
12356                synchronized (this) {
12357                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12358                }
12359            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12360                synchronized (this) {
12361                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12362                }
12363            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12364                String[] newArgs;
12365                String name;
12366                if (opti >= args.length) {
12367                    name = null;
12368                    newArgs = EMPTY_STRING_ARRAY;
12369                } else {
12370                    name = args[opti];
12371                    opti++;
12372                    newArgs = new String[args.length - opti];
12373                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12374                            args.length - opti);
12375                }
12376                synchronized (this) {
12377                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12378                }
12379            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12380                String[] newArgs;
12381                String name;
12382                if (opti >= args.length) {
12383                    name = null;
12384                    newArgs = EMPTY_STRING_ARRAY;
12385                } else {
12386                    name = args[opti];
12387                    opti++;
12388                    newArgs = new String[args.length - opti];
12389                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12390                            args.length - opti);
12391                }
12392                synchronized (this) {
12393                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12394                }
12395            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12396                String[] newArgs;
12397                String name;
12398                if (opti >= args.length) {
12399                    name = null;
12400                    newArgs = EMPTY_STRING_ARRAY;
12401                } else {
12402                    name = args[opti];
12403                    opti++;
12404                    newArgs = new String[args.length - opti];
12405                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12406                            args.length - opti);
12407                }
12408                synchronized (this) {
12409                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12410                }
12411            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12412                synchronized (this) {
12413                    dumpOomLocked(fd, pw, args, opti, true);
12414                }
12415            } else if ("provider".equals(cmd)) {
12416                String[] newArgs;
12417                String name;
12418                if (opti >= args.length) {
12419                    name = null;
12420                    newArgs = EMPTY_STRING_ARRAY;
12421                } else {
12422                    name = args[opti];
12423                    opti++;
12424                    newArgs = new String[args.length - opti];
12425                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12426                }
12427                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12428                    pw.println("No providers match: " + name);
12429                    pw.println("Use -h for help.");
12430                }
12431            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12432                synchronized (this) {
12433                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12434                }
12435            } else if ("service".equals(cmd)) {
12436                String[] newArgs;
12437                String name;
12438                if (opti >= args.length) {
12439                    name = null;
12440                    newArgs = EMPTY_STRING_ARRAY;
12441                } else {
12442                    name = args[opti];
12443                    opti++;
12444                    newArgs = new String[args.length - opti];
12445                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12446                            args.length - opti);
12447                }
12448                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12449                    pw.println("No services match: " + name);
12450                    pw.println("Use -h for help.");
12451                }
12452            } else if ("package".equals(cmd)) {
12453                String[] newArgs;
12454                if (opti >= args.length) {
12455                    pw.println("package: no package name specified");
12456                    pw.println("Use -h for help.");
12457                } else {
12458                    dumpPackage = args[opti];
12459                    opti++;
12460                    newArgs = new String[args.length - opti];
12461                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12462                            args.length - opti);
12463                    args = newArgs;
12464                    opti = 0;
12465                    more = true;
12466                }
12467            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12468                synchronized (this) {
12469                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12470                }
12471            } else if ("write".equals(cmd)) {
12472                mTaskPersister.flush();
12473                pw.println("All tasks persisted.");
12474                return;
12475            } else {
12476                // Dumping a single activity?
12477                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12478                    pw.println("Bad activity command, or no activities match: " + cmd);
12479                    pw.println("Use -h for help.");
12480                }
12481            }
12482            if (!more) {
12483                Binder.restoreCallingIdentity(origId);
12484                return;
12485            }
12486        }
12487
12488        // No piece of data specified, dump everything.
12489        synchronized (this) {
12490            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12491            pw.println();
12492            if (dumpAll) {
12493                pw.println("-------------------------------------------------------------------------------");
12494            }
12495            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12496            pw.println();
12497            if (dumpAll) {
12498                pw.println("-------------------------------------------------------------------------------");
12499            }
12500            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12501            pw.println();
12502            if (dumpAll) {
12503                pw.println("-------------------------------------------------------------------------------");
12504            }
12505            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12506            pw.println();
12507            if (dumpAll) {
12508                pw.println("-------------------------------------------------------------------------------");
12509            }
12510            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12511            pw.println();
12512            if (dumpAll) {
12513                pw.println("-------------------------------------------------------------------------------");
12514            }
12515            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12516            pw.println();
12517            if (dumpAll) {
12518                pw.println("-------------------------------------------------------------------------------");
12519            }
12520            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12521        }
12522        Binder.restoreCallingIdentity(origId);
12523    }
12524
12525    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12526            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12527        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12528
12529        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12530                dumpPackage);
12531        boolean needSep = printedAnything;
12532
12533        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12534                dumpPackage, needSep, "  mFocusedActivity: ");
12535        if (printed) {
12536            printedAnything = true;
12537            needSep = false;
12538        }
12539
12540        if (dumpPackage == null) {
12541            if (needSep) {
12542                pw.println();
12543            }
12544            needSep = true;
12545            printedAnything = true;
12546            mStackSupervisor.dump(pw, "  ");
12547        }
12548
12549        if (!printedAnything) {
12550            pw.println("  (nothing)");
12551        }
12552    }
12553
12554    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12555            int opti, boolean dumpAll, String dumpPackage) {
12556        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12557
12558        boolean printedAnything = false;
12559
12560        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12561            boolean printedHeader = false;
12562
12563            final int N = mRecentTasks.size();
12564            for (int i=0; i<N; i++) {
12565                TaskRecord tr = mRecentTasks.get(i);
12566                if (dumpPackage != null) {
12567                    if (tr.realActivity == null ||
12568                            !dumpPackage.equals(tr.realActivity)) {
12569                        continue;
12570                    }
12571                }
12572                if (!printedHeader) {
12573                    pw.println("  Recent tasks:");
12574                    printedHeader = true;
12575                    printedAnything = true;
12576                }
12577                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12578                        pw.println(tr);
12579                if (dumpAll) {
12580                    mRecentTasks.get(i).dump(pw, "    ");
12581                }
12582            }
12583        }
12584
12585        if (!printedAnything) {
12586            pw.println("  (nothing)");
12587        }
12588    }
12589
12590    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12591            int opti, boolean dumpAll, String dumpPackage) {
12592        boolean needSep = false;
12593        boolean printedAnything = false;
12594        int numPers = 0;
12595
12596        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12597
12598        if (dumpAll) {
12599            final int NP = mProcessNames.getMap().size();
12600            for (int ip=0; ip<NP; ip++) {
12601                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12602                final int NA = procs.size();
12603                for (int ia=0; ia<NA; ia++) {
12604                    ProcessRecord r = procs.valueAt(ia);
12605                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12606                        continue;
12607                    }
12608                    if (!needSep) {
12609                        pw.println("  All known processes:");
12610                        needSep = true;
12611                        printedAnything = true;
12612                    }
12613                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12614                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12615                        pw.print(" "); pw.println(r);
12616                    r.dump(pw, "    ");
12617                    if (r.persistent) {
12618                        numPers++;
12619                    }
12620                }
12621            }
12622        }
12623
12624        if (mIsolatedProcesses.size() > 0) {
12625            boolean printed = false;
12626            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12627                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12628                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12629                    continue;
12630                }
12631                if (!printed) {
12632                    if (needSep) {
12633                        pw.println();
12634                    }
12635                    pw.println("  Isolated process list (sorted by uid):");
12636                    printedAnything = true;
12637                    printed = true;
12638                    needSep = true;
12639                }
12640                pw.println(String.format("%sIsolated #%2d: %s",
12641                        "    ", i, r.toString()));
12642            }
12643        }
12644
12645        if (mLruProcesses.size() > 0) {
12646            if (needSep) {
12647                pw.println();
12648            }
12649            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12650                    pw.print(" total, non-act at ");
12651                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12652                    pw.print(", non-svc at ");
12653                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12654                    pw.println("):");
12655            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12656            needSep = true;
12657            printedAnything = true;
12658        }
12659
12660        if (dumpAll || dumpPackage != null) {
12661            synchronized (mPidsSelfLocked) {
12662                boolean printed = false;
12663                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12664                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12665                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12666                        continue;
12667                    }
12668                    if (!printed) {
12669                        if (needSep) pw.println();
12670                        needSep = true;
12671                        pw.println("  PID mappings:");
12672                        printed = true;
12673                        printedAnything = true;
12674                    }
12675                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12676                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12677                }
12678            }
12679        }
12680
12681        if (mForegroundProcesses.size() > 0) {
12682            synchronized (mPidsSelfLocked) {
12683                boolean printed = false;
12684                for (int i=0; i<mForegroundProcesses.size(); i++) {
12685                    ProcessRecord r = mPidsSelfLocked.get(
12686                            mForegroundProcesses.valueAt(i).pid);
12687                    if (dumpPackage != null && (r == null
12688                            || !r.pkgList.containsKey(dumpPackage))) {
12689                        continue;
12690                    }
12691                    if (!printed) {
12692                        if (needSep) pw.println();
12693                        needSep = true;
12694                        pw.println("  Foreground Processes:");
12695                        printed = true;
12696                        printedAnything = true;
12697                    }
12698                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12699                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12700                }
12701            }
12702        }
12703
12704        if (mPersistentStartingProcesses.size() > 0) {
12705            if (needSep) pw.println();
12706            needSep = true;
12707            printedAnything = true;
12708            pw.println("  Persisent processes that are starting:");
12709            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12710                    "Starting Norm", "Restarting PERS", dumpPackage);
12711        }
12712
12713        if (mRemovedProcesses.size() > 0) {
12714            if (needSep) pw.println();
12715            needSep = true;
12716            printedAnything = true;
12717            pw.println("  Processes that are being removed:");
12718            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12719                    "Removed Norm", "Removed PERS", dumpPackage);
12720        }
12721
12722        if (mProcessesOnHold.size() > 0) {
12723            if (needSep) pw.println();
12724            needSep = true;
12725            printedAnything = true;
12726            pw.println("  Processes that are on old until the system is ready:");
12727            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12728                    "OnHold Norm", "OnHold PERS", dumpPackage);
12729        }
12730
12731        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12732
12733        if (mProcessCrashTimes.getMap().size() > 0) {
12734            boolean printed = false;
12735            long now = SystemClock.uptimeMillis();
12736            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12737            final int NP = pmap.size();
12738            for (int ip=0; ip<NP; ip++) {
12739                String pname = pmap.keyAt(ip);
12740                SparseArray<Long> uids = pmap.valueAt(ip);
12741                final int N = uids.size();
12742                for (int i=0; i<N; i++) {
12743                    int puid = uids.keyAt(i);
12744                    ProcessRecord r = mProcessNames.get(pname, puid);
12745                    if (dumpPackage != null && (r == null
12746                            || !r.pkgList.containsKey(dumpPackage))) {
12747                        continue;
12748                    }
12749                    if (!printed) {
12750                        if (needSep) pw.println();
12751                        needSep = true;
12752                        pw.println("  Time since processes crashed:");
12753                        printed = true;
12754                        printedAnything = true;
12755                    }
12756                    pw.print("    Process "); pw.print(pname);
12757                            pw.print(" uid "); pw.print(puid);
12758                            pw.print(": last crashed ");
12759                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12760                            pw.println(" ago");
12761                }
12762            }
12763        }
12764
12765        if (mBadProcesses.getMap().size() > 0) {
12766            boolean printed = false;
12767            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12768            final int NP = pmap.size();
12769            for (int ip=0; ip<NP; ip++) {
12770                String pname = pmap.keyAt(ip);
12771                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12772                final int N = uids.size();
12773                for (int i=0; i<N; i++) {
12774                    int puid = uids.keyAt(i);
12775                    ProcessRecord r = mProcessNames.get(pname, puid);
12776                    if (dumpPackage != null && (r == null
12777                            || !r.pkgList.containsKey(dumpPackage))) {
12778                        continue;
12779                    }
12780                    if (!printed) {
12781                        if (needSep) pw.println();
12782                        needSep = true;
12783                        pw.println("  Bad processes:");
12784                        printedAnything = true;
12785                    }
12786                    BadProcessInfo info = uids.valueAt(i);
12787                    pw.print("    Bad process "); pw.print(pname);
12788                            pw.print(" uid "); pw.print(puid);
12789                            pw.print(": crashed at time "); pw.println(info.time);
12790                    if (info.shortMsg != null) {
12791                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12792                    }
12793                    if (info.longMsg != null) {
12794                        pw.print("      Long msg: "); pw.println(info.longMsg);
12795                    }
12796                    if (info.stack != null) {
12797                        pw.println("      Stack:");
12798                        int lastPos = 0;
12799                        for (int pos=0; pos<info.stack.length(); pos++) {
12800                            if (info.stack.charAt(pos) == '\n') {
12801                                pw.print("        ");
12802                                pw.write(info.stack, lastPos, pos-lastPos);
12803                                pw.println();
12804                                lastPos = pos+1;
12805                            }
12806                        }
12807                        if (lastPos < info.stack.length()) {
12808                            pw.print("        ");
12809                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12810                            pw.println();
12811                        }
12812                    }
12813                }
12814            }
12815        }
12816
12817        if (dumpPackage == null) {
12818            pw.println();
12819            needSep = false;
12820            pw.println("  mStartedUsers:");
12821            for (int i=0; i<mStartedUsers.size(); i++) {
12822                UserStartedState uss = mStartedUsers.valueAt(i);
12823                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12824                        pw.print(": "); uss.dump("", pw);
12825            }
12826            pw.print("  mStartedUserArray: [");
12827            for (int i=0; i<mStartedUserArray.length; i++) {
12828                if (i > 0) pw.print(", ");
12829                pw.print(mStartedUserArray[i]);
12830            }
12831            pw.println("]");
12832            pw.print("  mUserLru: [");
12833            for (int i=0; i<mUserLru.size(); i++) {
12834                if (i > 0) pw.print(", ");
12835                pw.print(mUserLru.get(i));
12836            }
12837            pw.println("]");
12838            if (dumpAll) {
12839                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12840            }
12841            synchronized (mUserProfileGroupIdsSelfLocked) {
12842                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12843                    pw.println("  mUserProfileGroupIds:");
12844                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12845                        pw.print("    User #");
12846                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12847                        pw.print(" -> profile #");
12848                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12849                    }
12850                }
12851            }
12852        }
12853        if (mHomeProcess != null && (dumpPackage == null
12854                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12855            if (needSep) {
12856                pw.println();
12857                needSep = false;
12858            }
12859            pw.println("  mHomeProcess: " + mHomeProcess);
12860        }
12861        if (mPreviousProcess != null && (dumpPackage == null
12862                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12863            if (needSep) {
12864                pw.println();
12865                needSep = false;
12866            }
12867            pw.println("  mPreviousProcess: " + mPreviousProcess);
12868        }
12869        if (dumpAll) {
12870            StringBuilder sb = new StringBuilder(128);
12871            sb.append("  mPreviousProcessVisibleTime: ");
12872            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12873            pw.println(sb);
12874        }
12875        if (mHeavyWeightProcess != null && (dumpPackage == null
12876                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12877            if (needSep) {
12878                pw.println();
12879                needSep = false;
12880            }
12881            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12882        }
12883        if (dumpPackage == null) {
12884            pw.println("  mConfiguration: " + mConfiguration);
12885        }
12886        if (dumpAll) {
12887            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12888            if (mCompatModePackages.getPackages().size() > 0) {
12889                boolean printed = false;
12890                for (Map.Entry<String, Integer> entry
12891                        : mCompatModePackages.getPackages().entrySet()) {
12892                    String pkg = entry.getKey();
12893                    int mode = entry.getValue();
12894                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12895                        continue;
12896                    }
12897                    if (!printed) {
12898                        pw.println("  mScreenCompatPackages:");
12899                        printed = true;
12900                    }
12901                    pw.print("    "); pw.print(pkg); pw.print(": ");
12902                            pw.print(mode); pw.println();
12903                }
12904            }
12905        }
12906        if (dumpPackage == null) {
12907            pw.println("  mWakefulness="
12908                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12909            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12910                    + lockScreenShownToString());
12911            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12912                    + " mTestPssMode=" + mTestPssMode);
12913        }
12914        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12915                || mOrigWaitForDebugger) {
12916            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12917                    || dumpPackage.equals(mOrigDebugApp)) {
12918                if (needSep) {
12919                    pw.println();
12920                    needSep = false;
12921                }
12922                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12923                        + " mDebugTransient=" + mDebugTransient
12924                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12925            }
12926        }
12927        if (mOpenGlTraceApp != null) {
12928            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12929                if (needSep) {
12930                    pw.println();
12931                    needSep = false;
12932                }
12933                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12934            }
12935        }
12936        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12937                || mProfileFd != null) {
12938            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12939                if (needSep) {
12940                    pw.println();
12941                    needSep = false;
12942                }
12943                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12944                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12945                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12946                        + mAutoStopProfiler);
12947                pw.println("  mProfileType=" + mProfileType);
12948            }
12949        }
12950        if (dumpPackage == null) {
12951            if (mAlwaysFinishActivities || mController != null) {
12952                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12953                        + " mController=" + mController);
12954            }
12955            if (dumpAll) {
12956                pw.println("  Total persistent processes: " + numPers);
12957                pw.println("  mProcessesReady=" + mProcessesReady
12958                        + " mSystemReady=" + mSystemReady
12959                        + " mBooted=" + mBooted
12960                        + " mFactoryTest=" + mFactoryTest);
12961                pw.println("  mBooting=" + mBooting
12962                        + " mCallFinishBooting=" + mCallFinishBooting
12963                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12964                pw.print("  mLastPowerCheckRealtime=");
12965                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12966                        pw.println("");
12967                pw.print("  mLastPowerCheckUptime=");
12968                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12969                        pw.println("");
12970                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12971                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12972                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12973                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12974                        + " (" + mLruProcesses.size() + " total)"
12975                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12976                        + " mNumServiceProcs=" + mNumServiceProcs
12977                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12978                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12979                        + " mLastMemoryLevel" + mLastMemoryLevel
12980                        + " mLastNumProcesses" + mLastNumProcesses);
12981                long now = SystemClock.uptimeMillis();
12982                pw.print("  mLastIdleTime=");
12983                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12984                        pw.print(" mLowRamSinceLastIdle=");
12985                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12986                        pw.println();
12987            }
12988        }
12989
12990        if (!printedAnything) {
12991            pw.println("  (nothing)");
12992        }
12993    }
12994
12995    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12996            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12997        if (mProcessesToGc.size() > 0) {
12998            boolean printed = false;
12999            long now = SystemClock.uptimeMillis();
13000            for (int i=0; i<mProcessesToGc.size(); i++) {
13001                ProcessRecord proc = mProcessesToGc.get(i);
13002                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13003                    continue;
13004                }
13005                if (!printed) {
13006                    if (needSep) pw.println();
13007                    needSep = true;
13008                    pw.println("  Processes that are waiting to GC:");
13009                    printed = true;
13010                }
13011                pw.print("    Process "); pw.println(proc);
13012                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13013                        pw.print(", last gced=");
13014                        pw.print(now-proc.lastRequestedGc);
13015                        pw.print(" ms ago, last lowMem=");
13016                        pw.print(now-proc.lastLowMemory);
13017                        pw.println(" ms ago");
13018
13019            }
13020        }
13021        return needSep;
13022    }
13023
13024    void printOomLevel(PrintWriter pw, String name, int adj) {
13025        pw.print("    ");
13026        if (adj >= 0) {
13027            pw.print(' ');
13028            if (adj < 10) pw.print(' ');
13029        } else {
13030            if (adj > -10) pw.print(' ');
13031        }
13032        pw.print(adj);
13033        pw.print(": ");
13034        pw.print(name);
13035        pw.print(" (");
13036        pw.print(mProcessList.getMemLevel(adj)/1024);
13037        pw.println(" kB)");
13038    }
13039
13040    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13041            int opti, boolean dumpAll) {
13042        boolean needSep = false;
13043
13044        if (mLruProcesses.size() > 0) {
13045            if (needSep) pw.println();
13046            needSep = true;
13047            pw.println("  OOM levels:");
13048            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13049            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13050            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13051            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13052            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13053            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13054            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13055            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13056            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13057            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13058            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13059            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13060            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13061            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13062
13063            if (needSep) pw.println();
13064            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13065                    pw.print(" total, non-act at ");
13066                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13067                    pw.print(", non-svc at ");
13068                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13069                    pw.println("):");
13070            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13071            needSep = true;
13072        }
13073
13074        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13075
13076        pw.println();
13077        pw.println("  mHomeProcess: " + mHomeProcess);
13078        pw.println("  mPreviousProcess: " + mPreviousProcess);
13079        if (mHeavyWeightProcess != null) {
13080            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13081        }
13082
13083        return true;
13084    }
13085
13086    /**
13087     * There are three ways to call this:
13088     *  - no provider specified: dump all the providers
13089     *  - a flattened component name that matched an existing provider was specified as the
13090     *    first arg: dump that one provider
13091     *  - the first arg isn't the flattened component name of an existing provider:
13092     *    dump all providers whose component contains the first arg as a substring
13093     */
13094    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13095            int opti, boolean dumpAll) {
13096        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13097    }
13098
13099    static class ItemMatcher {
13100        ArrayList<ComponentName> components;
13101        ArrayList<String> strings;
13102        ArrayList<Integer> objects;
13103        boolean all;
13104
13105        ItemMatcher() {
13106            all = true;
13107        }
13108
13109        void build(String name) {
13110            ComponentName componentName = ComponentName.unflattenFromString(name);
13111            if (componentName != null) {
13112                if (components == null) {
13113                    components = new ArrayList<ComponentName>();
13114                }
13115                components.add(componentName);
13116                all = false;
13117            } else {
13118                int objectId = 0;
13119                // Not a '/' separated full component name; maybe an object ID?
13120                try {
13121                    objectId = Integer.parseInt(name, 16);
13122                    if (objects == null) {
13123                        objects = new ArrayList<Integer>();
13124                    }
13125                    objects.add(objectId);
13126                    all = false;
13127                } catch (RuntimeException e) {
13128                    // Not an integer; just do string match.
13129                    if (strings == null) {
13130                        strings = new ArrayList<String>();
13131                    }
13132                    strings.add(name);
13133                    all = false;
13134                }
13135            }
13136        }
13137
13138        int build(String[] args, int opti) {
13139            for (; opti<args.length; opti++) {
13140                String name = args[opti];
13141                if ("--".equals(name)) {
13142                    return opti+1;
13143                }
13144                build(name);
13145            }
13146            return opti;
13147        }
13148
13149        boolean match(Object object, ComponentName comp) {
13150            if (all) {
13151                return true;
13152            }
13153            if (components != null) {
13154                for (int i=0; i<components.size(); i++) {
13155                    if (components.get(i).equals(comp)) {
13156                        return true;
13157                    }
13158                }
13159            }
13160            if (objects != null) {
13161                for (int i=0; i<objects.size(); i++) {
13162                    if (System.identityHashCode(object) == objects.get(i)) {
13163                        return true;
13164                    }
13165                }
13166            }
13167            if (strings != null) {
13168                String flat = comp.flattenToString();
13169                for (int i=0; i<strings.size(); i++) {
13170                    if (flat.contains(strings.get(i))) {
13171                        return true;
13172                    }
13173                }
13174            }
13175            return false;
13176        }
13177    }
13178
13179    /**
13180     * There are three things that cmd can be:
13181     *  - a flattened component name that matches an existing activity
13182     *  - the cmd arg isn't the flattened component name of an existing activity:
13183     *    dump all activity whose component contains the cmd as a substring
13184     *  - A hex number of the ActivityRecord object instance.
13185     */
13186    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13187            int opti, boolean dumpAll) {
13188        ArrayList<ActivityRecord> activities;
13189
13190        synchronized (this) {
13191            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13192        }
13193
13194        if (activities.size() <= 0) {
13195            return false;
13196        }
13197
13198        String[] newArgs = new String[args.length - opti];
13199        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13200
13201        TaskRecord lastTask = null;
13202        boolean needSep = false;
13203        for (int i=activities.size()-1; i>=0; i--) {
13204            ActivityRecord r = activities.get(i);
13205            if (needSep) {
13206                pw.println();
13207            }
13208            needSep = true;
13209            synchronized (this) {
13210                if (lastTask != r.task) {
13211                    lastTask = r.task;
13212                    pw.print("TASK "); pw.print(lastTask.affinity);
13213                            pw.print(" id="); pw.println(lastTask.taskId);
13214                    if (dumpAll) {
13215                        lastTask.dump(pw, "  ");
13216                    }
13217                }
13218            }
13219            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13220        }
13221        return true;
13222    }
13223
13224    /**
13225     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13226     * there is a thread associated with the activity.
13227     */
13228    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13229            final ActivityRecord r, String[] args, boolean dumpAll) {
13230        String innerPrefix = prefix + "  ";
13231        synchronized (this) {
13232            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13233                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13234                    pw.print(" pid=");
13235                    if (r.app != null) pw.println(r.app.pid);
13236                    else pw.println("(not running)");
13237            if (dumpAll) {
13238                r.dump(pw, innerPrefix);
13239            }
13240        }
13241        if (r.app != null && r.app.thread != null) {
13242            // flush anything that is already in the PrintWriter since the thread is going
13243            // to write to the file descriptor directly
13244            pw.flush();
13245            try {
13246                TransferPipe tp = new TransferPipe();
13247                try {
13248                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13249                            r.appToken, innerPrefix, args);
13250                    tp.go(fd);
13251                } finally {
13252                    tp.kill();
13253                }
13254            } catch (IOException e) {
13255                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13256            } catch (RemoteException e) {
13257                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13258            }
13259        }
13260    }
13261
13262    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13263            int opti, boolean dumpAll, String dumpPackage) {
13264        boolean needSep = false;
13265        boolean onlyHistory = false;
13266        boolean printedAnything = false;
13267
13268        if ("history".equals(dumpPackage)) {
13269            if (opti < args.length && "-s".equals(args[opti])) {
13270                dumpAll = false;
13271            }
13272            onlyHistory = true;
13273            dumpPackage = null;
13274        }
13275
13276        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13277        if (!onlyHistory && dumpAll) {
13278            if (mRegisteredReceivers.size() > 0) {
13279                boolean printed = false;
13280                Iterator it = mRegisteredReceivers.values().iterator();
13281                while (it.hasNext()) {
13282                    ReceiverList r = (ReceiverList)it.next();
13283                    if (dumpPackage != null && (r.app == null ||
13284                            !dumpPackage.equals(r.app.info.packageName))) {
13285                        continue;
13286                    }
13287                    if (!printed) {
13288                        pw.println("  Registered Receivers:");
13289                        needSep = true;
13290                        printed = true;
13291                        printedAnything = true;
13292                    }
13293                    pw.print("  * "); pw.println(r);
13294                    r.dump(pw, "    ");
13295                }
13296            }
13297
13298            if (mReceiverResolver.dump(pw, needSep ?
13299                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13300                    "    ", dumpPackage, false, false)) {
13301                needSep = true;
13302                printedAnything = true;
13303            }
13304        }
13305
13306        for (BroadcastQueue q : mBroadcastQueues) {
13307            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13308            printedAnything |= needSep;
13309        }
13310
13311        needSep = true;
13312
13313        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13314            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13315                if (needSep) {
13316                    pw.println();
13317                }
13318                needSep = true;
13319                printedAnything = true;
13320                pw.print("  Sticky broadcasts for user ");
13321                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13322                StringBuilder sb = new StringBuilder(128);
13323                for (Map.Entry<String, ArrayList<Intent>> ent
13324                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13325                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13326                    if (dumpAll) {
13327                        pw.println(":");
13328                        ArrayList<Intent> intents = ent.getValue();
13329                        final int N = intents.size();
13330                        for (int i=0; i<N; i++) {
13331                            sb.setLength(0);
13332                            sb.append("    Intent: ");
13333                            intents.get(i).toShortString(sb, false, true, false, false);
13334                            pw.println(sb.toString());
13335                            Bundle bundle = intents.get(i).getExtras();
13336                            if (bundle != null) {
13337                                pw.print("      ");
13338                                pw.println(bundle.toString());
13339                            }
13340                        }
13341                    } else {
13342                        pw.println("");
13343                    }
13344                }
13345            }
13346        }
13347
13348        if (!onlyHistory && dumpAll) {
13349            pw.println();
13350            for (BroadcastQueue queue : mBroadcastQueues) {
13351                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13352                        + queue.mBroadcastsScheduled);
13353            }
13354            pw.println("  mHandler:");
13355            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13356            needSep = true;
13357            printedAnything = true;
13358        }
13359
13360        if (!printedAnything) {
13361            pw.println("  (nothing)");
13362        }
13363    }
13364
13365    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13366            int opti, boolean dumpAll, String dumpPackage) {
13367        boolean needSep;
13368        boolean printedAnything = false;
13369
13370        ItemMatcher matcher = new ItemMatcher();
13371        matcher.build(args, opti);
13372
13373        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13374
13375        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13376        printedAnything |= needSep;
13377
13378        if (mLaunchingProviders.size() > 0) {
13379            boolean printed = false;
13380            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13381                ContentProviderRecord r = mLaunchingProviders.get(i);
13382                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13383                    continue;
13384                }
13385                if (!printed) {
13386                    if (needSep) pw.println();
13387                    needSep = true;
13388                    pw.println("  Launching content providers:");
13389                    printed = true;
13390                    printedAnything = true;
13391                }
13392                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13393                        pw.println(r);
13394            }
13395        }
13396
13397        if (mGrantedUriPermissions.size() > 0) {
13398            boolean printed = false;
13399            int dumpUid = -2;
13400            if (dumpPackage != null) {
13401                try {
13402                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13403                } catch (NameNotFoundException e) {
13404                    dumpUid = -1;
13405                }
13406            }
13407            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13408                int uid = mGrantedUriPermissions.keyAt(i);
13409                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13410                    continue;
13411                }
13412                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13413                if (!printed) {
13414                    if (needSep) pw.println();
13415                    needSep = true;
13416                    pw.println("  Granted Uri Permissions:");
13417                    printed = true;
13418                    printedAnything = true;
13419                }
13420                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13421                for (UriPermission perm : perms.values()) {
13422                    pw.print("    "); pw.println(perm);
13423                    if (dumpAll) {
13424                        perm.dump(pw, "      ");
13425                    }
13426                }
13427            }
13428        }
13429
13430        if (!printedAnything) {
13431            pw.println("  (nothing)");
13432        }
13433    }
13434
13435    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13436            int opti, boolean dumpAll, String dumpPackage) {
13437        boolean printed = false;
13438
13439        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13440
13441        if (mIntentSenderRecords.size() > 0) {
13442            Iterator<WeakReference<PendingIntentRecord>> it
13443                    = mIntentSenderRecords.values().iterator();
13444            while (it.hasNext()) {
13445                WeakReference<PendingIntentRecord> ref = it.next();
13446                PendingIntentRecord rec = ref != null ? ref.get(): null;
13447                if (dumpPackage != null && (rec == null
13448                        || !dumpPackage.equals(rec.key.packageName))) {
13449                    continue;
13450                }
13451                printed = true;
13452                if (rec != null) {
13453                    pw.print("  * "); pw.println(rec);
13454                    if (dumpAll) {
13455                        rec.dump(pw, "    ");
13456                    }
13457                } else {
13458                    pw.print("  * "); pw.println(ref);
13459                }
13460            }
13461        }
13462
13463        if (!printed) {
13464            pw.println("  (nothing)");
13465        }
13466    }
13467
13468    private static final int dumpProcessList(PrintWriter pw,
13469            ActivityManagerService service, List list,
13470            String prefix, String normalLabel, String persistentLabel,
13471            String dumpPackage) {
13472        int numPers = 0;
13473        final int N = list.size()-1;
13474        for (int i=N; i>=0; i--) {
13475            ProcessRecord r = (ProcessRecord)list.get(i);
13476            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13477                continue;
13478            }
13479            pw.println(String.format("%s%s #%2d: %s",
13480                    prefix, (r.persistent ? persistentLabel : normalLabel),
13481                    i, r.toString()));
13482            if (r.persistent) {
13483                numPers++;
13484            }
13485        }
13486        return numPers;
13487    }
13488
13489    private static final boolean dumpProcessOomList(PrintWriter pw,
13490            ActivityManagerService service, List<ProcessRecord> origList,
13491            String prefix, String normalLabel, String persistentLabel,
13492            boolean inclDetails, String dumpPackage) {
13493
13494        ArrayList<Pair<ProcessRecord, Integer>> list
13495                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13496        for (int i=0; i<origList.size(); i++) {
13497            ProcessRecord r = origList.get(i);
13498            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13499                continue;
13500            }
13501            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13502        }
13503
13504        if (list.size() <= 0) {
13505            return false;
13506        }
13507
13508        Comparator<Pair<ProcessRecord, Integer>> comparator
13509                = new Comparator<Pair<ProcessRecord, Integer>>() {
13510            @Override
13511            public int compare(Pair<ProcessRecord, Integer> object1,
13512                    Pair<ProcessRecord, Integer> object2) {
13513                if (object1.first.setAdj != object2.first.setAdj) {
13514                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13515                }
13516                if (object1.second.intValue() != object2.second.intValue()) {
13517                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13518                }
13519                return 0;
13520            }
13521        };
13522
13523        Collections.sort(list, comparator);
13524
13525        final long curRealtime = SystemClock.elapsedRealtime();
13526        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13527        final long curUptime = SystemClock.uptimeMillis();
13528        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13529
13530        for (int i=list.size()-1; i>=0; i--) {
13531            ProcessRecord r = list.get(i).first;
13532            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13533            char schedGroup;
13534            switch (r.setSchedGroup) {
13535                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13536                    schedGroup = 'B';
13537                    break;
13538                case Process.THREAD_GROUP_DEFAULT:
13539                    schedGroup = 'F';
13540                    break;
13541                default:
13542                    schedGroup = '?';
13543                    break;
13544            }
13545            char foreground;
13546            if (r.foregroundActivities) {
13547                foreground = 'A';
13548            } else if (r.foregroundServices) {
13549                foreground = 'S';
13550            } else {
13551                foreground = ' ';
13552            }
13553            String procState = ProcessList.makeProcStateString(r.curProcState);
13554            pw.print(prefix);
13555            pw.print(r.persistent ? persistentLabel : normalLabel);
13556            pw.print(" #");
13557            int num = (origList.size()-1)-list.get(i).second;
13558            if (num < 10) pw.print(' ');
13559            pw.print(num);
13560            pw.print(": ");
13561            pw.print(oomAdj);
13562            pw.print(' ');
13563            pw.print(schedGroup);
13564            pw.print('/');
13565            pw.print(foreground);
13566            pw.print('/');
13567            pw.print(procState);
13568            pw.print(" trm:");
13569            if (r.trimMemoryLevel < 10) pw.print(' ');
13570            pw.print(r.trimMemoryLevel);
13571            pw.print(' ');
13572            pw.print(r.toShortString());
13573            pw.print(" (");
13574            pw.print(r.adjType);
13575            pw.println(')');
13576            if (r.adjSource != null || r.adjTarget != null) {
13577                pw.print(prefix);
13578                pw.print("    ");
13579                if (r.adjTarget instanceof ComponentName) {
13580                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13581                } else if (r.adjTarget != null) {
13582                    pw.print(r.adjTarget.toString());
13583                } else {
13584                    pw.print("{null}");
13585                }
13586                pw.print("<=");
13587                if (r.adjSource instanceof ProcessRecord) {
13588                    pw.print("Proc{");
13589                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13590                    pw.println("}");
13591                } else if (r.adjSource != null) {
13592                    pw.println(r.adjSource.toString());
13593                } else {
13594                    pw.println("{null}");
13595                }
13596            }
13597            if (inclDetails) {
13598                pw.print(prefix);
13599                pw.print("    ");
13600                pw.print("oom: max="); pw.print(r.maxAdj);
13601                pw.print(" curRaw="); pw.print(r.curRawAdj);
13602                pw.print(" setRaw="); pw.print(r.setRawAdj);
13603                pw.print(" cur="); pw.print(r.curAdj);
13604                pw.print(" set="); pw.println(r.setAdj);
13605                pw.print(prefix);
13606                pw.print("    ");
13607                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13608                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13609                pw.print(" lastPss="); pw.print(r.lastPss);
13610                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13611                pw.print(prefix);
13612                pw.print("    ");
13613                pw.print("cached="); pw.print(r.cached);
13614                pw.print(" empty="); pw.print(r.empty);
13615                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13616
13617                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13618                    if (r.lastWakeTime != 0) {
13619                        long wtime;
13620                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13621                        synchronized (stats) {
13622                            wtime = stats.getProcessWakeTime(r.info.uid,
13623                                    r.pid, curRealtime);
13624                        }
13625                        long timeUsed = wtime - r.lastWakeTime;
13626                        pw.print(prefix);
13627                        pw.print("    ");
13628                        pw.print("keep awake over ");
13629                        TimeUtils.formatDuration(realtimeSince, pw);
13630                        pw.print(" used ");
13631                        TimeUtils.formatDuration(timeUsed, pw);
13632                        pw.print(" (");
13633                        pw.print((timeUsed*100)/realtimeSince);
13634                        pw.println("%)");
13635                    }
13636                    if (r.lastCpuTime != 0) {
13637                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13638                        pw.print(prefix);
13639                        pw.print("    ");
13640                        pw.print("run cpu over ");
13641                        TimeUtils.formatDuration(uptimeSince, pw);
13642                        pw.print(" used ");
13643                        TimeUtils.formatDuration(timeUsed, pw);
13644                        pw.print(" (");
13645                        pw.print((timeUsed*100)/uptimeSince);
13646                        pw.println("%)");
13647                    }
13648                }
13649            }
13650        }
13651        return true;
13652    }
13653
13654    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13655            String[] args) {
13656        ArrayList<ProcessRecord> procs;
13657        synchronized (this) {
13658            if (args != null && args.length > start
13659                    && args[start].charAt(0) != '-') {
13660                procs = new ArrayList<ProcessRecord>();
13661                int pid = -1;
13662                try {
13663                    pid = Integer.parseInt(args[start]);
13664                } catch (NumberFormatException e) {
13665                }
13666                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13667                    ProcessRecord proc = mLruProcesses.get(i);
13668                    if (proc.pid == pid) {
13669                        procs.add(proc);
13670                    } else if (allPkgs && proc.pkgList != null
13671                            && proc.pkgList.containsKey(args[start])) {
13672                        procs.add(proc);
13673                    } else if (proc.processName.equals(args[start])) {
13674                        procs.add(proc);
13675                    }
13676                }
13677                if (procs.size() <= 0) {
13678                    return null;
13679                }
13680            } else {
13681                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13682            }
13683        }
13684        return procs;
13685    }
13686
13687    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13688            PrintWriter pw, String[] args) {
13689        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13690        if (procs == null) {
13691            pw.println("No process found for: " + args[0]);
13692            return;
13693        }
13694
13695        long uptime = SystemClock.uptimeMillis();
13696        long realtime = SystemClock.elapsedRealtime();
13697        pw.println("Applications Graphics Acceleration Info:");
13698        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13699
13700        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13701            ProcessRecord r = procs.get(i);
13702            if (r.thread != null) {
13703                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13704                pw.flush();
13705                try {
13706                    TransferPipe tp = new TransferPipe();
13707                    try {
13708                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13709                        tp.go(fd);
13710                    } finally {
13711                        tp.kill();
13712                    }
13713                } catch (IOException e) {
13714                    pw.println("Failure while dumping the app: " + r);
13715                    pw.flush();
13716                } catch (RemoteException e) {
13717                    pw.println("Got a RemoteException while dumping the app " + r);
13718                    pw.flush();
13719                }
13720            }
13721        }
13722    }
13723
13724    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13725        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13726        if (procs == null) {
13727            pw.println("No process found for: " + args[0]);
13728            return;
13729        }
13730
13731        pw.println("Applications Database Info:");
13732
13733        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13734            ProcessRecord r = procs.get(i);
13735            if (r.thread != null) {
13736                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13737                pw.flush();
13738                try {
13739                    TransferPipe tp = new TransferPipe();
13740                    try {
13741                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13742                        tp.go(fd);
13743                    } finally {
13744                        tp.kill();
13745                    }
13746                } catch (IOException e) {
13747                    pw.println("Failure while dumping the app: " + r);
13748                    pw.flush();
13749                } catch (RemoteException e) {
13750                    pw.println("Got a RemoteException while dumping the app " + r);
13751                    pw.flush();
13752                }
13753            }
13754        }
13755    }
13756
13757    final static class MemItem {
13758        final boolean isProc;
13759        final String label;
13760        final String shortLabel;
13761        final long pss;
13762        final int id;
13763        final boolean hasActivities;
13764        ArrayList<MemItem> subitems;
13765
13766        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13767                boolean _hasActivities) {
13768            isProc = true;
13769            label = _label;
13770            shortLabel = _shortLabel;
13771            pss = _pss;
13772            id = _id;
13773            hasActivities = _hasActivities;
13774        }
13775
13776        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13777            isProc = false;
13778            label = _label;
13779            shortLabel = _shortLabel;
13780            pss = _pss;
13781            id = _id;
13782            hasActivities = false;
13783        }
13784    }
13785
13786    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13787            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13788        if (sort && !isCompact) {
13789            Collections.sort(items, new Comparator<MemItem>() {
13790                @Override
13791                public int compare(MemItem lhs, MemItem rhs) {
13792                    if (lhs.pss < rhs.pss) {
13793                        return 1;
13794                    } else if (lhs.pss > rhs.pss) {
13795                        return -1;
13796                    }
13797                    return 0;
13798                }
13799            });
13800        }
13801
13802        for (int i=0; i<items.size(); i++) {
13803            MemItem mi = items.get(i);
13804            if (!isCompact) {
13805                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13806            } else if (mi.isProc) {
13807                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13808                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13809                pw.println(mi.hasActivities ? ",a" : ",e");
13810            } else {
13811                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13812                pw.println(mi.pss);
13813            }
13814            if (mi.subitems != null) {
13815                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13816                        true, isCompact);
13817            }
13818        }
13819    }
13820
13821    // These are in KB.
13822    static final long[] DUMP_MEM_BUCKETS = new long[] {
13823        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13824        120*1024, 160*1024, 200*1024,
13825        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13826        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13827    };
13828
13829    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13830            boolean stackLike) {
13831        int start = label.lastIndexOf('.');
13832        if (start >= 0) start++;
13833        else start = 0;
13834        int end = label.length();
13835        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13836            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13837                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13838                out.append(bucket);
13839                out.append(stackLike ? "MB." : "MB ");
13840                out.append(label, start, end);
13841                return;
13842            }
13843        }
13844        out.append(memKB/1024);
13845        out.append(stackLike ? "MB." : "MB ");
13846        out.append(label, start, end);
13847    }
13848
13849    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13850            ProcessList.NATIVE_ADJ,
13851            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13852            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13853            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13854            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13855            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13856            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13857    };
13858    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13859            "Native",
13860            "System", "Persistent", "Persistent Service", "Foreground",
13861            "Visible", "Perceptible",
13862            "Heavy Weight", "Backup",
13863            "A Services", "Home",
13864            "Previous", "B Services", "Cached"
13865    };
13866    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13867            "native",
13868            "sys", "pers", "persvc", "fore",
13869            "vis", "percept",
13870            "heavy", "backup",
13871            "servicea", "home",
13872            "prev", "serviceb", "cached"
13873    };
13874
13875    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13876            long realtime, boolean isCheckinRequest, boolean isCompact) {
13877        if (isCheckinRequest || isCompact) {
13878            // short checkin version
13879            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13880        } else {
13881            pw.println("Applications Memory Usage (kB):");
13882            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13883        }
13884    }
13885
13886    private static final int KSM_SHARED = 0;
13887    private static final int KSM_SHARING = 1;
13888    private static final int KSM_UNSHARED = 2;
13889    private static final int KSM_VOLATILE = 3;
13890
13891    private final long[] getKsmInfo() {
13892        long[] longOut = new long[4];
13893        final int[] SINGLE_LONG_FORMAT = new int[] {
13894            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13895        };
13896        long[] longTmp = new long[1];
13897        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13898                SINGLE_LONG_FORMAT, null, longTmp, null);
13899        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13900        longTmp[0] = 0;
13901        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13902                SINGLE_LONG_FORMAT, null, longTmp, null);
13903        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13904        longTmp[0] = 0;
13905        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13906                SINGLE_LONG_FORMAT, null, longTmp, null);
13907        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13908        longTmp[0] = 0;
13909        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13910                SINGLE_LONG_FORMAT, null, longTmp, null);
13911        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13912        return longOut;
13913    }
13914
13915    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13916            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13917        boolean dumpDetails = false;
13918        boolean dumpFullDetails = false;
13919        boolean dumpDalvik = false;
13920        boolean oomOnly = false;
13921        boolean isCompact = false;
13922        boolean localOnly = false;
13923        boolean packages = false;
13924
13925        int opti = 0;
13926        while (opti < args.length) {
13927            String opt = args[opti];
13928            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13929                break;
13930            }
13931            opti++;
13932            if ("-a".equals(opt)) {
13933                dumpDetails = true;
13934                dumpFullDetails = true;
13935                dumpDalvik = true;
13936            } else if ("-d".equals(opt)) {
13937                dumpDalvik = true;
13938            } else if ("-c".equals(opt)) {
13939                isCompact = true;
13940            } else if ("--oom".equals(opt)) {
13941                oomOnly = true;
13942            } else if ("--local".equals(opt)) {
13943                localOnly = true;
13944            } else if ("--package".equals(opt)) {
13945                packages = true;
13946            } else if ("-h".equals(opt)) {
13947                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13948                pw.println("  -a: include all available information for each process.");
13949                pw.println("  -d: include dalvik details when dumping process details.");
13950                pw.println("  -c: dump in a compact machine-parseable representation.");
13951                pw.println("  --oom: only show processes organized by oom adj.");
13952                pw.println("  --local: only collect details locally, don't call process.");
13953                pw.println("  --package: interpret process arg as package, dumping all");
13954                pw.println("             processes that have loaded that package.");
13955                pw.println("If [process] is specified it can be the name or ");
13956                pw.println("pid of a specific process to dump.");
13957                return;
13958            } else {
13959                pw.println("Unknown argument: " + opt + "; use -h for help");
13960            }
13961        }
13962
13963        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13964        long uptime = SystemClock.uptimeMillis();
13965        long realtime = SystemClock.elapsedRealtime();
13966        final long[] tmpLong = new long[1];
13967
13968        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13969        if (procs == null) {
13970            // No Java processes.  Maybe they want to print a native process.
13971            if (args != null && args.length > opti
13972                    && args[opti].charAt(0) != '-') {
13973                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13974                        = new ArrayList<ProcessCpuTracker.Stats>();
13975                updateCpuStatsNow();
13976                int findPid = -1;
13977                try {
13978                    findPid = Integer.parseInt(args[opti]);
13979                } catch (NumberFormatException e) {
13980                }
13981                synchronized (mProcessCpuTracker) {
13982                    final int N = mProcessCpuTracker.countStats();
13983                    for (int i=0; i<N; i++) {
13984                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13985                        if (st.pid == findPid || (st.baseName != null
13986                                && st.baseName.equals(args[opti]))) {
13987                            nativeProcs.add(st);
13988                        }
13989                    }
13990                }
13991                if (nativeProcs.size() > 0) {
13992                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13993                            isCompact);
13994                    Debug.MemoryInfo mi = null;
13995                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13996                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13997                        final int pid = r.pid;
13998                        if (!isCheckinRequest && dumpDetails) {
13999                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14000                        }
14001                        if (mi == null) {
14002                            mi = new Debug.MemoryInfo();
14003                        }
14004                        if (dumpDetails || (!brief && !oomOnly)) {
14005                            Debug.getMemoryInfo(pid, mi);
14006                        } else {
14007                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14008                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14009                        }
14010                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14011                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14012                        if (isCheckinRequest) {
14013                            pw.println();
14014                        }
14015                    }
14016                    return;
14017                }
14018            }
14019            pw.println("No process found for: " + args[opti]);
14020            return;
14021        }
14022
14023        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14024            dumpDetails = true;
14025        }
14026
14027        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14028
14029        String[] innerArgs = new String[args.length-opti];
14030        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14031
14032        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14033        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14034        long nativePss = 0;
14035        long dalvikPss = 0;
14036        long otherPss = 0;
14037        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14038
14039        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14040        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14041                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14042
14043        long totalPss = 0;
14044        long cachedPss = 0;
14045
14046        Debug.MemoryInfo mi = null;
14047        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14048            final ProcessRecord r = procs.get(i);
14049            final IApplicationThread thread;
14050            final int pid;
14051            final int oomAdj;
14052            final boolean hasActivities;
14053            synchronized (this) {
14054                thread = r.thread;
14055                pid = r.pid;
14056                oomAdj = r.getSetAdjWithServices();
14057                hasActivities = r.activities.size() > 0;
14058            }
14059            if (thread != null) {
14060                if (!isCheckinRequest && dumpDetails) {
14061                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14062                }
14063                if (mi == null) {
14064                    mi = new Debug.MemoryInfo();
14065                }
14066                if (dumpDetails || (!brief && !oomOnly)) {
14067                    Debug.getMemoryInfo(pid, mi);
14068                } else {
14069                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14070                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14071                }
14072                if (dumpDetails) {
14073                    if (localOnly) {
14074                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14075                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14076                        if (isCheckinRequest) {
14077                            pw.println();
14078                        }
14079                    } else {
14080                        try {
14081                            pw.flush();
14082                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14083                                    dumpDalvik, innerArgs);
14084                        } catch (RemoteException e) {
14085                            if (!isCheckinRequest) {
14086                                pw.println("Got RemoteException!");
14087                                pw.flush();
14088                            }
14089                        }
14090                    }
14091                }
14092
14093                final long myTotalPss = mi.getTotalPss();
14094                final long myTotalUss = mi.getTotalUss();
14095
14096                synchronized (this) {
14097                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14098                        // Record this for posterity if the process has been stable.
14099                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14100                    }
14101                }
14102
14103                if (!isCheckinRequest && mi != null) {
14104                    totalPss += myTotalPss;
14105                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14106                            (hasActivities ? " / activities)" : ")"),
14107                            r.processName, myTotalPss, pid, hasActivities);
14108                    procMems.add(pssItem);
14109                    procMemsMap.put(pid, pssItem);
14110
14111                    nativePss += mi.nativePss;
14112                    dalvikPss += mi.dalvikPss;
14113                    otherPss += mi.otherPss;
14114                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14115                        long mem = mi.getOtherPss(j);
14116                        miscPss[j] += mem;
14117                        otherPss -= mem;
14118                    }
14119
14120                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14121                        cachedPss += myTotalPss;
14122                    }
14123
14124                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14125                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14126                                || oomIndex == (oomPss.length-1)) {
14127                            oomPss[oomIndex] += myTotalPss;
14128                            if (oomProcs[oomIndex] == null) {
14129                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14130                            }
14131                            oomProcs[oomIndex].add(pssItem);
14132                            break;
14133                        }
14134                    }
14135                }
14136            }
14137        }
14138
14139        long nativeProcTotalPss = 0;
14140
14141        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14142            // If we are showing aggregations, also look for native processes to
14143            // include so that our aggregations are more accurate.
14144            updateCpuStatsNow();
14145            mi = null;
14146            synchronized (mProcessCpuTracker) {
14147                final int N = mProcessCpuTracker.countStats();
14148                for (int i=0; i<N; i++) {
14149                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14150                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14151                        if (mi == null) {
14152                            mi = new Debug.MemoryInfo();
14153                        }
14154                        if (!brief && !oomOnly) {
14155                            Debug.getMemoryInfo(st.pid, mi);
14156                        } else {
14157                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14158                            mi.nativePrivateDirty = (int)tmpLong[0];
14159                        }
14160
14161                        final long myTotalPss = mi.getTotalPss();
14162                        totalPss += myTotalPss;
14163                        nativeProcTotalPss += myTotalPss;
14164
14165                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14166                                st.name, myTotalPss, st.pid, false);
14167                        procMems.add(pssItem);
14168
14169                        nativePss += mi.nativePss;
14170                        dalvikPss += mi.dalvikPss;
14171                        otherPss += mi.otherPss;
14172                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14173                            long mem = mi.getOtherPss(j);
14174                            miscPss[j] += mem;
14175                            otherPss -= mem;
14176                        }
14177                        oomPss[0] += myTotalPss;
14178                        if (oomProcs[0] == null) {
14179                            oomProcs[0] = new ArrayList<MemItem>();
14180                        }
14181                        oomProcs[0].add(pssItem);
14182                    }
14183                }
14184            }
14185
14186            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14187
14188            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14189            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14190            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14191            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14192                String label = Debug.MemoryInfo.getOtherLabel(j);
14193                catMems.add(new MemItem(label, label, miscPss[j], j));
14194            }
14195
14196            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14197            for (int j=0; j<oomPss.length; j++) {
14198                if (oomPss[j] != 0) {
14199                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14200                            : DUMP_MEM_OOM_LABEL[j];
14201                    MemItem item = new MemItem(label, label, oomPss[j],
14202                            DUMP_MEM_OOM_ADJ[j]);
14203                    item.subitems = oomProcs[j];
14204                    oomMems.add(item);
14205                }
14206            }
14207
14208            if (!brief && !oomOnly && !isCompact) {
14209                pw.println();
14210                pw.println("Total PSS by process:");
14211                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14212                pw.println();
14213            }
14214            if (!isCompact) {
14215                pw.println("Total PSS by OOM adjustment:");
14216            }
14217            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14218            if (!brief && !oomOnly) {
14219                PrintWriter out = categoryPw != null ? categoryPw : pw;
14220                if (!isCompact) {
14221                    out.println();
14222                    out.println("Total PSS by category:");
14223                }
14224                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14225            }
14226            if (!isCompact) {
14227                pw.println();
14228            }
14229            MemInfoReader memInfo = new MemInfoReader();
14230            memInfo.readMemInfo();
14231            if (nativeProcTotalPss > 0) {
14232                synchronized (this) {
14233                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14234                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14235                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14236                }
14237            }
14238            if (!brief) {
14239                if (!isCompact) {
14240                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14241                    pw.print(" kB (status ");
14242                    switch (mLastMemoryLevel) {
14243                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14244                            pw.println("normal)");
14245                            break;
14246                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14247                            pw.println("moderate)");
14248                            break;
14249                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14250                            pw.println("low)");
14251                            break;
14252                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14253                            pw.println("critical)");
14254                            break;
14255                        default:
14256                            pw.print(mLastMemoryLevel);
14257                            pw.println(")");
14258                            break;
14259                    }
14260                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14261                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14262                            pw.print(cachedPss); pw.print(" cached pss + ");
14263                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14264                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14265                } else {
14266                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14267                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14268                            + memInfo.getFreeSizeKb()); pw.print(",");
14269                    pw.println(totalPss - cachedPss);
14270                }
14271            }
14272            if (!isCompact) {
14273                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14274                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14275                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14276                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14277                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14278                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14279                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14280            }
14281            if (!brief) {
14282                if (memInfo.getZramTotalSizeKb() != 0) {
14283                    if (!isCompact) {
14284                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14285                                pw.print(" kB physical used for ");
14286                                pw.print(memInfo.getSwapTotalSizeKb()
14287                                        - memInfo.getSwapFreeSizeKb());
14288                                pw.print(" kB in swap (");
14289                                pw.print(memInfo.getSwapTotalSizeKb());
14290                                pw.println(" kB total swap)");
14291                    } else {
14292                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14293                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14294                                pw.println(memInfo.getSwapFreeSizeKb());
14295                    }
14296                }
14297                final long[] ksm = getKsmInfo();
14298                if (!isCompact) {
14299                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14300                            || ksm[KSM_VOLATILE] != 0) {
14301                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14302                                pw.print(" kB saved from shared ");
14303                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14304                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14305                                pw.print(" kB unshared; ");
14306                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14307                    }
14308                    pw.print("   Tuning: ");
14309                    pw.print(ActivityManager.staticGetMemoryClass());
14310                    pw.print(" (large ");
14311                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14312                    pw.print("), oom ");
14313                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14314                    pw.print(" kB");
14315                    pw.print(", restore limit ");
14316                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14317                    pw.print(" kB");
14318                    if (ActivityManager.isLowRamDeviceStatic()) {
14319                        pw.print(" (low-ram)");
14320                    }
14321                    if (ActivityManager.isHighEndGfx()) {
14322                        pw.print(" (high-end-gfx)");
14323                    }
14324                    pw.println();
14325                } else {
14326                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14327                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14328                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14329                    pw.print("tuning,");
14330                    pw.print(ActivityManager.staticGetMemoryClass());
14331                    pw.print(',');
14332                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14333                    pw.print(',');
14334                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14335                    if (ActivityManager.isLowRamDeviceStatic()) {
14336                        pw.print(",low-ram");
14337                    }
14338                    if (ActivityManager.isHighEndGfx()) {
14339                        pw.print(",high-end-gfx");
14340                    }
14341                    pw.println();
14342                }
14343            }
14344        }
14345    }
14346
14347    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14348            long memtrack, String name) {
14349        sb.append("  ");
14350        sb.append(ProcessList.makeOomAdjString(oomAdj));
14351        sb.append(' ');
14352        sb.append(ProcessList.makeProcStateString(procState));
14353        sb.append(' ');
14354        ProcessList.appendRamKb(sb, pss);
14355        sb.append(" kB: ");
14356        sb.append(name);
14357        if (memtrack > 0) {
14358            sb.append(" (");
14359            sb.append(memtrack);
14360            sb.append(" kB memtrack)");
14361        }
14362    }
14363
14364    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14365        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14366        sb.append(" (pid ");
14367        sb.append(mi.pid);
14368        sb.append(") ");
14369        sb.append(mi.adjType);
14370        sb.append('\n');
14371        if (mi.adjReason != null) {
14372            sb.append("                      ");
14373            sb.append(mi.adjReason);
14374            sb.append('\n');
14375        }
14376    }
14377
14378    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14379        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14380        for (int i=0, N=memInfos.size(); i<N; i++) {
14381            ProcessMemInfo mi = memInfos.get(i);
14382            infoMap.put(mi.pid, mi);
14383        }
14384        updateCpuStatsNow();
14385        long[] memtrackTmp = new long[1];
14386        synchronized (mProcessCpuTracker) {
14387            final int N = mProcessCpuTracker.countStats();
14388            for (int i=0; i<N; i++) {
14389                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14390                if (st.vsize > 0) {
14391                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14392                    if (pss > 0) {
14393                        if (infoMap.indexOfKey(st.pid) < 0) {
14394                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14395                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14396                            mi.pss = pss;
14397                            mi.memtrack = memtrackTmp[0];
14398                            memInfos.add(mi);
14399                        }
14400                    }
14401                }
14402            }
14403        }
14404
14405        long totalPss = 0;
14406        long totalMemtrack = 0;
14407        for (int i=0, N=memInfos.size(); i<N; i++) {
14408            ProcessMemInfo mi = memInfos.get(i);
14409            if (mi.pss == 0) {
14410                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14411                mi.memtrack = memtrackTmp[0];
14412            }
14413            totalPss += mi.pss;
14414            totalMemtrack += mi.memtrack;
14415        }
14416        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14417            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14418                if (lhs.oomAdj != rhs.oomAdj) {
14419                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14420                }
14421                if (lhs.pss != rhs.pss) {
14422                    return lhs.pss < rhs.pss ? 1 : -1;
14423                }
14424                return 0;
14425            }
14426        });
14427
14428        StringBuilder tag = new StringBuilder(128);
14429        StringBuilder stack = new StringBuilder(128);
14430        tag.append("Low on memory -- ");
14431        appendMemBucket(tag, totalPss, "total", false);
14432        appendMemBucket(stack, totalPss, "total", true);
14433
14434        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14435        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14436        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14437
14438        boolean firstLine = true;
14439        int lastOomAdj = Integer.MIN_VALUE;
14440        long extraNativeRam = 0;
14441        long extraNativeMemtrack = 0;
14442        long cachedPss = 0;
14443        for (int i=0, N=memInfos.size(); i<N; i++) {
14444            ProcessMemInfo mi = memInfos.get(i);
14445
14446            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14447                cachedPss += mi.pss;
14448            }
14449
14450            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14451                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14452                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14453                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14454                if (lastOomAdj != mi.oomAdj) {
14455                    lastOomAdj = mi.oomAdj;
14456                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14457                        tag.append(" / ");
14458                    }
14459                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14460                        if (firstLine) {
14461                            stack.append(":");
14462                            firstLine = false;
14463                        }
14464                        stack.append("\n\t at ");
14465                    } else {
14466                        stack.append("$");
14467                    }
14468                } else {
14469                    tag.append(" ");
14470                    stack.append("$");
14471                }
14472                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14473                    appendMemBucket(tag, mi.pss, mi.name, false);
14474                }
14475                appendMemBucket(stack, mi.pss, mi.name, true);
14476                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14477                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14478                    stack.append("(");
14479                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14480                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14481                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14482                            stack.append(":");
14483                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14484                        }
14485                    }
14486                    stack.append(")");
14487                }
14488            }
14489
14490            appendMemInfo(fullNativeBuilder, mi);
14491            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14492                // The short form only has native processes that are >= 512K.
14493                if (mi.pss >= 512) {
14494                    appendMemInfo(shortNativeBuilder, mi);
14495                } else {
14496                    extraNativeRam += mi.pss;
14497                    extraNativeMemtrack += mi.memtrack;
14498                }
14499            } else {
14500                // Short form has all other details, but if we have collected RAM
14501                // from smaller native processes let's dump a summary of that.
14502                if (extraNativeRam > 0) {
14503                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14504                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14505                    shortNativeBuilder.append('\n');
14506                    extraNativeRam = 0;
14507                }
14508                appendMemInfo(fullJavaBuilder, mi);
14509            }
14510        }
14511
14512        fullJavaBuilder.append("           ");
14513        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14514        fullJavaBuilder.append(" kB: TOTAL");
14515        if (totalMemtrack > 0) {
14516            fullJavaBuilder.append(" (");
14517            fullJavaBuilder.append(totalMemtrack);
14518            fullJavaBuilder.append(" kB memtrack)");
14519        } else {
14520        }
14521        fullJavaBuilder.append("\n");
14522
14523        MemInfoReader memInfo = new MemInfoReader();
14524        memInfo.readMemInfo();
14525        final long[] infos = memInfo.getRawInfo();
14526
14527        StringBuilder memInfoBuilder = new StringBuilder(1024);
14528        Debug.getMemInfo(infos);
14529        memInfoBuilder.append("  MemInfo: ");
14530        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14531        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14532        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14533        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14534        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14535        memInfoBuilder.append("           ");
14536        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14537        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14538        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14539        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14540        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14541            memInfoBuilder.append("  ZRAM: ");
14542            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14543            memInfoBuilder.append(" kB RAM, ");
14544            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14545            memInfoBuilder.append(" kB swap total, ");
14546            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14547            memInfoBuilder.append(" kB swap free\n");
14548        }
14549        final long[] ksm = getKsmInfo();
14550        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14551                || ksm[KSM_VOLATILE] != 0) {
14552            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14553            memInfoBuilder.append(" kB saved from shared ");
14554            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14555            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14556            memInfoBuilder.append(" kB unshared; ");
14557            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14558        }
14559        memInfoBuilder.append("  Free RAM: ");
14560        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14561                + memInfo.getFreeSizeKb());
14562        memInfoBuilder.append(" kB\n");
14563        memInfoBuilder.append("  Used RAM: ");
14564        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14565        memInfoBuilder.append(" kB\n");
14566        memInfoBuilder.append("  Lost RAM: ");
14567        memInfoBuilder.append(memInfo.getTotalSizeKb()
14568                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14569                - memInfo.getKernelUsedSizeKb());
14570        memInfoBuilder.append(" kB\n");
14571        Slog.i(TAG, "Low on memory:");
14572        Slog.i(TAG, shortNativeBuilder.toString());
14573        Slog.i(TAG, fullJavaBuilder.toString());
14574        Slog.i(TAG, memInfoBuilder.toString());
14575
14576        StringBuilder dropBuilder = new StringBuilder(1024);
14577        /*
14578        StringWriter oomSw = new StringWriter();
14579        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14580        StringWriter catSw = new StringWriter();
14581        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14582        String[] emptyArgs = new String[] { };
14583        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14584        oomPw.flush();
14585        String oomString = oomSw.toString();
14586        */
14587        dropBuilder.append("Low on memory:");
14588        dropBuilder.append(stack);
14589        dropBuilder.append('\n');
14590        dropBuilder.append(fullNativeBuilder);
14591        dropBuilder.append(fullJavaBuilder);
14592        dropBuilder.append('\n');
14593        dropBuilder.append(memInfoBuilder);
14594        dropBuilder.append('\n');
14595        /*
14596        dropBuilder.append(oomString);
14597        dropBuilder.append('\n');
14598        */
14599        StringWriter catSw = new StringWriter();
14600        synchronized (ActivityManagerService.this) {
14601            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14602            String[] emptyArgs = new String[] { };
14603            catPw.println();
14604            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14605            catPw.println();
14606            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14607                    false, false, null);
14608            catPw.println();
14609            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14610            catPw.flush();
14611        }
14612        dropBuilder.append(catSw.toString());
14613        addErrorToDropBox("lowmem", null, "system_server", null,
14614                null, tag.toString(), dropBuilder.toString(), null, null);
14615        //Slog.i(TAG, "Sent to dropbox:");
14616        //Slog.i(TAG, dropBuilder.toString());
14617        synchronized (ActivityManagerService.this) {
14618            long now = SystemClock.uptimeMillis();
14619            if (mLastMemUsageReportTime < now) {
14620                mLastMemUsageReportTime = now;
14621            }
14622        }
14623    }
14624
14625    /**
14626     * Searches array of arguments for the specified string
14627     * @param args array of argument strings
14628     * @param value value to search for
14629     * @return true if the value is contained in the array
14630     */
14631    private static boolean scanArgs(String[] args, String value) {
14632        if (args != null) {
14633            for (String arg : args) {
14634                if (value.equals(arg)) {
14635                    return true;
14636                }
14637            }
14638        }
14639        return false;
14640    }
14641
14642    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14643            ContentProviderRecord cpr, boolean always) {
14644        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14645
14646        if (!inLaunching || always) {
14647            synchronized (cpr) {
14648                cpr.launchingApp = null;
14649                cpr.notifyAll();
14650            }
14651            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14652            String names[] = cpr.info.authority.split(";");
14653            for (int j = 0; j < names.length; j++) {
14654                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14655            }
14656        }
14657
14658        for (int i=0; i<cpr.connections.size(); i++) {
14659            ContentProviderConnection conn = cpr.connections.get(i);
14660            if (conn.waiting) {
14661                // If this connection is waiting for the provider, then we don't
14662                // need to mess with its process unless we are always removing
14663                // or for some reason the provider is not currently launching.
14664                if (inLaunching && !always) {
14665                    continue;
14666                }
14667            }
14668            ProcessRecord capp = conn.client;
14669            conn.dead = true;
14670            if (conn.stableCount > 0) {
14671                if (!capp.persistent && capp.thread != null
14672                        && capp.pid != 0
14673                        && capp.pid != MY_PID) {
14674                    capp.kill("depends on provider "
14675                            + cpr.name.flattenToShortString()
14676                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14677                }
14678            } else if (capp.thread != null && conn.provider.provider != null) {
14679                try {
14680                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14681                } catch (RemoteException e) {
14682                }
14683                // In the protocol here, we don't expect the client to correctly
14684                // clean up this connection, we'll just remove it.
14685                cpr.connections.remove(i);
14686                conn.client.conProviders.remove(conn);
14687            }
14688        }
14689
14690        if (inLaunching && always) {
14691            mLaunchingProviders.remove(cpr);
14692        }
14693        return inLaunching;
14694    }
14695
14696    /**
14697     * Main code for cleaning up a process when it has gone away.  This is
14698     * called both as a result of the process dying, or directly when stopping
14699     * a process when running in single process mode.
14700     *
14701     * @return Returns true if the given process has been restarted, so the
14702     * app that was passed in must remain on the process lists.
14703     */
14704    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14705            boolean restarting, boolean allowRestart, int index) {
14706        if (index >= 0) {
14707            removeLruProcessLocked(app);
14708            ProcessList.remove(app.pid);
14709        }
14710
14711        mProcessesToGc.remove(app);
14712        mPendingPssProcesses.remove(app);
14713
14714        // Dismiss any open dialogs.
14715        if (app.crashDialog != null && !app.forceCrashReport) {
14716            app.crashDialog.dismiss();
14717            app.crashDialog = null;
14718        }
14719        if (app.anrDialog != null) {
14720            app.anrDialog.dismiss();
14721            app.anrDialog = null;
14722        }
14723        if (app.waitDialog != null) {
14724            app.waitDialog.dismiss();
14725            app.waitDialog = null;
14726        }
14727
14728        app.crashing = false;
14729        app.notResponding = false;
14730
14731        app.resetPackageList(mProcessStats);
14732        app.unlinkDeathRecipient();
14733        app.makeInactive(mProcessStats);
14734        app.waitingToKill = null;
14735        app.forcingToForeground = null;
14736        updateProcessForegroundLocked(app, false, false);
14737        app.foregroundActivities = false;
14738        app.hasShownUi = false;
14739        app.treatLikeActivity = false;
14740        app.hasAboveClient = false;
14741        app.hasClientActivities = false;
14742
14743        mServices.killServicesLocked(app, allowRestart);
14744
14745        boolean restart = false;
14746
14747        // Remove published content providers.
14748        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14749            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14750            final boolean always = app.bad || !allowRestart;
14751            if (removeDyingProviderLocked(app, cpr, always) || always) {
14752                // We left the provider in the launching list, need to
14753                // restart it.
14754                restart = true;
14755            }
14756
14757            cpr.provider = null;
14758            cpr.proc = null;
14759        }
14760        app.pubProviders.clear();
14761
14762        // Take care of any launching providers waiting for this process.
14763        if (checkAppInLaunchingProvidersLocked(app, false)) {
14764            restart = true;
14765        }
14766
14767        // Unregister from connected content providers.
14768        if (!app.conProviders.isEmpty()) {
14769            for (int i=0; i<app.conProviders.size(); i++) {
14770                ContentProviderConnection conn = app.conProviders.get(i);
14771                conn.provider.connections.remove(conn);
14772            }
14773            app.conProviders.clear();
14774        }
14775
14776        // At this point there may be remaining entries in mLaunchingProviders
14777        // where we were the only one waiting, so they are no longer of use.
14778        // Look for these and clean up if found.
14779        // XXX Commented out for now.  Trying to figure out a way to reproduce
14780        // the actual situation to identify what is actually going on.
14781        if (false) {
14782            for (int i=0; i<mLaunchingProviders.size(); i++) {
14783                ContentProviderRecord cpr = (ContentProviderRecord)
14784                        mLaunchingProviders.get(i);
14785                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14786                    synchronized (cpr) {
14787                        cpr.launchingApp = null;
14788                        cpr.notifyAll();
14789                    }
14790                }
14791            }
14792        }
14793
14794        skipCurrentReceiverLocked(app);
14795
14796        // Unregister any receivers.
14797        for (int i=app.receivers.size()-1; i>=0; i--) {
14798            removeReceiverLocked(app.receivers.valueAt(i));
14799        }
14800        app.receivers.clear();
14801
14802        // If the app is undergoing backup, tell the backup manager about it
14803        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14804            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14805                    + mBackupTarget.appInfo + " died during backup");
14806            try {
14807                IBackupManager bm = IBackupManager.Stub.asInterface(
14808                        ServiceManager.getService(Context.BACKUP_SERVICE));
14809                bm.agentDisconnected(app.info.packageName);
14810            } catch (RemoteException e) {
14811                // can't happen; backup manager is local
14812            }
14813        }
14814
14815        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14816            ProcessChangeItem item = mPendingProcessChanges.get(i);
14817            if (item.pid == app.pid) {
14818                mPendingProcessChanges.remove(i);
14819                mAvailProcessChanges.add(item);
14820            }
14821        }
14822        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14823
14824        // If the caller is restarting this app, then leave it in its
14825        // current lists and let the caller take care of it.
14826        if (restarting) {
14827            return false;
14828        }
14829
14830        if (!app.persistent || app.isolated) {
14831            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14832                    "Removing non-persistent process during cleanup: " + app);
14833            mProcessNames.remove(app.processName, app.uid);
14834            mIsolatedProcesses.remove(app.uid);
14835            if (mHeavyWeightProcess == app) {
14836                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14837                        mHeavyWeightProcess.userId, 0));
14838                mHeavyWeightProcess = null;
14839            }
14840        } else if (!app.removed) {
14841            // This app is persistent, so we need to keep its record around.
14842            // If it is not already on the pending app list, add it there
14843            // and start a new process for it.
14844            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14845                mPersistentStartingProcesses.add(app);
14846                restart = true;
14847            }
14848        }
14849        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14850                "Clean-up removing on hold: " + app);
14851        mProcessesOnHold.remove(app);
14852
14853        if (app == mHomeProcess) {
14854            mHomeProcess = null;
14855        }
14856        if (app == mPreviousProcess) {
14857            mPreviousProcess = null;
14858        }
14859
14860        if (restart && !app.isolated) {
14861            // We have components that still need to be running in the
14862            // process, so re-launch it.
14863            if (index < 0) {
14864                ProcessList.remove(app.pid);
14865            }
14866            mProcessNames.put(app.processName, app.uid, app);
14867            startProcessLocked(app, "restart", app.processName);
14868            return true;
14869        } else if (app.pid > 0 && app.pid != MY_PID) {
14870            // Goodbye!
14871            boolean removed;
14872            synchronized (mPidsSelfLocked) {
14873                mPidsSelfLocked.remove(app.pid);
14874                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14875            }
14876            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14877            if (app.isolated) {
14878                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14879            }
14880            app.setPid(0);
14881        }
14882        return false;
14883    }
14884
14885    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14886        // Look through the content providers we are waiting to have launched,
14887        // and if any run in this process then either schedule a restart of
14888        // the process or kill the client waiting for it if this process has
14889        // gone bad.
14890        int NL = mLaunchingProviders.size();
14891        boolean restart = false;
14892        for (int i=0; i<NL; i++) {
14893            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14894            if (cpr.launchingApp == app) {
14895                if (!alwaysBad && !app.bad) {
14896                    restart = true;
14897                } else {
14898                    removeDyingProviderLocked(app, cpr, true);
14899                    // cpr should have been removed from mLaunchingProviders
14900                    NL = mLaunchingProviders.size();
14901                    i--;
14902                }
14903            }
14904        }
14905        return restart;
14906    }
14907
14908    // =========================================================
14909    // SERVICES
14910    // =========================================================
14911
14912    @Override
14913    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14914            int flags) {
14915        enforceNotIsolatedCaller("getServices");
14916        synchronized (this) {
14917            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14918        }
14919    }
14920
14921    @Override
14922    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14923        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14924        synchronized (this) {
14925            return mServices.getRunningServiceControlPanelLocked(name);
14926        }
14927    }
14928
14929    @Override
14930    public ComponentName startService(IApplicationThread caller, Intent service,
14931            String resolvedType, int userId) {
14932        enforceNotIsolatedCaller("startService");
14933        // Refuse possible leaked file descriptors
14934        if (service != null && service.hasFileDescriptors() == true) {
14935            throw new IllegalArgumentException("File descriptors passed in Intent");
14936        }
14937
14938        if (DEBUG_SERVICE)
14939            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14940        synchronized(this) {
14941            final int callingPid = Binder.getCallingPid();
14942            final int callingUid = Binder.getCallingUid();
14943            final long origId = Binder.clearCallingIdentity();
14944            ComponentName res = mServices.startServiceLocked(caller, service,
14945                    resolvedType, callingPid, callingUid, userId);
14946            Binder.restoreCallingIdentity(origId);
14947            return res;
14948        }
14949    }
14950
14951    ComponentName startServiceInPackage(int uid,
14952            Intent service, String resolvedType, int userId) {
14953        synchronized(this) {
14954            if (DEBUG_SERVICE)
14955                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14956            final long origId = Binder.clearCallingIdentity();
14957            ComponentName res = mServices.startServiceLocked(null, service,
14958                    resolvedType, -1, uid, userId);
14959            Binder.restoreCallingIdentity(origId);
14960            return res;
14961        }
14962    }
14963
14964    @Override
14965    public int stopService(IApplicationThread caller, Intent service,
14966            String resolvedType, int userId) {
14967        enforceNotIsolatedCaller("stopService");
14968        // Refuse possible leaked file descriptors
14969        if (service != null && service.hasFileDescriptors() == true) {
14970            throw new IllegalArgumentException("File descriptors passed in Intent");
14971        }
14972
14973        synchronized(this) {
14974            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14975        }
14976    }
14977
14978    @Override
14979    public IBinder peekService(Intent service, String resolvedType) {
14980        enforceNotIsolatedCaller("peekService");
14981        // Refuse possible leaked file descriptors
14982        if (service != null && service.hasFileDescriptors() == true) {
14983            throw new IllegalArgumentException("File descriptors passed in Intent");
14984        }
14985        synchronized(this) {
14986            return mServices.peekServiceLocked(service, resolvedType);
14987        }
14988    }
14989
14990    @Override
14991    public boolean stopServiceToken(ComponentName className, IBinder token,
14992            int startId) {
14993        synchronized(this) {
14994            return mServices.stopServiceTokenLocked(className, token, startId);
14995        }
14996    }
14997
14998    @Override
14999    public void setServiceForeground(ComponentName className, IBinder token,
15000            int id, Notification notification, boolean removeNotification) {
15001        synchronized(this) {
15002            mServices.setServiceForegroundLocked(className, token, id, notification,
15003                    removeNotification);
15004        }
15005    }
15006
15007    @Override
15008    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15009            boolean requireFull, String name, String callerPackage) {
15010        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15011                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15012    }
15013
15014    int unsafeConvertIncomingUser(int userId) {
15015        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15016                ? mCurrentUserId : userId;
15017    }
15018
15019    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15020            int allowMode, String name, String callerPackage) {
15021        final int callingUserId = UserHandle.getUserId(callingUid);
15022        if (callingUserId == userId) {
15023            return userId;
15024        }
15025
15026        // Note that we may be accessing mCurrentUserId outside of a lock...
15027        // shouldn't be a big deal, if this is being called outside
15028        // of a locked context there is intrinsically a race with
15029        // the value the caller will receive and someone else changing it.
15030        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15031        // we will switch to the calling user if access to the current user fails.
15032        int targetUserId = unsafeConvertIncomingUser(userId);
15033
15034        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15035            final boolean allow;
15036            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15037                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15038                // If the caller has this permission, they always pass go.  And collect $200.
15039                allow = true;
15040            } else if (allowMode == ALLOW_FULL_ONLY) {
15041                // We require full access, sucks to be you.
15042                allow = false;
15043            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15044                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15045                // If the caller does not have either permission, they are always doomed.
15046                allow = false;
15047            } else if (allowMode == ALLOW_NON_FULL) {
15048                // We are blanket allowing non-full access, you lucky caller!
15049                allow = true;
15050            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15051                // We may or may not allow this depending on whether the two users are
15052                // in the same profile.
15053                synchronized (mUserProfileGroupIdsSelfLocked) {
15054                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15055                            UserInfo.NO_PROFILE_GROUP_ID);
15056                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15057                            UserInfo.NO_PROFILE_GROUP_ID);
15058                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15059                            && callingProfile == targetProfile;
15060                }
15061            } else {
15062                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15063            }
15064            if (!allow) {
15065                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15066                    // In this case, they would like to just execute as their
15067                    // owner user instead of failing.
15068                    targetUserId = callingUserId;
15069                } else {
15070                    StringBuilder builder = new StringBuilder(128);
15071                    builder.append("Permission Denial: ");
15072                    builder.append(name);
15073                    if (callerPackage != null) {
15074                        builder.append(" from ");
15075                        builder.append(callerPackage);
15076                    }
15077                    builder.append(" asks to run as user ");
15078                    builder.append(userId);
15079                    builder.append(" but is calling from user ");
15080                    builder.append(UserHandle.getUserId(callingUid));
15081                    builder.append("; this requires ");
15082                    builder.append(INTERACT_ACROSS_USERS_FULL);
15083                    if (allowMode != ALLOW_FULL_ONLY) {
15084                        builder.append(" or ");
15085                        builder.append(INTERACT_ACROSS_USERS);
15086                    }
15087                    String msg = builder.toString();
15088                    Slog.w(TAG, msg);
15089                    throw new SecurityException(msg);
15090                }
15091            }
15092        }
15093        if (!allowAll && targetUserId < 0) {
15094            throw new IllegalArgumentException(
15095                    "Call does not support special user #" + targetUserId);
15096        }
15097        // Check shell permission
15098        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15099            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15100                    targetUserId)) {
15101                throw new SecurityException("Shell does not have permission to access user "
15102                        + targetUserId + "\n " + Debug.getCallers(3));
15103            }
15104        }
15105        return targetUserId;
15106    }
15107
15108    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15109            String className, int flags) {
15110        boolean result = false;
15111        // For apps that don't have pre-defined UIDs, check for permission
15112        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15113            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15114                if (ActivityManager.checkUidPermission(
15115                        INTERACT_ACROSS_USERS,
15116                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15117                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15118                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15119                            + " requests FLAG_SINGLE_USER, but app does not hold "
15120                            + INTERACT_ACROSS_USERS;
15121                    Slog.w(TAG, msg);
15122                    throw new SecurityException(msg);
15123                }
15124                // Permission passed
15125                result = true;
15126            }
15127        } else if ("system".equals(componentProcessName)) {
15128            result = true;
15129        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15130            // Phone app and persistent apps are allowed to export singleuser providers.
15131            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15132                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15133        }
15134        if (DEBUG_MU) {
15135            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15136                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15137        }
15138        return result;
15139    }
15140
15141    /**
15142     * Checks to see if the caller is in the same app as the singleton
15143     * component, or the component is in a special app. It allows special apps
15144     * to export singleton components but prevents exporting singleton
15145     * components for regular apps.
15146     */
15147    boolean isValidSingletonCall(int callingUid, int componentUid) {
15148        int componentAppId = UserHandle.getAppId(componentUid);
15149        return UserHandle.isSameApp(callingUid, componentUid)
15150                || componentAppId == Process.SYSTEM_UID
15151                || componentAppId == Process.PHONE_UID
15152                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15153                        == PackageManager.PERMISSION_GRANTED;
15154    }
15155
15156    public int bindService(IApplicationThread caller, IBinder token,
15157            Intent service, String resolvedType,
15158            IServiceConnection connection, int flags, int userId) {
15159        enforceNotIsolatedCaller("bindService");
15160
15161        // Refuse possible leaked file descriptors
15162        if (service != null && service.hasFileDescriptors() == true) {
15163            throw new IllegalArgumentException("File descriptors passed in Intent");
15164        }
15165
15166        synchronized(this) {
15167            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15168                    connection, flags, userId);
15169        }
15170    }
15171
15172    public boolean unbindService(IServiceConnection connection) {
15173        synchronized (this) {
15174            return mServices.unbindServiceLocked(connection);
15175        }
15176    }
15177
15178    public void publishService(IBinder token, Intent intent, IBinder service) {
15179        // Refuse possible leaked file descriptors
15180        if (intent != null && intent.hasFileDescriptors() == true) {
15181            throw new IllegalArgumentException("File descriptors passed in Intent");
15182        }
15183
15184        synchronized(this) {
15185            if (!(token instanceof ServiceRecord)) {
15186                throw new IllegalArgumentException("Invalid service token");
15187            }
15188            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15189        }
15190    }
15191
15192    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15193        // Refuse possible leaked file descriptors
15194        if (intent != null && intent.hasFileDescriptors() == true) {
15195            throw new IllegalArgumentException("File descriptors passed in Intent");
15196        }
15197
15198        synchronized(this) {
15199            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15200        }
15201    }
15202
15203    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15204        synchronized(this) {
15205            if (!(token instanceof ServiceRecord)) {
15206                throw new IllegalArgumentException("Invalid service token");
15207            }
15208            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15209        }
15210    }
15211
15212    // =========================================================
15213    // BACKUP AND RESTORE
15214    // =========================================================
15215
15216    // Cause the target app to be launched if necessary and its backup agent
15217    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15218    // activity manager to announce its creation.
15219    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15220        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15221        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15222
15223        synchronized(this) {
15224            // !!! TODO: currently no check here that we're already bound
15225            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15226            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15227            synchronized (stats) {
15228                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15229            }
15230
15231            // Backup agent is now in use, its package can't be stopped.
15232            try {
15233                AppGlobals.getPackageManager().setPackageStoppedState(
15234                        app.packageName, false, UserHandle.getUserId(app.uid));
15235            } catch (RemoteException e) {
15236            } catch (IllegalArgumentException e) {
15237                Slog.w(TAG, "Failed trying to unstop package "
15238                        + app.packageName + ": " + e);
15239            }
15240
15241            BackupRecord r = new BackupRecord(ss, app, backupMode);
15242            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15243                    ? new ComponentName(app.packageName, app.backupAgentName)
15244                    : new ComponentName("android", "FullBackupAgent");
15245            // startProcessLocked() returns existing proc's record if it's already running
15246            ProcessRecord proc = startProcessLocked(app.processName, app,
15247                    false, 0, "backup", hostingName, false, false, false);
15248            if (proc == null) {
15249                Slog.e(TAG, "Unable to start backup agent process " + r);
15250                return false;
15251            }
15252
15253            r.app = proc;
15254            mBackupTarget = r;
15255            mBackupAppName = app.packageName;
15256
15257            // Try not to kill the process during backup
15258            updateOomAdjLocked(proc);
15259
15260            // If the process is already attached, schedule the creation of the backup agent now.
15261            // If it is not yet live, this will be done when it attaches to the framework.
15262            if (proc.thread != null) {
15263                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15264                try {
15265                    proc.thread.scheduleCreateBackupAgent(app,
15266                            compatibilityInfoForPackageLocked(app), backupMode);
15267                } catch (RemoteException e) {
15268                    // Will time out on the backup manager side
15269                }
15270            } else {
15271                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15272            }
15273            // Invariants: at this point, the target app process exists and the application
15274            // is either already running or in the process of coming up.  mBackupTarget and
15275            // mBackupAppName describe the app, so that when it binds back to the AM we
15276            // know that it's scheduled for a backup-agent operation.
15277        }
15278
15279        return true;
15280    }
15281
15282    @Override
15283    public void clearPendingBackup() {
15284        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15285        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15286
15287        synchronized (this) {
15288            mBackupTarget = null;
15289            mBackupAppName = null;
15290        }
15291    }
15292
15293    // A backup agent has just come up
15294    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15295        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15296                + " = " + agent);
15297
15298        synchronized(this) {
15299            if (!agentPackageName.equals(mBackupAppName)) {
15300                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15301                return;
15302            }
15303        }
15304
15305        long oldIdent = Binder.clearCallingIdentity();
15306        try {
15307            IBackupManager bm = IBackupManager.Stub.asInterface(
15308                    ServiceManager.getService(Context.BACKUP_SERVICE));
15309            bm.agentConnected(agentPackageName, agent);
15310        } catch (RemoteException e) {
15311            // can't happen; the backup manager service is local
15312        } catch (Exception e) {
15313            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15314            e.printStackTrace();
15315        } finally {
15316            Binder.restoreCallingIdentity(oldIdent);
15317        }
15318    }
15319
15320    // done with this agent
15321    public void unbindBackupAgent(ApplicationInfo appInfo) {
15322        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15323        if (appInfo == null) {
15324            Slog.w(TAG, "unbind backup agent for null app");
15325            return;
15326        }
15327
15328        synchronized(this) {
15329            try {
15330                if (mBackupAppName == null) {
15331                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15332                    return;
15333                }
15334
15335                if (!mBackupAppName.equals(appInfo.packageName)) {
15336                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15337                    return;
15338                }
15339
15340                // Not backing this app up any more; reset its OOM adjustment
15341                final ProcessRecord proc = mBackupTarget.app;
15342                updateOomAdjLocked(proc);
15343
15344                // If the app crashed during backup, 'thread' will be null here
15345                if (proc.thread != null) {
15346                    try {
15347                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15348                                compatibilityInfoForPackageLocked(appInfo));
15349                    } catch (Exception e) {
15350                        Slog.e(TAG, "Exception when unbinding backup agent:");
15351                        e.printStackTrace();
15352                    }
15353                }
15354            } finally {
15355                mBackupTarget = null;
15356                mBackupAppName = null;
15357            }
15358        }
15359    }
15360    // =========================================================
15361    // BROADCASTS
15362    // =========================================================
15363
15364    private final List getStickiesLocked(String action, IntentFilter filter,
15365            List cur, int userId) {
15366        final ContentResolver resolver = mContext.getContentResolver();
15367        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15368        if (stickies == null) {
15369            return cur;
15370        }
15371        final ArrayList<Intent> list = stickies.get(action);
15372        if (list == null) {
15373            return cur;
15374        }
15375        int N = list.size();
15376        for (int i=0; i<N; i++) {
15377            Intent intent = list.get(i);
15378            if (filter.match(resolver, intent, true, TAG) >= 0) {
15379                if (cur == null) {
15380                    cur = new ArrayList<Intent>();
15381                }
15382                cur.add(intent);
15383            }
15384        }
15385        return cur;
15386    }
15387
15388    boolean isPendingBroadcastProcessLocked(int pid) {
15389        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15390                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15391    }
15392
15393    void skipPendingBroadcastLocked(int pid) {
15394            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15395            for (BroadcastQueue queue : mBroadcastQueues) {
15396                queue.skipPendingBroadcastLocked(pid);
15397            }
15398    }
15399
15400    // The app just attached; send any pending broadcasts that it should receive
15401    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15402        boolean didSomething = false;
15403        for (BroadcastQueue queue : mBroadcastQueues) {
15404            didSomething |= queue.sendPendingBroadcastsLocked(app);
15405        }
15406        return didSomething;
15407    }
15408
15409    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15410            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15411        enforceNotIsolatedCaller("registerReceiver");
15412        int callingUid;
15413        int callingPid;
15414        synchronized(this) {
15415            ProcessRecord callerApp = null;
15416            if (caller != null) {
15417                callerApp = getRecordForAppLocked(caller);
15418                if (callerApp == null) {
15419                    throw new SecurityException(
15420                            "Unable to find app for caller " + caller
15421                            + " (pid=" + Binder.getCallingPid()
15422                            + ") when registering receiver " + receiver);
15423                }
15424                if (callerApp.info.uid != Process.SYSTEM_UID &&
15425                        !callerApp.pkgList.containsKey(callerPackage) &&
15426                        !"android".equals(callerPackage)) {
15427                    throw new SecurityException("Given caller package " + callerPackage
15428                            + " is not running in process " + callerApp);
15429                }
15430                callingUid = callerApp.info.uid;
15431                callingPid = callerApp.pid;
15432            } else {
15433                callerPackage = null;
15434                callingUid = Binder.getCallingUid();
15435                callingPid = Binder.getCallingPid();
15436            }
15437
15438            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15439                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15440
15441            List allSticky = null;
15442
15443            // Look for any matching sticky broadcasts...
15444            Iterator actions = filter.actionsIterator();
15445            if (actions != null) {
15446                while (actions.hasNext()) {
15447                    String action = (String)actions.next();
15448                    allSticky = getStickiesLocked(action, filter, allSticky,
15449                            UserHandle.USER_ALL);
15450                    allSticky = getStickiesLocked(action, filter, allSticky,
15451                            UserHandle.getUserId(callingUid));
15452                }
15453            } else {
15454                allSticky = getStickiesLocked(null, filter, allSticky,
15455                        UserHandle.USER_ALL);
15456                allSticky = getStickiesLocked(null, filter, allSticky,
15457                        UserHandle.getUserId(callingUid));
15458            }
15459
15460            // The first sticky in the list is returned directly back to
15461            // the client.
15462            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15463
15464            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15465                    + ": " + sticky);
15466
15467            if (receiver == null) {
15468                return sticky;
15469            }
15470
15471            ReceiverList rl
15472                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15473            if (rl == null) {
15474                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15475                        userId, receiver);
15476                if (rl.app != null) {
15477                    rl.app.receivers.add(rl);
15478                } else {
15479                    try {
15480                        receiver.asBinder().linkToDeath(rl, 0);
15481                    } catch (RemoteException e) {
15482                        return sticky;
15483                    }
15484                    rl.linkedToDeath = true;
15485                }
15486                mRegisteredReceivers.put(receiver.asBinder(), rl);
15487            } else if (rl.uid != callingUid) {
15488                throw new IllegalArgumentException(
15489                        "Receiver requested to register for uid " + callingUid
15490                        + " was previously registered for uid " + rl.uid);
15491            } else if (rl.pid != callingPid) {
15492                throw new IllegalArgumentException(
15493                        "Receiver requested to register for pid " + callingPid
15494                        + " was previously registered for pid " + rl.pid);
15495            } else if (rl.userId != userId) {
15496                throw new IllegalArgumentException(
15497                        "Receiver requested to register for user " + userId
15498                        + " was previously registered for user " + rl.userId);
15499            }
15500            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15501                    permission, callingUid, userId);
15502            rl.add(bf);
15503            if (!bf.debugCheck()) {
15504                Slog.w(TAG, "==> For Dynamic broadast");
15505            }
15506            mReceiverResolver.addFilter(bf);
15507
15508            // Enqueue broadcasts for all existing stickies that match
15509            // this filter.
15510            if (allSticky != null) {
15511                ArrayList receivers = new ArrayList();
15512                receivers.add(bf);
15513
15514                int N = allSticky.size();
15515                for (int i=0; i<N; i++) {
15516                    Intent intent = (Intent)allSticky.get(i);
15517                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15518                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15519                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15520                            null, null, false, true, true, -1);
15521                    queue.enqueueParallelBroadcastLocked(r);
15522                    queue.scheduleBroadcastsLocked();
15523                }
15524            }
15525
15526            return sticky;
15527        }
15528    }
15529
15530    public void unregisterReceiver(IIntentReceiver receiver) {
15531        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15532
15533        final long origId = Binder.clearCallingIdentity();
15534        try {
15535            boolean doTrim = false;
15536
15537            synchronized(this) {
15538                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15539                if (rl != null) {
15540                    if (rl.curBroadcast != null) {
15541                        BroadcastRecord r = rl.curBroadcast;
15542                        final boolean doNext = finishReceiverLocked(
15543                                receiver.asBinder(), r.resultCode, r.resultData,
15544                                r.resultExtras, r.resultAbort);
15545                        if (doNext) {
15546                            doTrim = true;
15547                            r.queue.processNextBroadcast(false);
15548                        }
15549                    }
15550
15551                    if (rl.app != null) {
15552                        rl.app.receivers.remove(rl);
15553                    }
15554                    removeReceiverLocked(rl);
15555                    if (rl.linkedToDeath) {
15556                        rl.linkedToDeath = false;
15557                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15558                    }
15559                }
15560            }
15561
15562            // If we actually concluded any broadcasts, we might now be able
15563            // to trim the recipients' apps from our working set
15564            if (doTrim) {
15565                trimApplications();
15566                return;
15567            }
15568
15569        } finally {
15570            Binder.restoreCallingIdentity(origId);
15571        }
15572    }
15573
15574    void removeReceiverLocked(ReceiverList rl) {
15575        mRegisteredReceivers.remove(rl.receiver.asBinder());
15576        int N = rl.size();
15577        for (int i=0; i<N; i++) {
15578            mReceiverResolver.removeFilter(rl.get(i));
15579        }
15580    }
15581
15582    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15583        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15584            ProcessRecord r = mLruProcesses.get(i);
15585            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15586                try {
15587                    r.thread.dispatchPackageBroadcast(cmd, packages);
15588                } catch (RemoteException ex) {
15589                }
15590            }
15591        }
15592    }
15593
15594    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15595            int callingUid, int[] users) {
15596        List<ResolveInfo> receivers = null;
15597        try {
15598            HashSet<ComponentName> singleUserReceivers = null;
15599            boolean scannedFirstReceivers = false;
15600            for (int user : users) {
15601                // Skip users that have Shell restrictions
15602                if (callingUid == Process.SHELL_UID
15603                        && getUserManagerLocked().hasUserRestriction(
15604                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15605                    continue;
15606                }
15607                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15608                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15609                if (user != 0 && newReceivers != null) {
15610                    // If this is not the primary user, we need to check for
15611                    // any receivers that should be filtered out.
15612                    for (int i=0; i<newReceivers.size(); i++) {
15613                        ResolveInfo ri = newReceivers.get(i);
15614                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15615                            newReceivers.remove(i);
15616                            i--;
15617                        }
15618                    }
15619                }
15620                if (newReceivers != null && newReceivers.size() == 0) {
15621                    newReceivers = null;
15622                }
15623                if (receivers == null) {
15624                    receivers = newReceivers;
15625                } else if (newReceivers != null) {
15626                    // We need to concatenate the additional receivers
15627                    // found with what we have do far.  This would be easy,
15628                    // but we also need to de-dup any receivers that are
15629                    // singleUser.
15630                    if (!scannedFirstReceivers) {
15631                        // Collect any single user receivers we had already retrieved.
15632                        scannedFirstReceivers = true;
15633                        for (int i=0; i<receivers.size(); i++) {
15634                            ResolveInfo ri = receivers.get(i);
15635                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15636                                ComponentName cn = new ComponentName(
15637                                        ri.activityInfo.packageName, ri.activityInfo.name);
15638                                if (singleUserReceivers == null) {
15639                                    singleUserReceivers = new HashSet<ComponentName>();
15640                                }
15641                                singleUserReceivers.add(cn);
15642                            }
15643                        }
15644                    }
15645                    // Add the new results to the existing results, tracking
15646                    // and de-dupping single user receivers.
15647                    for (int i=0; i<newReceivers.size(); i++) {
15648                        ResolveInfo ri = newReceivers.get(i);
15649                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15650                            ComponentName cn = new ComponentName(
15651                                    ri.activityInfo.packageName, ri.activityInfo.name);
15652                            if (singleUserReceivers == null) {
15653                                singleUserReceivers = new HashSet<ComponentName>();
15654                            }
15655                            if (!singleUserReceivers.contains(cn)) {
15656                                singleUserReceivers.add(cn);
15657                                receivers.add(ri);
15658                            }
15659                        } else {
15660                            receivers.add(ri);
15661                        }
15662                    }
15663                }
15664            }
15665        } catch (RemoteException ex) {
15666            // pm is in same process, this will never happen.
15667        }
15668        return receivers;
15669    }
15670
15671    private final int broadcastIntentLocked(ProcessRecord callerApp,
15672            String callerPackage, Intent intent, String resolvedType,
15673            IIntentReceiver resultTo, int resultCode, String resultData,
15674            Bundle map, String requiredPermission, int appOp,
15675            boolean ordered, boolean sticky, int callingPid, int callingUid,
15676            int userId) {
15677        intent = new Intent(intent);
15678
15679        // By default broadcasts do not go to stopped apps.
15680        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15681
15682        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15683            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15684            + " ordered=" + ordered + " userid=" + userId);
15685        if ((resultTo != null) && !ordered) {
15686            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15687        }
15688
15689        userId = handleIncomingUser(callingPid, callingUid, userId,
15690                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15691
15692        // Make sure that the user who is receiving this broadcast is running.
15693        // If not, we will just skip it. Make an exception for shutdown broadcasts
15694        // and upgrade steps.
15695
15696        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15697            if ((callingUid != Process.SYSTEM_UID
15698                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15699                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15700                Slog.w(TAG, "Skipping broadcast of " + intent
15701                        + ": user " + userId + " is stopped");
15702                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15703            }
15704        }
15705
15706        /*
15707         * Prevent non-system code (defined here to be non-persistent
15708         * processes) from sending protected broadcasts.
15709         */
15710        int callingAppId = UserHandle.getAppId(callingUid);
15711        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15712            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15713            || callingAppId == Process.NFC_UID || callingUid == 0) {
15714            // Always okay.
15715        } else if (callerApp == null || !callerApp.persistent) {
15716            try {
15717                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15718                        intent.getAction())) {
15719                    String msg = "Permission Denial: not allowed to send broadcast "
15720                            + intent.getAction() + " from pid="
15721                            + callingPid + ", uid=" + callingUid;
15722                    Slog.w(TAG, msg);
15723                    throw new SecurityException(msg);
15724                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15725                    // Special case for compatibility: we don't want apps to send this,
15726                    // but historically it has not been protected and apps may be using it
15727                    // to poke their own app widget.  So, instead of making it protected,
15728                    // just limit it to the caller.
15729                    if (callerApp == null) {
15730                        String msg = "Permission Denial: not allowed to send broadcast "
15731                                + intent.getAction() + " from unknown caller.";
15732                        Slog.w(TAG, msg);
15733                        throw new SecurityException(msg);
15734                    } else if (intent.getComponent() != null) {
15735                        // They are good enough to send to an explicit component...  verify
15736                        // it is being sent to the calling app.
15737                        if (!intent.getComponent().getPackageName().equals(
15738                                callerApp.info.packageName)) {
15739                            String msg = "Permission Denial: not allowed to send broadcast "
15740                                    + intent.getAction() + " to "
15741                                    + intent.getComponent().getPackageName() + " from "
15742                                    + callerApp.info.packageName;
15743                            Slog.w(TAG, msg);
15744                            throw new SecurityException(msg);
15745                        }
15746                    } else {
15747                        // Limit broadcast to their own package.
15748                        intent.setPackage(callerApp.info.packageName);
15749                    }
15750                }
15751            } catch (RemoteException e) {
15752                Slog.w(TAG, "Remote exception", e);
15753                return ActivityManager.BROADCAST_SUCCESS;
15754            }
15755        }
15756
15757        final String action = intent.getAction();
15758        if (action != null) {
15759            switch (action) {
15760                case Intent.ACTION_UID_REMOVED:
15761                case Intent.ACTION_PACKAGE_REMOVED:
15762                case Intent.ACTION_PACKAGE_CHANGED:
15763                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15764                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15765                    // Handle special intents: if this broadcast is from the package
15766                    // manager about a package being removed, we need to remove all of
15767                    // its activities from the history stack.
15768                    if (checkComponentPermission(
15769                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15770                            callingPid, callingUid, -1, true)
15771                            != PackageManager.PERMISSION_GRANTED) {
15772                        String msg = "Permission Denial: " + intent.getAction()
15773                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15774                                + ", uid=" + callingUid + ")"
15775                                + " requires "
15776                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15777                        Slog.w(TAG, msg);
15778                        throw new SecurityException(msg);
15779                    }
15780                    switch (action) {
15781                        case Intent.ACTION_UID_REMOVED:
15782                            final Bundle intentExtras = intent.getExtras();
15783                            final int uid = intentExtras != null
15784                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15785                            if (uid >= 0) {
15786                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15787                                synchronized (bs) {
15788                                    bs.removeUidStatsLocked(uid);
15789                                }
15790                                mAppOpsService.uidRemoved(uid);
15791                            }
15792                            break;
15793                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15794                            // If resources are unavailable just force stop all those packages
15795                            // and flush the attribute cache as well.
15796                            String list[] =
15797                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15798                            if (list != null && list.length > 0) {
15799                                for (int i = 0; i < list.length; i++) {
15800                                    forceStopPackageLocked(list[i], -1, false, true, true,
15801                                            false, false, userId, "storage unmount");
15802                                }
15803                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15804                                sendPackageBroadcastLocked(
15805                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15806                                        userId);
15807                            }
15808                            break;
15809                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15810                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15811                            break;
15812                        case Intent.ACTION_PACKAGE_REMOVED:
15813                        case Intent.ACTION_PACKAGE_CHANGED:
15814                            Uri data = intent.getData();
15815                            String ssp;
15816                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15817                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15818                                boolean fullUninstall = removed &&
15819                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15820                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15821                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15822                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15823                                            false, true, true, false, fullUninstall, userId,
15824                                            removed ? "pkg removed" : "pkg changed");
15825                                }
15826                                if (removed) {
15827                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15828                                            new String[] {ssp}, userId);
15829                                    if (fullUninstall) {
15830                                        mAppOpsService.packageRemoved(
15831                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15832
15833                                        // Remove all permissions granted from/to this package
15834                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15835
15836                                        removeTasksByPackageNameLocked(ssp, userId);
15837                                    }
15838                                } else {
15839                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15840                                    if (userId == UserHandle.USER_OWNER) {
15841                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15842                                    }
15843                                }
15844                            }
15845                            break;
15846                    }
15847                    break;
15848                case Intent.ACTION_PACKAGE_ADDED:
15849                    // Special case for adding a package: by default turn on compatibility mode.
15850                    Uri data = intent.getData();
15851                    String ssp;
15852                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15853                        final boolean replacing =
15854                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15855                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15856
15857                        if (replacing) {
15858                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15859                        }
15860                        if (userId == UserHandle.USER_OWNER) {
15861                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15862                        }
15863                    }
15864                    break;
15865                case Intent.ACTION_TIMEZONE_CHANGED:
15866                    // If this is the time zone changed action, queue up a message that will reset
15867                    // the timezone of all currently running processes. This message will get
15868                    // queued up before the broadcast happens.
15869                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15870                    break;
15871                case Intent.ACTION_TIME_CHANGED:
15872                    // If the user set the time, let all running processes know.
15873                    final int is24Hour =
15874                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15875                                    : 0;
15876                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15877                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15878                    synchronized (stats) {
15879                        stats.noteCurrentTimeChangedLocked();
15880                    }
15881                    break;
15882                case Intent.ACTION_CLEAR_DNS_CACHE:
15883                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15884                    break;
15885                case Proxy.PROXY_CHANGE_ACTION:
15886                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15887                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15888                    break;
15889            }
15890        }
15891
15892        // Add to the sticky list if requested.
15893        if (sticky) {
15894            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15895                    callingPid, callingUid)
15896                    != PackageManager.PERMISSION_GRANTED) {
15897                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15898                        + callingPid + ", uid=" + callingUid
15899                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15900                Slog.w(TAG, msg);
15901                throw new SecurityException(msg);
15902            }
15903            if (requiredPermission != null) {
15904                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15905                        + " and enforce permission " + requiredPermission);
15906                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15907            }
15908            if (intent.getComponent() != null) {
15909                throw new SecurityException(
15910                        "Sticky broadcasts can't target a specific component");
15911            }
15912            // We use userId directly here, since the "all" target is maintained
15913            // as a separate set of sticky broadcasts.
15914            if (userId != UserHandle.USER_ALL) {
15915                // But first, if this is not a broadcast to all users, then
15916                // make sure it doesn't conflict with an existing broadcast to
15917                // all users.
15918                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15919                        UserHandle.USER_ALL);
15920                if (stickies != null) {
15921                    ArrayList<Intent> list = stickies.get(intent.getAction());
15922                    if (list != null) {
15923                        int N = list.size();
15924                        int i;
15925                        for (i=0; i<N; i++) {
15926                            if (intent.filterEquals(list.get(i))) {
15927                                throw new IllegalArgumentException(
15928                                        "Sticky broadcast " + intent + " for user "
15929                                        + userId + " conflicts with existing global broadcast");
15930                            }
15931                        }
15932                    }
15933                }
15934            }
15935            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15936            if (stickies == null) {
15937                stickies = new ArrayMap<String, ArrayList<Intent>>();
15938                mStickyBroadcasts.put(userId, stickies);
15939            }
15940            ArrayList<Intent> list = stickies.get(intent.getAction());
15941            if (list == null) {
15942                list = new ArrayList<Intent>();
15943                stickies.put(intent.getAction(), list);
15944            }
15945            int N = list.size();
15946            int i;
15947            for (i=0; i<N; i++) {
15948                if (intent.filterEquals(list.get(i))) {
15949                    // This sticky already exists, replace it.
15950                    list.set(i, new Intent(intent));
15951                    break;
15952                }
15953            }
15954            if (i >= N) {
15955                list.add(new Intent(intent));
15956            }
15957        }
15958
15959        int[] users;
15960        if (userId == UserHandle.USER_ALL) {
15961            // Caller wants broadcast to go to all started users.
15962            users = mStartedUserArray;
15963        } else {
15964            // Caller wants broadcast to go to one specific user.
15965            users = new int[] {userId};
15966        }
15967
15968        // Figure out who all will receive this broadcast.
15969        List receivers = null;
15970        List<BroadcastFilter> registeredReceivers = null;
15971        // Need to resolve the intent to interested receivers...
15972        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15973                 == 0) {
15974            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15975        }
15976        if (intent.getComponent() == null) {
15977            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15978                // Query one target user at a time, excluding shell-restricted users
15979                UserManagerService ums = getUserManagerLocked();
15980                for (int i = 0; i < users.length; i++) {
15981                    if (ums.hasUserRestriction(
15982                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15983                        continue;
15984                    }
15985                    List<BroadcastFilter> registeredReceiversForUser =
15986                            mReceiverResolver.queryIntent(intent,
15987                                    resolvedType, false, users[i]);
15988                    if (registeredReceivers == null) {
15989                        registeredReceivers = registeredReceiversForUser;
15990                    } else if (registeredReceiversForUser != null) {
15991                        registeredReceivers.addAll(registeredReceiversForUser);
15992                    }
15993                }
15994            } else {
15995                registeredReceivers = mReceiverResolver.queryIntent(intent,
15996                        resolvedType, false, userId);
15997            }
15998        }
15999
16000        final boolean replacePending =
16001                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16002
16003        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16004                + " replacePending=" + replacePending);
16005
16006        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16007        if (!ordered && NR > 0) {
16008            // If we are not serializing this broadcast, then send the
16009            // registered receivers separately so they don't wait for the
16010            // components to be launched.
16011            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16012            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16013                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16014                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16015                    ordered, sticky, false, userId);
16016            if (DEBUG_BROADCAST) Slog.v(
16017                    TAG, "Enqueueing parallel broadcast " + r);
16018            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16019            if (!replaced) {
16020                queue.enqueueParallelBroadcastLocked(r);
16021                queue.scheduleBroadcastsLocked();
16022            }
16023            registeredReceivers = null;
16024            NR = 0;
16025        }
16026
16027        // Merge into one list.
16028        int ir = 0;
16029        if (receivers != null) {
16030            // A special case for PACKAGE_ADDED: do not allow the package
16031            // being added to see this broadcast.  This prevents them from
16032            // using this as a back door to get run as soon as they are
16033            // installed.  Maybe in the future we want to have a special install
16034            // broadcast or such for apps, but we'd like to deliberately make
16035            // this decision.
16036            String skipPackages[] = null;
16037            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16038                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16039                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16040                Uri data = intent.getData();
16041                if (data != null) {
16042                    String pkgName = data.getSchemeSpecificPart();
16043                    if (pkgName != null) {
16044                        skipPackages = new String[] { pkgName };
16045                    }
16046                }
16047            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16048                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16049            }
16050            if (skipPackages != null && (skipPackages.length > 0)) {
16051                for (String skipPackage : skipPackages) {
16052                    if (skipPackage != null) {
16053                        int NT = receivers.size();
16054                        for (int it=0; it<NT; it++) {
16055                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16056                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16057                                receivers.remove(it);
16058                                it--;
16059                                NT--;
16060                            }
16061                        }
16062                    }
16063                }
16064            }
16065
16066            int NT = receivers != null ? receivers.size() : 0;
16067            int it = 0;
16068            ResolveInfo curt = null;
16069            BroadcastFilter curr = null;
16070            while (it < NT && ir < NR) {
16071                if (curt == null) {
16072                    curt = (ResolveInfo)receivers.get(it);
16073                }
16074                if (curr == null) {
16075                    curr = registeredReceivers.get(ir);
16076                }
16077                if (curr.getPriority() >= curt.priority) {
16078                    // Insert this broadcast record into the final list.
16079                    receivers.add(it, curr);
16080                    ir++;
16081                    curr = null;
16082                    it++;
16083                    NT++;
16084                } else {
16085                    // Skip to the next ResolveInfo in the final list.
16086                    it++;
16087                    curt = null;
16088                }
16089            }
16090        }
16091        while (ir < NR) {
16092            if (receivers == null) {
16093                receivers = new ArrayList();
16094            }
16095            receivers.add(registeredReceivers.get(ir));
16096            ir++;
16097        }
16098
16099        if ((receivers != null && receivers.size() > 0)
16100                || resultTo != null) {
16101            BroadcastQueue queue = broadcastQueueForIntent(intent);
16102            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16103                    callerPackage, callingPid, callingUid, resolvedType,
16104                    requiredPermission, appOp, receivers, resultTo, resultCode,
16105                    resultData, map, ordered, sticky, false, userId);
16106            if (DEBUG_BROADCAST) Slog.v(
16107                    TAG, "Enqueueing ordered broadcast " + r
16108                    + ": prev had " + queue.mOrderedBroadcasts.size());
16109            if (DEBUG_BROADCAST) {
16110                int seq = r.intent.getIntExtra("seq", -1);
16111                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16112            }
16113            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16114            if (!replaced) {
16115                queue.enqueueOrderedBroadcastLocked(r);
16116                queue.scheduleBroadcastsLocked();
16117            }
16118        }
16119
16120        return ActivityManager.BROADCAST_SUCCESS;
16121    }
16122
16123    final Intent verifyBroadcastLocked(Intent intent) {
16124        // Refuse possible leaked file descriptors
16125        if (intent != null && intent.hasFileDescriptors() == true) {
16126            throw new IllegalArgumentException("File descriptors passed in Intent");
16127        }
16128
16129        int flags = intent.getFlags();
16130
16131        if (!mProcessesReady) {
16132            // if the caller really truly claims to know what they're doing, go
16133            // ahead and allow the broadcast without launching any receivers
16134            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16135                intent = new Intent(intent);
16136                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16137            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16138                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16139                        + " before boot completion");
16140                throw new IllegalStateException("Cannot broadcast before boot completed");
16141            }
16142        }
16143
16144        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16145            throw new IllegalArgumentException(
16146                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16147        }
16148
16149        return intent;
16150    }
16151
16152    public final int broadcastIntent(IApplicationThread caller,
16153            Intent intent, String resolvedType, IIntentReceiver resultTo,
16154            int resultCode, String resultData, Bundle map,
16155            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16156        enforceNotIsolatedCaller("broadcastIntent");
16157        synchronized(this) {
16158            intent = verifyBroadcastLocked(intent);
16159
16160            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16161            final int callingPid = Binder.getCallingPid();
16162            final int callingUid = Binder.getCallingUid();
16163            final long origId = Binder.clearCallingIdentity();
16164            int res = broadcastIntentLocked(callerApp,
16165                    callerApp != null ? callerApp.info.packageName : null,
16166                    intent, resolvedType, resultTo,
16167                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16168                    callingPid, callingUid, userId);
16169            Binder.restoreCallingIdentity(origId);
16170            return res;
16171        }
16172    }
16173
16174    int broadcastIntentInPackage(String packageName, int uid,
16175            Intent intent, String resolvedType, IIntentReceiver resultTo,
16176            int resultCode, String resultData, Bundle map,
16177            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16178        synchronized(this) {
16179            intent = verifyBroadcastLocked(intent);
16180
16181            final long origId = Binder.clearCallingIdentity();
16182            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16183                    resultTo, resultCode, resultData, map, requiredPermission,
16184                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16185            Binder.restoreCallingIdentity(origId);
16186            return res;
16187        }
16188    }
16189
16190    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16191        // Refuse possible leaked file descriptors
16192        if (intent != null && intent.hasFileDescriptors() == true) {
16193            throw new IllegalArgumentException("File descriptors passed in Intent");
16194        }
16195
16196        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16197                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16198
16199        synchronized(this) {
16200            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16201                    != PackageManager.PERMISSION_GRANTED) {
16202                String msg = "Permission Denial: unbroadcastIntent() from pid="
16203                        + Binder.getCallingPid()
16204                        + ", uid=" + Binder.getCallingUid()
16205                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16206                Slog.w(TAG, msg);
16207                throw new SecurityException(msg);
16208            }
16209            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16210            if (stickies != null) {
16211                ArrayList<Intent> list = stickies.get(intent.getAction());
16212                if (list != null) {
16213                    int N = list.size();
16214                    int i;
16215                    for (i=0; i<N; i++) {
16216                        if (intent.filterEquals(list.get(i))) {
16217                            list.remove(i);
16218                            break;
16219                        }
16220                    }
16221                    if (list.size() <= 0) {
16222                        stickies.remove(intent.getAction());
16223                    }
16224                }
16225                if (stickies.size() <= 0) {
16226                    mStickyBroadcasts.remove(userId);
16227                }
16228            }
16229        }
16230    }
16231
16232    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16233            String resultData, Bundle resultExtras, boolean resultAbort) {
16234        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16235        if (r == null) {
16236            Slog.w(TAG, "finishReceiver called but not found on queue");
16237            return false;
16238        }
16239
16240        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16241    }
16242
16243    void backgroundServicesFinishedLocked(int userId) {
16244        for (BroadcastQueue queue : mBroadcastQueues) {
16245            queue.backgroundServicesFinishedLocked(userId);
16246        }
16247    }
16248
16249    public void finishReceiver(IBinder who, int resultCode, String resultData,
16250            Bundle resultExtras, boolean resultAbort) {
16251        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16252
16253        // Refuse possible leaked file descriptors
16254        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16255            throw new IllegalArgumentException("File descriptors passed in Bundle");
16256        }
16257
16258        final long origId = Binder.clearCallingIdentity();
16259        try {
16260            boolean doNext = false;
16261            BroadcastRecord r;
16262
16263            synchronized(this) {
16264                r = broadcastRecordForReceiverLocked(who);
16265                if (r != null) {
16266                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16267                        resultData, resultExtras, resultAbort, true);
16268                }
16269            }
16270
16271            if (doNext) {
16272                r.queue.processNextBroadcast(false);
16273            }
16274            trimApplications();
16275        } finally {
16276            Binder.restoreCallingIdentity(origId);
16277        }
16278    }
16279
16280    // =========================================================
16281    // INSTRUMENTATION
16282    // =========================================================
16283
16284    public boolean startInstrumentation(ComponentName className,
16285            String profileFile, int flags, Bundle arguments,
16286            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16287            int userId, String abiOverride) {
16288        enforceNotIsolatedCaller("startInstrumentation");
16289        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16290                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16291        // Refuse possible leaked file descriptors
16292        if (arguments != null && arguments.hasFileDescriptors()) {
16293            throw new IllegalArgumentException("File descriptors passed in Bundle");
16294        }
16295
16296        synchronized(this) {
16297            InstrumentationInfo ii = null;
16298            ApplicationInfo ai = null;
16299            try {
16300                ii = mContext.getPackageManager().getInstrumentationInfo(
16301                    className, STOCK_PM_FLAGS);
16302                ai = AppGlobals.getPackageManager().getApplicationInfo(
16303                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16304            } catch (PackageManager.NameNotFoundException e) {
16305            } catch (RemoteException e) {
16306            }
16307            if (ii == null) {
16308                reportStartInstrumentationFailure(watcher, className,
16309                        "Unable to find instrumentation info for: " + className);
16310                return false;
16311            }
16312            if (ai == null) {
16313                reportStartInstrumentationFailure(watcher, className,
16314                        "Unable to find instrumentation target package: " + ii.targetPackage);
16315                return false;
16316            }
16317
16318            int match = mContext.getPackageManager().checkSignatures(
16319                    ii.targetPackage, ii.packageName);
16320            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16321                String msg = "Permission Denial: starting instrumentation "
16322                        + className + " from pid="
16323                        + Binder.getCallingPid()
16324                        + ", uid=" + Binder.getCallingPid()
16325                        + " not allowed because package " + ii.packageName
16326                        + " does not have a signature matching the target "
16327                        + ii.targetPackage;
16328                reportStartInstrumentationFailure(watcher, className, msg);
16329                throw new SecurityException(msg);
16330            }
16331
16332            final long origId = Binder.clearCallingIdentity();
16333            // Instrumentation can kill and relaunch even persistent processes
16334            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16335                    "start instr");
16336            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16337            app.instrumentationClass = className;
16338            app.instrumentationInfo = ai;
16339            app.instrumentationProfileFile = profileFile;
16340            app.instrumentationArguments = arguments;
16341            app.instrumentationWatcher = watcher;
16342            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16343            app.instrumentationResultClass = className;
16344            Binder.restoreCallingIdentity(origId);
16345        }
16346
16347        return true;
16348    }
16349
16350    /**
16351     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16352     * error to the logs, but if somebody is watching, send the report there too.  This enables
16353     * the "am" command to report errors with more information.
16354     *
16355     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16356     * @param cn The component name of the instrumentation.
16357     * @param report The error report.
16358     */
16359    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16360            ComponentName cn, String report) {
16361        Slog.w(TAG, report);
16362        try {
16363            if (watcher != null) {
16364                Bundle results = new Bundle();
16365                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16366                results.putString("Error", report);
16367                watcher.instrumentationStatus(cn, -1, results);
16368            }
16369        } catch (RemoteException e) {
16370            Slog.w(TAG, e);
16371        }
16372    }
16373
16374    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16375        if (app.instrumentationWatcher != null) {
16376            try {
16377                // NOTE:  IInstrumentationWatcher *must* be oneway here
16378                app.instrumentationWatcher.instrumentationFinished(
16379                    app.instrumentationClass,
16380                    resultCode,
16381                    results);
16382            } catch (RemoteException e) {
16383            }
16384        }
16385        if (app.instrumentationUiAutomationConnection != null) {
16386            try {
16387                app.instrumentationUiAutomationConnection.shutdown();
16388            } catch (RemoteException re) {
16389                /* ignore */
16390            }
16391            // Only a UiAutomation can set this flag and now that
16392            // it is finished we make sure it is reset to its default.
16393            mUserIsMonkey = false;
16394        }
16395        app.instrumentationWatcher = null;
16396        app.instrumentationUiAutomationConnection = null;
16397        app.instrumentationClass = null;
16398        app.instrumentationInfo = null;
16399        app.instrumentationProfileFile = null;
16400        app.instrumentationArguments = null;
16401
16402        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16403                "finished inst");
16404    }
16405
16406    public void finishInstrumentation(IApplicationThread target,
16407            int resultCode, Bundle results) {
16408        int userId = UserHandle.getCallingUserId();
16409        // Refuse possible leaked file descriptors
16410        if (results != null && results.hasFileDescriptors()) {
16411            throw new IllegalArgumentException("File descriptors passed in Intent");
16412        }
16413
16414        synchronized(this) {
16415            ProcessRecord app = getRecordForAppLocked(target);
16416            if (app == null) {
16417                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16418                return;
16419            }
16420            final long origId = Binder.clearCallingIdentity();
16421            finishInstrumentationLocked(app, resultCode, results);
16422            Binder.restoreCallingIdentity(origId);
16423        }
16424    }
16425
16426    // =========================================================
16427    // CONFIGURATION
16428    // =========================================================
16429
16430    public ConfigurationInfo getDeviceConfigurationInfo() {
16431        ConfigurationInfo config = new ConfigurationInfo();
16432        synchronized (this) {
16433            config.reqTouchScreen = mConfiguration.touchscreen;
16434            config.reqKeyboardType = mConfiguration.keyboard;
16435            config.reqNavigation = mConfiguration.navigation;
16436            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16437                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16438                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16439            }
16440            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16441                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16442                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16443            }
16444            config.reqGlEsVersion = GL_ES_VERSION;
16445        }
16446        return config;
16447    }
16448
16449    ActivityStack getFocusedStack() {
16450        return mStackSupervisor.getFocusedStack();
16451    }
16452
16453    public Configuration getConfiguration() {
16454        Configuration ci;
16455        synchronized(this) {
16456            ci = new Configuration(mConfiguration);
16457        }
16458        return ci;
16459    }
16460
16461    public void updatePersistentConfiguration(Configuration values) {
16462        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16463                "updateConfiguration()");
16464        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16465                "updateConfiguration()");
16466        if (values == null) {
16467            throw new NullPointerException("Configuration must not be null");
16468        }
16469
16470        synchronized(this) {
16471            final long origId = Binder.clearCallingIdentity();
16472            updateConfigurationLocked(values, null, true, false);
16473            Binder.restoreCallingIdentity(origId);
16474        }
16475    }
16476
16477    public void updateConfiguration(Configuration values) {
16478        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16479                "updateConfiguration()");
16480
16481        synchronized(this) {
16482            if (values == null && mWindowManager != null) {
16483                // sentinel: fetch the current configuration from the window manager
16484                values = mWindowManager.computeNewConfiguration();
16485            }
16486
16487            if (mWindowManager != null) {
16488                mProcessList.applyDisplaySize(mWindowManager);
16489            }
16490
16491            final long origId = Binder.clearCallingIdentity();
16492            if (values != null) {
16493                Settings.System.clearConfiguration(values);
16494            }
16495            updateConfigurationLocked(values, null, false, false);
16496            Binder.restoreCallingIdentity(origId);
16497        }
16498    }
16499
16500    /**
16501     * Do either or both things: (1) change the current configuration, and (2)
16502     * make sure the given activity is running with the (now) current
16503     * configuration.  Returns true if the activity has been left running, or
16504     * false if <var>starting</var> is being destroyed to match the new
16505     * configuration.
16506     * @param persistent TODO
16507     */
16508    boolean updateConfigurationLocked(Configuration values,
16509            ActivityRecord starting, boolean persistent, boolean initLocale) {
16510        int changes = 0;
16511
16512        if (values != null) {
16513            Configuration newConfig = new Configuration(mConfiguration);
16514            changes = newConfig.updateFrom(values);
16515            if (changes != 0) {
16516                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16517                    Slog.i(TAG, "Updating configuration to: " + values);
16518                }
16519
16520                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16521
16522                if (values.locale != null && !initLocale) {
16523                    saveLocaleLocked(values.locale,
16524                                     !values.locale.equals(mConfiguration.locale),
16525                                     values.userSetLocale);
16526                }
16527
16528                mConfigurationSeq++;
16529                if (mConfigurationSeq <= 0) {
16530                    mConfigurationSeq = 1;
16531                }
16532                newConfig.seq = mConfigurationSeq;
16533                mConfiguration = newConfig;
16534                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16535                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16536                //mUsageStatsService.noteStartConfig(newConfig);
16537
16538                final Configuration configCopy = new Configuration(mConfiguration);
16539
16540                // TODO: If our config changes, should we auto dismiss any currently
16541                // showing dialogs?
16542                mShowDialogs = shouldShowDialogs(newConfig);
16543
16544                AttributeCache ac = AttributeCache.instance();
16545                if (ac != null) {
16546                    ac.updateConfiguration(configCopy);
16547                }
16548
16549                // Make sure all resources in our process are updated
16550                // right now, so that anyone who is going to retrieve
16551                // resource values after we return will be sure to get
16552                // the new ones.  This is especially important during
16553                // boot, where the first config change needs to guarantee
16554                // all resources have that config before following boot
16555                // code is executed.
16556                mSystemThread.applyConfigurationToResources(configCopy);
16557
16558                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16559                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16560                    msg.obj = new Configuration(configCopy);
16561                    mHandler.sendMessage(msg);
16562                }
16563
16564                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16565                    ProcessRecord app = mLruProcesses.get(i);
16566                    try {
16567                        if (app.thread != null) {
16568                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16569                                    + app.processName + " new config " + mConfiguration);
16570                            app.thread.scheduleConfigurationChanged(configCopy);
16571                        }
16572                    } catch (Exception e) {
16573                    }
16574                }
16575                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16576                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16577                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16578                        | Intent.FLAG_RECEIVER_FOREGROUND);
16579                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16580                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16581                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16582                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16583                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16584                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16585                    broadcastIntentLocked(null, null, intent,
16586                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16587                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16588                }
16589            }
16590        }
16591
16592        boolean kept = true;
16593        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16594        // mainStack is null during startup.
16595        if (mainStack != null) {
16596            if (changes != 0 && starting == null) {
16597                // If the configuration changed, and the caller is not already
16598                // in the process of starting an activity, then find the top
16599                // activity to check if its configuration needs to change.
16600                starting = mainStack.topRunningActivityLocked(null);
16601            }
16602
16603            if (starting != null) {
16604                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16605                // And we need to make sure at this point that all other activities
16606                // are made visible with the correct configuration.
16607                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16608            }
16609        }
16610
16611        if (values != null && mWindowManager != null) {
16612            mWindowManager.setNewConfiguration(mConfiguration);
16613        }
16614
16615        return kept;
16616    }
16617
16618    /**
16619     * Decide based on the configuration whether we should shouw the ANR,
16620     * crash, etc dialogs.  The idea is that if there is no affordnace to
16621     * press the on-screen buttons, we shouldn't show the dialog.
16622     *
16623     * A thought: SystemUI might also want to get told about this, the Power
16624     * dialog / global actions also might want different behaviors.
16625     */
16626    private static final boolean shouldShowDialogs(Configuration config) {
16627        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16628                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16629    }
16630
16631    /**
16632     * Save the locale.  You must be inside a synchronized (this) block.
16633     */
16634    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16635        if(isDiff) {
16636            SystemProperties.set("user.language", l.getLanguage());
16637            SystemProperties.set("user.region", l.getCountry());
16638        }
16639
16640        if(isPersist) {
16641            SystemProperties.set("persist.sys.language", l.getLanguage());
16642            SystemProperties.set("persist.sys.country", l.getCountry());
16643            SystemProperties.set("persist.sys.localevar", l.getVariant());
16644
16645            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16646        }
16647    }
16648
16649    @Override
16650    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16651        synchronized (this) {
16652            ActivityRecord srec = ActivityRecord.forToken(token);
16653            if (srec.task != null && srec.task.stack != null) {
16654                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16655            }
16656        }
16657        return false;
16658    }
16659
16660    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16661            Intent resultData) {
16662
16663        synchronized (this) {
16664            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16665            if (stack != null) {
16666                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16667            }
16668            return false;
16669        }
16670    }
16671
16672    public int getLaunchedFromUid(IBinder activityToken) {
16673        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16674        if (srec == null) {
16675            return -1;
16676        }
16677        return srec.launchedFromUid;
16678    }
16679
16680    public String getLaunchedFromPackage(IBinder activityToken) {
16681        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16682        if (srec == null) {
16683            return null;
16684        }
16685        return srec.launchedFromPackage;
16686    }
16687
16688    // =========================================================
16689    // LIFETIME MANAGEMENT
16690    // =========================================================
16691
16692    // Returns which broadcast queue the app is the current [or imminent] receiver
16693    // on, or 'null' if the app is not an active broadcast recipient.
16694    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16695        BroadcastRecord r = app.curReceiver;
16696        if (r != null) {
16697            return r.queue;
16698        }
16699
16700        // It's not the current receiver, but it might be starting up to become one
16701        synchronized (this) {
16702            for (BroadcastQueue queue : mBroadcastQueues) {
16703                r = queue.mPendingBroadcast;
16704                if (r != null && r.curApp == app) {
16705                    // found it; report which queue it's in
16706                    return queue;
16707                }
16708            }
16709        }
16710
16711        return null;
16712    }
16713
16714    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16715            boolean doingAll, long now) {
16716        if (mAdjSeq == app.adjSeq) {
16717            // This adjustment has already been computed.
16718            return app.curRawAdj;
16719        }
16720
16721        if (app.thread == null) {
16722            app.adjSeq = mAdjSeq;
16723            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16724            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16725            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16726        }
16727
16728        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16729        app.adjSource = null;
16730        app.adjTarget = null;
16731        app.empty = false;
16732        app.cached = false;
16733
16734        final int activitiesSize = app.activities.size();
16735
16736        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16737            // The max adjustment doesn't allow this app to be anything
16738            // below foreground, so it is not worth doing work for it.
16739            app.adjType = "fixed";
16740            app.adjSeq = mAdjSeq;
16741            app.curRawAdj = app.maxAdj;
16742            app.foregroundActivities = false;
16743            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16744            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16745            // System processes can do UI, and when they do we want to have
16746            // them trim their memory after the user leaves the UI.  To
16747            // facilitate this, here we need to determine whether or not it
16748            // is currently showing UI.
16749            app.systemNoUi = true;
16750            if (app == TOP_APP) {
16751                app.systemNoUi = false;
16752            } else if (activitiesSize > 0) {
16753                for (int j = 0; j < activitiesSize; j++) {
16754                    final ActivityRecord r = app.activities.get(j);
16755                    if (r.visible) {
16756                        app.systemNoUi = false;
16757                    }
16758                }
16759            }
16760            if (!app.systemNoUi) {
16761                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16762            }
16763            return (app.curAdj=app.maxAdj);
16764        }
16765
16766        app.systemNoUi = false;
16767
16768        // Determine the importance of the process, starting with most
16769        // important to least, and assign an appropriate OOM adjustment.
16770        int adj;
16771        int schedGroup;
16772        int procState;
16773        boolean foregroundActivities = false;
16774        BroadcastQueue queue;
16775        if (app == TOP_APP) {
16776            // The last app on the list is the foreground app.
16777            adj = ProcessList.FOREGROUND_APP_ADJ;
16778            schedGroup = Process.THREAD_GROUP_DEFAULT;
16779            app.adjType = "top-activity";
16780            foregroundActivities = true;
16781            procState = ActivityManager.PROCESS_STATE_TOP;
16782        } else if (app.instrumentationClass != null) {
16783            // Don't want to kill running instrumentation.
16784            adj = ProcessList.FOREGROUND_APP_ADJ;
16785            schedGroup = Process.THREAD_GROUP_DEFAULT;
16786            app.adjType = "instrumentation";
16787            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16788        } else if ((queue = isReceivingBroadcast(app)) != null) {
16789            // An app that is currently receiving a broadcast also
16790            // counts as being in the foreground for OOM killer purposes.
16791            // It's placed in a sched group based on the nature of the
16792            // broadcast as reflected by which queue it's active in.
16793            adj = ProcessList.FOREGROUND_APP_ADJ;
16794            schedGroup = (queue == mFgBroadcastQueue)
16795                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16796            app.adjType = "broadcast";
16797            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16798        } else if (app.executingServices.size() > 0) {
16799            // An app that is currently executing a service callback also
16800            // counts as being in the foreground.
16801            adj = ProcessList.FOREGROUND_APP_ADJ;
16802            schedGroup = app.execServicesFg ?
16803                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16804            app.adjType = "exec-service";
16805            procState = ActivityManager.PROCESS_STATE_SERVICE;
16806            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16807        } else {
16808            // As far as we know the process is empty.  We may change our mind later.
16809            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16810            // At this point we don't actually know the adjustment.  Use the cached adj
16811            // value that the caller wants us to.
16812            adj = cachedAdj;
16813            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16814            app.cached = true;
16815            app.empty = true;
16816            app.adjType = "cch-empty";
16817        }
16818
16819        // Examine all activities if not already foreground.
16820        if (!foregroundActivities && activitiesSize > 0) {
16821            for (int j = 0; j < activitiesSize; j++) {
16822                final ActivityRecord r = app.activities.get(j);
16823                if (r.app != app) {
16824                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16825                            + app + "?!?");
16826                    continue;
16827                }
16828                if (r.visible) {
16829                    // App has a visible activity; only upgrade adjustment.
16830                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16831                        adj = ProcessList.VISIBLE_APP_ADJ;
16832                        app.adjType = "visible";
16833                    }
16834                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16835                        procState = ActivityManager.PROCESS_STATE_TOP;
16836                    }
16837                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16838                    app.cached = false;
16839                    app.empty = false;
16840                    foregroundActivities = true;
16841                    break;
16842                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16843                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16844                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16845                        app.adjType = "pausing";
16846                    }
16847                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16848                        procState = ActivityManager.PROCESS_STATE_TOP;
16849                    }
16850                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16851                    app.cached = false;
16852                    app.empty = false;
16853                    foregroundActivities = true;
16854                } else if (r.state == ActivityState.STOPPING) {
16855                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16856                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16857                        app.adjType = "stopping";
16858                    }
16859                    // For the process state, we will at this point consider the
16860                    // process to be cached.  It will be cached either as an activity
16861                    // or empty depending on whether the activity is finishing.  We do
16862                    // this so that we can treat the process as cached for purposes of
16863                    // memory trimming (determing current memory level, trim command to
16864                    // send to process) since there can be an arbitrary number of stopping
16865                    // processes and they should soon all go into the cached state.
16866                    if (!r.finishing) {
16867                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16868                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16869                        }
16870                    }
16871                    app.cached = false;
16872                    app.empty = false;
16873                    foregroundActivities = true;
16874                } else {
16875                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16876                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16877                        app.adjType = "cch-act";
16878                    }
16879                }
16880            }
16881        }
16882
16883        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16884            if (app.foregroundServices) {
16885                // The user is aware of this app, so make it visible.
16886                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16887                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16888                app.cached = false;
16889                app.adjType = "fg-service";
16890                schedGroup = Process.THREAD_GROUP_DEFAULT;
16891            } else if (app.forcingToForeground != null) {
16892                // The user is aware of this app, so make it visible.
16893                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16894                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16895                app.cached = false;
16896                app.adjType = "force-fg";
16897                app.adjSource = app.forcingToForeground;
16898                schedGroup = Process.THREAD_GROUP_DEFAULT;
16899            }
16900        }
16901
16902        if (app == mHeavyWeightProcess) {
16903            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16904                // We don't want to kill the current heavy-weight process.
16905                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16906                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16907                app.cached = false;
16908                app.adjType = "heavy";
16909            }
16910            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16911                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16912            }
16913        }
16914
16915        if (app == mHomeProcess) {
16916            if (adj > ProcessList.HOME_APP_ADJ) {
16917                // This process is hosting what we currently consider to be the
16918                // home app, so we don't want to let it go into the background.
16919                adj = ProcessList.HOME_APP_ADJ;
16920                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16921                app.cached = false;
16922                app.adjType = "home";
16923            }
16924            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16925                procState = ActivityManager.PROCESS_STATE_HOME;
16926            }
16927        }
16928
16929        if (app == mPreviousProcess && app.activities.size() > 0) {
16930            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16931                // This was the previous process that showed UI to the user.
16932                // We want to try to keep it around more aggressively, to give
16933                // a good experience around switching between two apps.
16934                adj = ProcessList.PREVIOUS_APP_ADJ;
16935                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16936                app.cached = false;
16937                app.adjType = "previous";
16938            }
16939            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16940                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16941            }
16942        }
16943
16944        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16945                + " reason=" + app.adjType);
16946
16947        // By default, we use the computed adjustment.  It may be changed if
16948        // there are applications dependent on our services or providers, but
16949        // this gives us a baseline and makes sure we don't get into an
16950        // infinite recursion.
16951        app.adjSeq = mAdjSeq;
16952        app.curRawAdj = adj;
16953        app.hasStartedServices = false;
16954
16955        if (mBackupTarget != null && app == mBackupTarget.app) {
16956            // If possible we want to avoid killing apps while they're being backed up
16957            if (adj > ProcessList.BACKUP_APP_ADJ) {
16958                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16959                adj = ProcessList.BACKUP_APP_ADJ;
16960                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16961                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16962                }
16963                app.adjType = "backup";
16964                app.cached = false;
16965            }
16966            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16967                procState = ActivityManager.PROCESS_STATE_BACKUP;
16968            }
16969        }
16970
16971        boolean mayBeTop = false;
16972
16973        for (int is = app.services.size()-1;
16974                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16975                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16976                        || procState > ActivityManager.PROCESS_STATE_TOP);
16977                is--) {
16978            ServiceRecord s = app.services.valueAt(is);
16979            if (s.startRequested) {
16980                app.hasStartedServices = true;
16981                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16982                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16983                }
16984                if (app.hasShownUi && app != mHomeProcess) {
16985                    // If this process has shown some UI, let it immediately
16986                    // go to the LRU list because it may be pretty heavy with
16987                    // UI stuff.  We'll tag it with a label just to help
16988                    // debug and understand what is going on.
16989                    if (adj > ProcessList.SERVICE_ADJ) {
16990                        app.adjType = "cch-started-ui-services";
16991                    }
16992                } else {
16993                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16994                        // This service has seen some activity within
16995                        // recent memory, so we will keep its process ahead
16996                        // of the background processes.
16997                        if (adj > ProcessList.SERVICE_ADJ) {
16998                            adj = ProcessList.SERVICE_ADJ;
16999                            app.adjType = "started-services";
17000                            app.cached = false;
17001                        }
17002                    }
17003                    // If we have let the service slide into the background
17004                    // state, still have some text describing what it is doing
17005                    // even though the service no longer has an impact.
17006                    if (adj > ProcessList.SERVICE_ADJ) {
17007                        app.adjType = "cch-started-services";
17008                    }
17009                }
17010            }
17011            for (int conni = s.connections.size()-1;
17012                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17013                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17014                            || procState > ActivityManager.PROCESS_STATE_TOP);
17015                    conni--) {
17016                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17017                for (int i = 0;
17018                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17019                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17020                                || procState > ActivityManager.PROCESS_STATE_TOP);
17021                        i++) {
17022                    // XXX should compute this based on the max of
17023                    // all connected clients.
17024                    ConnectionRecord cr = clist.get(i);
17025                    if (cr.binding.client == app) {
17026                        // Binding to ourself is not interesting.
17027                        continue;
17028                    }
17029                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17030                        ProcessRecord client = cr.binding.client;
17031                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17032                                TOP_APP, doingAll, now);
17033                        int clientProcState = client.curProcState;
17034                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17035                            // If the other app is cached for any reason, for purposes here
17036                            // we are going to consider it empty.  The specific cached state
17037                            // doesn't propagate except under certain conditions.
17038                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17039                        }
17040                        String adjType = null;
17041                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17042                            // Not doing bind OOM management, so treat
17043                            // this guy more like a started service.
17044                            if (app.hasShownUi && app != mHomeProcess) {
17045                                // If this process has shown some UI, let it immediately
17046                                // go to the LRU list because it may be pretty heavy with
17047                                // UI stuff.  We'll tag it with a label just to help
17048                                // debug and understand what is going on.
17049                                if (adj > clientAdj) {
17050                                    adjType = "cch-bound-ui-services";
17051                                }
17052                                app.cached = false;
17053                                clientAdj = adj;
17054                                clientProcState = procState;
17055                            } else {
17056                                if (now >= (s.lastActivity
17057                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17058                                    // This service has not seen activity within
17059                                    // recent memory, so allow it to drop to the
17060                                    // LRU list if there is no other reason to keep
17061                                    // it around.  We'll also tag it with a label just
17062                                    // to help debug and undertand what is going on.
17063                                    if (adj > clientAdj) {
17064                                        adjType = "cch-bound-services";
17065                                    }
17066                                    clientAdj = adj;
17067                                }
17068                            }
17069                        }
17070                        if (adj > clientAdj) {
17071                            // If this process has recently shown UI, and
17072                            // the process that is binding to it is less
17073                            // important than being visible, then we don't
17074                            // care about the binding as much as we care
17075                            // about letting this process get into the LRU
17076                            // list to be killed and restarted if needed for
17077                            // memory.
17078                            if (app.hasShownUi && app != mHomeProcess
17079                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17080                                adjType = "cch-bound-ui-services";
17081                            } else {
17082                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17083                                        |Context.BIND_IMPORTANT)) != 0) {
17084                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17085                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17086                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17087                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17088                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17089                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17090                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17091                                    adj = clientAdj;
17092                                } else {
17093                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17094                                        adj = ProcessList.VISIBLE_APP_ADJ;
17095                                    }
17096                                }
17097                                if (!client.cached) {
17098                                    app.cached = false;
17099                                }
17100                                adjType = "service";
17101                            }
17102                        }
17103                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17104                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17105                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17106                            }
17107                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17108                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17109                                    // Special handling of clients who are in the top state.
17110                                    // We *may* want to consider this process to be in the
17111                                    // top state as well, but only if there is not another
17112                                    // reason for it to be running.  Being on the top is a
17113                                    // special state, meaning you are specifically running
17114                                    // for the current top app.  If the process is already
17115                                    // running in the background for some other reason, it
17116                                    // is more important to continue considering it to be
17117                                    // in the background state.
17118                                    mayBeTop = true;
17119                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17120                                } else {
17121                                    // Special handling for above-top states (persistent
17122                                    // processes).  These should not bring the current process
17123                                    // into the top state, since they are not on top.  Instead
17124                                    // give them the best state after that.
17125                                    clientProcState =
17126                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17127                                }
17128                            }
17129                        } else {
17130                            if (clientProcState <
17131                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17132                                clientProcState =
17133                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17134                            }
17135                        }
17136                        if (procState > clientProcState) {
17137                            procState = clientProcState;
17138                        }
17139                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17140                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17141                            app.pendingUiClean = true;
17142                        }
17143                        if (adjType != null) {
17144                            app.adjType = adjType;
17145                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17146                                    .REASON_SERVICE_IN_USE;
17147                            app.adjSource = cr.binding.client;
17148                            app.adjSourceProcState = clientProcState;
17149                            app.adjTarget = s.name;
17150                        }
17151                    }
17152                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17153                        app.treatLikeActivity = true;
17154                    }
17155                    final ActivityRecord a = cr.activity;
17156                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17157                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17158                                (a.visible || a.state == ActivityState.RESUMED
17159                                 || a.state == ActivityState.PAUSING)) {
17160                            adj = ProcessList.FOREGROUND_APP_ADJ;
17161                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17162                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17163                            }
17164                            app.cached = false;
17165                            app.adjType = "service";
17166                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17167                                    .REASON_SERVICE_IN_USE;
17168                            app.adjSource = a;
17169                            app.adjSourceProcState = procState;
17170                            app.adjTarget = s.name;
17171                        }
17172                    }
17173                }
17174            }
17175        }
17176
17177        for (int provi = app.pubProviders.size()-1;
17178                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17179                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17180                        || procState > ActivityManager.PROCESS_STATE_TOP);
17181                provi--) {
17182            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17183            for (int i = cpr.connections.size()-1;
17184                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17185                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17186                            || procState > ActivityManager.PROCESS_STATE_TOP);
17187                    i--) {
17188                ContentProviderConnection conn = cpr.connections.get(i);
17189                ProcessRecord client = conn.client;
17190                if (client == app) {
17191                    // Being our own client is not interesting.
17192                    continue;
17193                }
17194                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17195                int clientProcState = client.curProcState;
17196                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17197                    // If the other app is cached for any reason, for purposes here
17198                    // we are going to consider it empty.
17199                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17200                }
17201                if (adj > clientAdj) {
17202                    if (app.hasShownUi && app != mHomeProcess
17203                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17204                        app.adjType = "cch-ui-provider";
17205                    } else {
17206                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17207                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17208                        app.adjType = "provider";
17209                    }
17210                    app.cached &= client.cached;
17211                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17212                            .REASON_PROVIDER_IN_USE;
17213                    app.adjSource = client;
17214                    app.adjSourceProcState = clientProcState;
17215                    app.adjTarget = cpr.name;
17216                }
17217                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17218                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17219                        // Special handling of clients who are in the top state.
17220                        // We *may* want to consider this process to be in the
17221                        // top state as well, but only if there is not another
17222                        // reason for it to be running.  Being on the top is a
17223                        // special state, meaning you are specifically running
17224                        // for the current top app.  If the process is already
17225                        // running in the background for some other reason, it
17226                        // is more important to continue considering it to be
17227                        // in the background state.
17228                        mayBeTop = true;
17229                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17230                    } else {
17231                        // Special handling for above-top states (persistent
17232                        // processes).  These should not bring the current process
17233                        // into the top state, since they are not on top.  Instead
17234                        // give them the best state after that.
17235                        clientProcState =
17236                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17237                    }
17238                }
17239                if (procState > clientProcState) {
17240                    procState = clientProcState;
17241                }
17242                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17243                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17244                }
17245            }
17246            // If the provider has external (non-framework) process
17247            // dependencies, ensure that its adjustment is at least
17248            // FOREGROUND_APP_ADJ.
17249            if (cpr.hasExternalProcessHandles()) {
17250                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17251                    adj = ProcessList.FOREGROUND_APP_ADJ;
17252                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17253                    app.cached = false;
17254                    app.adjType = "provider";
17255                    app.adjTarget = cpr.name;
17256                }
17257                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17258                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17259                }
17260            }
17261        }
17262
17263        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17264            // A client of one of our services or providers is in the top state.  We
17265            // *may* want to be in the top state, but not if we are already running in
17266            // the background for some other reason.  For the decision here, we are going
17267            // to pick out a few specific states that we want to remain in when a client
17268            // is top (states that tend to be longer-term) and otherwise allow it to go
17269            // to the top state.
17270            switch (procState) {
17271                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17272                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17273                case ActivityManager.PROCESS_STATE_SERVICE:
17274                    // These all are longer-term states, so pull them up to the top
17275                    // of the background states, but not all the way to the top state.
17276                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17277                    break;
17278                default:
17279                    // Otherwise, top is a better choice, so take it.
17280                    procState = ActivityManager.PROCESS_STATE_TOP;
17281                    break;
17282            }
17283        }
17284
17285        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17286            if (app.hasClientActivities) {
17287                // This is a cached process, but with client activities.  Mark it so.
17288                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17289                app.adjType = "cch-client-act";
17290            } else if (app.treatLikeActivity) {
17291                // This is a cached process, but somebody wants us to treat it like it has
17292                // an activity, okay!
17293                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17294                app.adjType = "cch-as-act";
17295            }
17296        }
17297
17298        if (adj == ProcessList.SERVICE_ADJ) {
17299            if (doingAll) {
17300                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17301                mNewNumServiceProcs++;
17302                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17303                if (!app.serviceb) {
17304                    // This service isn't far enough down on the LRU list to
17305                    // normally be a B service, but if we are low on RAM and it
17306                    // is large we want to force it down since we would prefer to
17307                    // keep launcher over it.
17308                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17309                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17310                        app.serviceHighRam = true;
17311                        app.serviceb = true;
17312                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17313                    } else {
17314                        mNewNumAServiceProcs++;
17315                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17316                    }
17317                } else {
17318                    app.serviceHighRam = false;
17319                }
17320            }
17321            if (app.serviceb) {
17322                adj = ProcessList.SERVICE_B_ADJ;
17323            }
17324        }
17325
17326        app.curRawAdj = adj;
17327
17328        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17329        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17330        if (adj > app.maxAdj) {
17331            adj = app.maxAdj;
17332            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17333                schedGroup = Process.THREAD_GROUP_DEFAULT;
17334            }
17335        }
17336
17337        // Do final modification to adj.  Everything we do between here and applying
17338        // the final setAdj must be done in this function, because we will also use
17339        // it when computing the final cached adj later.  Note that we don't need to
17340        // worry about this for max adj above, since max adj will always be used to
17341        // keep it out of the cached vaues.
17342        app.curAdj = app.modifyRawOomAdj(adj);
17343        app.curSchedGroup = schedGroup;
17344        app.curProcState = procState;
17345        app.foregroundActivities = foregroundActivities;
17346
17347        return app.curRawAdj;
17348    }
17349
17350    /**
17351     * Record new PSS sample for a process.
17352     */
17353    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17354        proc.lastPssTime = now;
17355        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17356        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17357                + ": " + pss + " lastPss=" + proc.lastPss
17358                + " state=" + ProcessList.makeProcStateString(procState));
17359        if (proc.initialIdlePss == 0) {
17360            proc.initialIdlePss = pss;
17361        }
17362        proc.lastPss = pss;
17363        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17364            proc.lastCachedPss = pss;
17365        }
17366    }
17367
17368    /**
17369     * Schedule PSS collection of a process.
17370     */
17371    void requestPssLocked(ProcessRecord proc, int procState) {
17372        if (mPendingPssProcesses.contains(proc)) {
17373            return;
17374        }
17375        if (mPendingPssProcesses.size() == 0) {
17376            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17377        }
17378        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17379        proc.pssProcState = procState;
17380        mPendingPssProcesses.add(proc);
17381    }
17382
17383    /**
17384     * Schedule PSS collection of all processes.
17385     */
17386    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17387        if (!always) {
17388            if (now < (mLastFullPssTime +
17389                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17390                return;
17391            }
17392        }
17393        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17394        mLastFullPssTime = now;
17395        mFullPssPending = true;
17396        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17397        mPendingPssProcesses.clear();
17398        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17399            ProcessRecord app = mLruProcesses.get(i);
17400            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17401                app.pssProcState = app.setProcState;
17402                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17403                        mTestPssMode, isSleeping(), now);
17404                mPendingPssProcesses.add(app);
17405            }
17406        }
17407        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17408    }
17409
17410    public void setTestPssMode(boolean enabled) {
17411        synchronized (this) {
17412            mTestPssMode = enabled;
17413            if (enabled) {
17414                // Whenever we enable the mode, we want to take a snapshot all of current
17415                // process mem use.
17416                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17417            }
17418        }
17419    }
17420
17421    /**
17422     * Ask a given process to GC right now.
17423     */
17424    final void performAppGcLocked(ProcessRecord app) {
17425        try {
17426            app.lastRequestedGc = SystemClock.uptimeMillis();
17427            if (app.thread != null) {
17428                if (app.reportLowMemory) {
17429                    app.reportLowMemory = false;
17430                    app.thread.scheduleLowMemory();
17431                } else {
17432                    app.thread.processInBackground();
17433                }
17434            }
17435        } catch (Exception e) {
17436            // whatever.
17437        }
17438    }
17439
17440    /**
17441     * Returns true if things are idle enough to perform GCs.
17442     */
17443    private final boolean canGcNowLocked() {
17444        boolean processingBroadcasts = false;
17445        for (BroadcastQueue q : mBroadcastQueues) {
17446            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17447                processingBroadcasts = true;
17448            }
17449        }
17450        return !processingBroadcasts
17451                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17452    }
17453
17454    /**
17455     * Perform GCs on all processes that are waiting for it, but only
17456     * if things are idle.
17457     */
17458    final void performAppGcsLocked() {
17459        final int N = mProcessesToGc.size();
17460        if (N <= 0) {
17461            return;
17462        }
17463        if (canGcNowLocked()) {
17464            while (mProcessesToGc.size() > 0) {
17465                ProcessRecord proc = mProcessesToGc.remove(0);
17466                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17467                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17468                            <= SystemClock.uptimeMillis()) {
17469                        // To avoid spamming the system, we will GC processes one
17470                        // at a time, waiting a few seconds between each.
17471                        performAppGcLocked(proc);
17472                        scheduleAppGcsLocked();
17473                        return;
17474                    } else {
17475                        // It hasn't been long enough since we last GCed this
17476                        // process...  put it in the list to wait for its time.
17477                        addProcessToGcListLocked(proc);
17478                        break;
17479                    }
17480                }
17481            }
17482
17483            scheduleAppGcsLocked();
17484        }
17485    }
17486
17487    /**
17488     * If all looks good, perform GCs on all processes waiting for them.
17489     */
17490    final void performAppGcsIfAppropriateLocked() {
17491        if (canGcNowLocked()) {
17492            performAppGcsLocked();
17493            return;
17494        }
17495        // Still not idle, wait some more.
17496        scheduleAppGcsLocked();
17497    }
17498
17499    /**
17500     * Schedule the execution of all pending app GCs.
17501     */
17502    final void scheduleAppGcsLocked() {
17503        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17504
17505        if (mProcessesToGc.size() > 0) {
17506            // Schedule a GC for the time to the next process.
17507            ProcessRecord proc = mProcessesToGc.get(0);
17508            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17509
17510            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17511            long now = SystemClock.uptimeMillis();
17512            if (when < (now+GC_TIMEOUT)) {
17513                when = now + GC_TIMEOUT;
17514            }
17515            mHandler.sendMessageAtTime(msg, when);
17516        }
17517    }
17518
17519    /**
17520     * Add a process to the array of processes waiting to be GCed.  Keeps the
17521     * list in sorted order by the last GC time.  The process can't already be
17522     * on the list.
17523     */
17524    final void addProcessToGcListLocked(ProcessRecord proc) {
17525        boolean added = false;
17526        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17527            if (mProcessesToGc.get(i).lastRequestedGc <
17528                    proc.lastRequestedGc) {
17529                added = true;
17530                mProcessesToGc.add(i+1, proc);
17531                break;
17532            }
17533        }
17534        if (!added) {
17535            mProcessesToGc.add(0, proc);
17536        }
17537    }
17538
17539    /**
17540     * Set up to ask a process to GC itself.  This will either do it
17541     * immediately, or put it on the list of processes to gc the next
17542     * time things are idle.
17543     */
17544    final void scheduleAppGcLocked(ProcessRecord app) {
17545        long now = SystemClock.uptimeMillis();
17546        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17547            return;
17548        }
17549        if (!mProcessesToGc.contains(app)) {
17550            addProcessToGcListLocked(app);
17551            scheduleAppGcsLocked();
17552        }
17553    }
17554
17555    final void checkExcessivePowerUsageLocked(boolean doKills) {
17556        updateCpuStatsNow();
17557
17558        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17559        boolean doWakeKills = doKills;
17560        boolean doCpuKills = doKills;
17561        if (mLastPowerCheckRealtime == 0) {
17562            doWakeKills = false;
17563        }
17564        if (mLastPowerCheckUptime == 0) {
17565            doCpuKills = false;
17566        }
17567        if (stats.isScreenOn()) {
17568            doWakeKills = false;
17569        }
17570        final long curRealtime = SystemClock.elapsedRealtime();
17571        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17572        final long curUptime = SystemClock.uptimeMillis();
17573        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17574        mLastPowerCheckRealtime = curRealtime;
17575        mLastPowerCheckUptime = curUptime;
17576        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17577            doWakeKills = false;
17578        }
17579        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17580            doCpuKills = false;
17581        }
17582        int i = mLruProcesses.size();
17583        while (i > 0) {
17584            i--;
17585            ProcessRecord app = mLruProcesses.get(i);
17586            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17587                long wtime;
17588                synchronized (stats) {
17589                    wtime = stats.getProcessWakeTime(app.info.uid,
17590                            app.pid, curRealtime);
17591                }
17592                long wtimeUsed = wtime - app.lastWakeTime;
17593                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17594                if (DEBUG_POWER) {
17595                    StringBuilder sb = new StringBuilder(128);
17596                    sb.append("Wake for ");
17597                    app.toShortString(sb);
17598                    sb.append(": over ");
17599                    TimeUtils.formatDuration(realtimeSince, sb);
17600                    sb.append(" used ");
17601                    TimeUtils.formatDuration(wtimeUsed, sb);
17602                    sb.append(" (");
17603                    sb.append((wtimeUsed*100)/realtimeSince);
17604                    sb.append("%)");
17605                    Slog.i(TAG, sb.toString());
17606                    sb.setLength(0);
17607                    sb.append("CPU for ");
17608                    app.toShortString(sb);
17609                    sb.append(": over ");
17610                    TimeUtils.formatDuration(uptimeSince, sb);
17611                    sb.append(" used ");
17612                    TimeUtils.formatDuration(cputimeUsed, sb);
17613                    sb.append(" (");
17614                    sb.append((cputimeUsed*100)/uptimeSince);
17615                    sb.append("%)");
17616                    Slog.i(TAG, sb.toString());
17617                }
17618                // If a process has held a wake lock for more
17619                // than 50% of the time during this period,
17620                // that sounds bad.  Kill!
17621                if (doWakeKills && realtimeSince > 0
17622                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17623                    synchronized (stats) {
17624                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17625                                realtimeSince, wtimeUsed);
17626                    }
17627                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17628                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17629                } else if (doCpuKills && uptimeSince > 0
17630                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17631                    synchronized (stats) {
17632                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17633                                uptimeSince, cputimeUsed);
17634                    }
17635                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17636                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17637                } else {
17638                    app.lastWakeTime = wtime;
17639                    app.lastCpuTime = app.curCpuTime;
17640                }
17641            }
17642        }
17643    }
17644
17645    private final boolean applyOomAdjLocked(ProcessRecord app,
17646            ProcessRecord TOP_APP, boolean doingAll, long now) {
17647        boolean success = true;
17648
17649        if (app.curRawAdj != app.setRawAdj) {
17650            app.setRawAdj = app.curRawAdj;
17651        }
17652
17653        int changes = 0;
17654
17655        if (app.curAdj != app.setAdj) {
17656            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17657            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17658                TAG, "Set " + app.pid + " " + app.processName +
17659                " adj " + app.curAdj + ": " + app.adjType);
17660            app.setAdj = app.curAdj;
17661        }
17662
17663        if (app.setSchedGroup != app.curSchedGroup) {
17664            app.setSchedGroup = app.curSchedGroup;
17665            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17666                    "Setting process group of " + app.processName
17667                    + " to " + app.curSchedGroup);
17668            if (app.waitingToKill != null &&
17669                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17670                app.kill(app.waitingToKill, true);
17671                success = false;
17672            } else {
17673                if (true) {
17674                    long oldId = Binder.clearCallingIdentity();
17675                    try {
17676                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17677                    } catch (Exception e) {
17678                        Slog.w(TAG, "Failed setting process group of " + app.pid
17679                                + " to " + app.curSchedGroup);
17680                        e.printStackTrace();
17681                    } finally {
17682                        Binder.restoreCallingIdentity(oldId);
17683                    }
17684                } else {
17685                    if (app.thread != null) {
17686                        try {
17687                            app.thread.setSchedulingGroup(app.curSchedGroup);
17688                        } catch (RemoteException e) {
17689                        }
17690                    }
17691                }
17692                Process.setSwappiness(app.pid,
17693                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17694            }
17695        }
17696        if (app.repForegroundActivities != app.foregroundActivities) {
17697            app.repForegroundActivities = app.foregroundActivities;
17698            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17699        }
17700        if (app.repProcState != app.curProcState) {
17701            app.repProcState = app.curProcState;
17702            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17703            if (app.thread != null) {
17704                try {
17705                    if (false) {
17706                        //RuntimeException h = new RuntimeException("here");
17707                        Slog.i(TAG, "Sending new process state " + app.repProcState
17708                                + " to " + app /*, h*/);
17709                    }
17710                    app.thread.setProcessState(app.repProcState);
17711                } catch (RemoteException e) {
17712                }
17713            }
17714        }
17715        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17716                app.setProcState)) {
17717            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17718                // Experimental code to more aggressively collect pss while
17719                // running test...  the problem is that this tends to collect
17720                // the data right when a process is transitioning between process
17721                // states, which well tend to give noisy data.
17722                long start = SystemClock.uptimeMillis();
17723                long pss = Debug.getPss(app.pid, mTmpLong, null);
17724                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17725                mPendingPssProcesses.remove(app);
17726                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17727                        + " to " + app.curProcState + ": "
17728                        + (SystemClock.uptimeMillis()-start) + "ms");
17729            }
17730            app.lastStateTime = now;
17731            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17732                    mTestPssMode, isSleeping(), now);
17733            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17734                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17735                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17736                    + (app.nextPssTime-now) + ": " + app);
17737        } else {
17738            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17739                    && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
17740                    mTestPssMode)))) {
17741                requestPssLocked(app, app.setProcState);
17742                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17743                        mTestPssMode, isSleeping(), now);
17744            } else if (false && DEBUG_PSS) {
17745                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17746            }
17747        }
17748        if (app.setProcState != app.curProcState) {
17749            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17750                    "Proc state change of " + app.processName
17751                    + " to " + app.curProcState);
17752            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17753            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17754            if (setImportant && !curImportant) {
17755                // This app is no longer something we consider important enough to allow to
17756                // use arbitrary amounts of battery power.  Note
17757                // its current wake lock time to later know to kill it if
17758                // it is not behaving well.
17759                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17760                synchronized (stats) {
17761                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17762                            app.pid, SystemClock.elapsedRealtime());
17763                }
17764                app.lastCpuTime = app.curCpuTime;
17765
17766            }
17767            app.setProcState = app.curProcState;
17768            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17769                app.notCachedSinceIdle = false;
17770            }
17771            if (!doingAll) {
17772                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17773            } else {
17774                app.procStateChanged = true;
17775            }
17776        }
17777
17778        if (changes != 0) {
17779            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17780            int i = mPendingProcessChanges.size()-1;
17781            ProcessChangeItem item = null;
17782            while (i >= 0) {
17783                item = mPendingProcessChanges.get(i);
17784                if (item.pid == app.pid) {
17785                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17786                    break;
17787                }
17788                i--;
17789            }
17790            if (i < 0) {
17791                // No existing item in pending changes; need a new one.
17792                final int NA = mAvailProcessChanges.size();
17793                if (NA > 0) {
17794                    item = mAvailProcessChanges.remove(NA-1);
17795                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17796                } else {
17797                    item = new ProcessChangeItem();
17798                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17799                }
17800                item.changes = 0;
17801                item.pid = app.pid;
17802                item.uid = app.info.uid;
17803                if (mPendingProcessChanges.size() == 0) {
17804                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17805                            "*** Enqueueing dispatch processes changed!");
17806                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17807                }
17808                mPendingProcessChanges.add(item);
17809            }
17810            item.changes |= changes;
17811            item.processState = app.repProcState;
17812            item.foregroundActivities = app.repForegroundActivities;
17813            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17814                    + Integer.toHexString(System.identityHashCode(item))
17815                    + " " + app.toShortString() + ": changes=" + item.changes
17816                    + " procState=" + item.processState
17817                    + " foreground=" + item.foregroundActivities
17818                    + " type=" + app.adjType + " source=" + app.adjSource
17819                    + " target=" + app.adjTarget);
17820        }
17821
17822        return success;
17823    }
17824
17825    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17826        if (proc.thread != null) {
17827            if (proc.baseProcessTracker != null) {
17828                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17829            }
17830            if (proc.repProcState >= 0) {
17831                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17832                        proc.repProcState);
17833            }
17834        }
17835    }
17836
17837    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17838            ProcessRecord TOP_APP, boolean doingAll, long now) {
17839        if (app.thread == null) {
17840            return false;
17841        }
17842
17843        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17844
17845        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17846    }
17847
17848    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17849            boolean oomAdj) {
17850        if (isForeground != proc.foregroundServices) {
17851            proc.foregroundServices = isForeground;
17852            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17853                    proc.info.uid);
17854            if (isForeground) {
17855                if (curProcs == null) {
17856                    curProcs = new ArrayList<ProcessRecord>();
17857                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17858                }
17859                if (!curProcs.contains(proc)) {
17860                    curProcs.add(proc);
17861                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17862                            proc.info.packageName, proc.info.uid);
17863                }
17864            } else {
17865                if (curProcs != null) {
17866                    if (curProcs.remove(proc)) {
17867                        mBatteryStatsService.noteEvent(
17868                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17869                                proc.info.packageName, proc.info.uid);
17870                        if (curProcs.size() <= 0) {
17871                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17872                        }
17873                    }
17874                }
17875            }
17876            if (oomAdj) {
17877                updateOomAdjLocked();
17878            }
17879        }
17880    }
17881
17882    private final ActivityRecord resumedAppLocked() {
17883        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17884        String pkg;
17885        int uid;
17886        if (act != null) {
17887            pkg = act.packageName;
17888            uid = act.info.applicationInfo.uid;
17889        } else {
17890            pkg = null;
17891            uid = -1;
17892        }
17893        // Has the UID or resumed package name changed?
17894        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17895                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17896            if (mCurResumedPackage != null) {
17897                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17898                        mCurResumedPackage, mCurResumedUid);
17899            }
17900            mCurResumedPackage = pkg;
17901            mCurResumedUid = uid;
17902            if (mCurResumedPackage != null) {
17903                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17904                        mCurResumedPackage, mCurResumedUid);
17905            }
17906        }
17907        return act;
17908    }
17909
17910    final boolean updateOomAdjLocked(ProcessRecord app) {
17911        final ActivityRecord TOP_ACT = resumedAppLocked();
17912        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17913        final boolean wasCached = app.cached;
17914
17915        mAdjSeq++;
17916
17917        // This is the desired cached adjusment we want to tell it to use.
17918        // If our app is currently cached, we know it, and that is it.  Otherwise,
17919        // we don't know it yet, and it needs to now be cached we will then
17920        // need to do a complete oom adj.
17921        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17922                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17923        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17924                SystemClock.uptimeMillis());
17925        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17926            // Changed to/from cached state, so apps after it in the LRU
17927            // list may also be changed.
17928            updateOomAdjLocked();
17929        }
17930        return success;
17931    }
17932
17933    final void updateOomAdjLocked() {
17934        final ActivityRecord TOP_ACT = resumedAppLocked();
17935        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17936        final long now = SystemClock.uptimeMillis();
17937        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17938        final int N = mLruProcesses.size();
17939
17940        if (false) {
17941            RuntimeException e = new RuntimeException();
17942            e.fillInStackTrace();
17943            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17944        }
17945
17946        mAdjSeq++;
17947        mNewNumServiceProcs = 0;
17948        mNewNumAServiceProcs = 0;
17949
17950        final int emptyProcessLimit;
17951        final int cachedProcessLimit;
17952        if (mProcessLimit <= 0) {
17953            emptyProcessLimit = cachedProcessLimit = 0;
17954        } else if (mProcessLimit == 1) {
17955            emptyProcessLimit = 1;
17956            cachedProcessLimit = 0;
17957        } else {
17958            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17959            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17960        }
17961
17962        // Let's determine how many processes we have running vs.
17963        // how many slots we have for background processes; we may want
17964        // to put multiple processes in a slot of there are enough of
17965        // them.
17966        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17967                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17968        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17969        if (numEmptyProcs > cachedProcessLimit) {
17970            // If there are more empty processes than our limit on cached
17971            // processes, then use the cached process limit for the factor.
17972            // This ensures that the really old empty processes get pushed
17973            // down to the bottom, so if we are running low on memory we will
17974            // have a better chance at keeping around more cached processes
17975            // instead of a gazillion empty processes.
17976            numEmptyProcs = cachedProcessLimit;
17977        }
17978        int emptyFactor = numEmptyProcs/numSlots;
17979        if (emptyFactor < 1) emptyFactor = 1;
17980        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17981        if (cachedFactor < 1) cachedFactor = 1;
17982        int stepCached = 0;
17983        int stepEmpty = 0;
17984        int numCached = 0;
17985        int numEmpty = 0;
17986        int numTrimming = 0;
17987
17988        mNumNonCachedProcs = 0;
17989        mNumCachedHiddenProcs = 0;
17990
17991        // First update the OOM adjustment for each of the
17992        // application processes based on their current state.
17993        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17994        int nextCachedAdj = curCachedAdj+1;
17995        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17996        int nextEmptyAdj = curEmptyAdj+2;
17997        for (int i=N-1; i>=0; i--) {
17998            ProcessRecord app = mLruProcesses.get(i);
17999            if (!app.killedByAm && app.thread != null) {
18000                app.procStateChanged = false;
18001                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18002
18003                // If we haven't yet assigned the final cached adj
18004                // to the process, do that now.
18005                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18006                    switch (app.curProcState) {
18007                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18008                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18009                            // This process is a cached process holding activities...
18010                            // assign it the next cached value for that type, and then
18011                            // step that cached level.
18012                            app.curRawAdj = curCachedAdj;
18013                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18014                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18015                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18016                                    + ")");
18017                            if (curCachedAdj != nextCachedAdj) {
18018                                stepCached++;
18019                                if (stepCached >= cachedFactor) {
18020                                    stepCached = 0;
18021                                    curCachedAdj = nextCachedAdj;
18022                                    nextCachedAdj += 2;
18023                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18024                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18025                                    }
18026                                }
18027                            }
18028                            break;
18029                        default:
18030                            // For everything else, assign next empty cached process
18031                            // level and bump that up.  Note that this means that
18032                            // long-running services that have dropped down to the
18033                            // cached level will be treated as empty (since their process
18034                            // state is still as a service), which is what we want.
18035                            app.curRawAdj = curEmptyAdj;
18036                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18037                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18038                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18039                                    + ")");
18040                            if (curEmptyAdj != nextEmptyAdj) {
18041                                stepEmpty++;
18042                                if (stepEmpty >= emptyFactor) {
18043                                    stepEmpty = 0;
18044                                    curEmptyAdj = nextEmptyAdj;
18045                                    nextEmptyAdj += 2;
18046                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18047                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18048                                    }
18049                                }
18050                            }
18051                            break;
18052                    }
18053                }
18054
18055                applyOomAdjLocked(app, TOP_APP, true, now);
18056
18057                // Count the number of process types.
18058                switch (app.curProcState) {
18059                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18060                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18061                        mNumCachedHiddenProcs++;
18062                        numCached++;
18063                        if (numCached > cachedProcessLimit) {
18064                            app.kill("cached #" + numCached, true);
18065                        }
18066                        break;
18067                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18068                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18069                                && app.lastActivityTime < oldTime) {
18070                            app.kill("empty for "
18071                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18072                                    / 1000) + "s", true);
18073                        } else {
18074                            numEmpty++;
18075                            if (numEmpty > emptyProcessLimit) {
18076                                app.kill("empty #" + numEmpty, true);
18077                            }
18078                        }
18079                        break;
18080                    default:
18081                        mNumNonCachedProcs++;
18082                        break;
18083                }
18084
18085                if (app.isolated && app.services.size() <= 0) {
18086                    // If this is an isolated process, and there are no
18087                    // services running in it, then the process is no longer
18088                    // needed.  We agressively kill these because we can by
18089                    // definition not re-use the same process again, and it is
18090                    // good to avoid having whatever code was running in them
18091                    // left sitting around after no longer needed.
18092                    app.kill("isolated not needed", true);
18093                }
18094
18095                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18096                        && !app.killedByAm) {
18097                    numTrimming++;
18098                }
18099            }
18100        }
18101
18102        mNumServiceProcs = mNewNumServiceProcs;
18103
18104        // Now determine the memory trimming level of background processes.
18105        // Unfortunately we need to start at the back of the list to do this
18106        // properly.  We only do this if the number of background apps we
18107        // are managing to keep around is less than half the maximum we desire;
18108        // if we are keeping a good number around, we'll let them use whatever
18109        // memory they want.
18110        final int numCachedAndEmpty = numCached + numEmpty;
18111        int memFactor;
18112        if (numCached <= ProcessList.TRIM_CACHED_APPS
18113                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18114            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18115                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18116            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18117                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18118            } else {
18119                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18120            }
18121        } else {
18122            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18123        }
18124        // We always allow the memory level to go up (better).  We only allow it to go
18125        // down if we are in a state where that is allowed, *and* the total number of processes
18126        // has gone down since last time.
18127        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18128                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18129                + " last=" + mLastNumProcesses);
18130        if (memFactor > mLastMemoryLevel) {
18131            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18132                memFactor = mLastMemoryLevel;
18133                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18134            }
18135        }
18136        mLastMemoryLevel = memFactor;
18137        mLastNumProcesses = mLruProcesses.size();
18138        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18139        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18140        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18141            if (mLowRamStartTime == 0) {
18142                mLowRamStartTime = now;
18143            }
18144            int step = 0;
18145            int fgTrimLevel;
18146            switch (memFactor) {
18147                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18148                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18149                    break;
18150                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18151                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18152                    break;
18153                default:
18154                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18155                    break;
18156            }
18157            int factor = numTrimming/3;
18158            int minFactor = 2;
18159            if (mHomeProcess != null) minFactor++;
18160            if (mPreviousProcess != null) minFactor++;
18161            if (factor < minFactor) factor = minFactor;
18162            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18163            for (int i=N-1; i>=0; i--) {
18164                ProcessRecord app = mLruProcesses.get(i);
18165                if (allChanged || app.procStateChanged) {
18166                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18167                    app.procStateChanged = false;
18168                }
18169                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18170                        && !app.killedByAm) {
18171                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18172                        try {
18173                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18174                                    "Trimming memory of " + app.processName
18175                                    + " to " + curLevel);
18176                            app.thread.scheduleTrimMemory(curLevel);
18177                        } catch (RemoteException e) {
18178                        }
18179                        if (false) {
18180                            // For now we won't do this; our memory trimming seems
18181                            // to be good enough at this point that destroying
18182                            // activities causes more harm than good.
18183                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18184                                    && app != mHomeProcess && app != mPreviousProcess) {
18185                                // Need to do this on its own message because the stack may not
18186                                // be in a consistent state at this point.
18187                                // For these apps we will also finish their activities
18188                                // to help them free memory.
18189                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18190                            }
18191                        }
18192                    }
18193                    app.trimMemoryLevel = curLevel;
18194                    step++;
18195                    if (step >= factor) {
18196                        step = 0;
18197                        switch (curLevel) {
18198                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18199                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18200                                break;
18201                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18202                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18203                                break;
18204                        }
18205                    }
18206                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18207                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18208                            && app.thread != null) {
18209                        try {
18210                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18211                                    "Trimming memory of heavy-weight " + app.processName
18212                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18213                            app.thread.scheduleTrimMemory(
18214                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18215                        } catch (RemoteException e) {
18216                        }
18217                    }
18218                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18219                } else {
18220                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18221                            || app.systemNoUi) && app.pendingUiClean) {
18222                        // If this application is now in the background and it
18223                        // had done UI, then give it the special trim level to
18224                        // have it free UI resources.
18225                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18226                        if (app.trimMemoryLevel < level && app.thread != null) {
18227                            try {
18228                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18229                                        "Trimming memory of bg-ui " + app.processName
18230                                        + " to " + level);
18231                                app.thread.scheduleTrimMemory(level);
18232                            } catch (RemoteException e) {
18233                            }
18234                        }
18235                        app.pendingUiClean = false;
18236                    }
18237                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18238                        try {
18239                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18240                                    "Trimming memory of fg " + app.processName
18241                                    + " to " + fgTrimLevel);
18242                            app.thread.scheduleTrimMemory(fgTrimLevel);
18243                        } catch (RemoteException e) {
18244                        }
18245                    }
18246                    app.trimMemoryLevel = fgTrimLevel;
18247                }
18248            }
18249        } else {
18250            if (mLowRamStartTime != 0) {
18251                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18252                mLowRamStartTime = 0;
18253            }
18254            for (int i=N-1; i>=0; i--) {
18255                ProcessRecord app = mLruProcesses.get(i);
18256                if (allChanged || app.procStateChanged) {
18257                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18258                    app.procStateChanged = false;
18259                }
18260                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18261                        || app.systemNoUi) && app.pendingUiClean) {
18262                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18263                            && app.thread != null) {
18264                        try {
18265                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18266                                    "Trimming memory of ui hidden " + app.processName
18267                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18268                            app.thread.scheduleTrimMemory(
18269                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18270                        } catch (RemoteException e) {
18271                        }
18272                    }
18273                    app.pendingUiClean = false;
18274                }
18275                app.trimMemoryLevel = 0;
18276            }
18277        }
18278
18279        if (mAlwaysFinishActivities) {
18280            // Need to do this on its own message because the stack may not
18281            // be in a consistent state at this point.
18282            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18283        }
18284
18285        if (allChanged) {
18286            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18287        }
18288
18289        if (mProcessStats.shouldWriteNowLocked(now)) {
18290            mHandler.post(new Runnable() {
18291                @Override public void run() {
18292                    synchronized (ActivityManagerService.this) {
18293                        mProcessStats.writeStateAsyncLocked();
18294                    }
18295                }
18296            });
18297        }
18298
18299        if (DEBUG_OOM_ADJ) {
18300            if (false) {
18301                RuntimeException here = new RuntimeException("here");
18302                here.fillInStackTrace();
18303                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18304            } else {
18305                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18306            }
18307        }
18308    }
18309
18310    final void trimApplications() {
18311        synchronized (this) {
18312            int i;
18313
18314            // First remove any unused application processes whose package
18315            // has been removed.
18316            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18317                final ProcessRecord app = mRemovedProcesses.get(i);
18318                if (app.activities.size() == 0
18319                        && app.curReceiver == null && app.services.size() == 0) {
18320                    Slog.i(
18321                        TAG, "Exiting empty application process "
18322                        + app.processName + " ("
18323                        + (app.thread != null ? app.thread.asBinder() : null)
18324                        + ")\n");
18325                    if (app.pid > 0 && app.pid != MY_PID) {
18326                        app.kill("empty", false);
18327                    } else {
18328                        try {
18329                            app.thread.scheduleExit();
18330                        } catch (Exception e) {
18331                            // Ignore exceptions.
18332                        }
18333                    }
18334                    cleanUpApplicationRecordLocked(app, false, true, -1);
18335                    mRemovedProcesses.remove(i);
18336
18337                    if (app.persistent) {
18338                        addAppLocked(app.info, false, null /* ABI override */);
18339                    }
18340                }
18341            }
18342
18343            // Now update the oom adj for all processes.
18344            updateOomAdjLocked();
18345        }
18346    }
18347
18348    /** This method sends the specified signal to each of the persistent apps */
18349    public void signalPersistentProcesses(int sig) throws RemoteException {
18350        if (sig != Process.SIGNAL_USR1) {
18351            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18352        }
18353
18354        synchronized (this) {
18355            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18356                    != PackageManager.PERMISSION_GRANTED) {
18357                throw new SecurityException("Requires permission "
18358                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18359            }
18360
18361            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18362                ProcessRecord r = mLruProcesses.get(i);
18363                if (r.thread != null && r.persistent) {
18364                    Process.sendSignal(r.pid, sig);
18365                }
18366            }
18367        }
18368    }
18369
18370    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18371        if (proc == null || proc == mProfileProc) {
18372            proc = mProfileProc;
18373            profileType = mProfileType;
18374            clearProfilerLocked();
18375        }
18376        if (proc == null) {
18377            return;
18378        }
18379        try {
18380            proc.thread.profilerControl(false, null, profileType);
18381        } catch (RemoteException e) {
18382            throw new IllegalStateException("Process disappeared");
18383        }
18384    }
18385
18386    private void clearProfilerLocked() {
18387        if (mProfileFd != null) {
18388            try {
18389                mProfileFd.close();
18390            } catch (IOException e) {
18391            }
18392        }
18393        mProfileApp = null;
18394        mProfileProc = null;
18395        mProfileFile = null;
18396        mProfileType = 0;
18397        mAutoStopProfiler = false;
18398        mSamplingInterval = 0;
18399    }
18400
18401    public boolean profileControl(String process, int userId, boolean start,
18402            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18403
18404        try {
18405            synchronized (this) {
18406                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18407                // its own permission.
18408                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18409                        != PackageManager.PERMISSION_GRANTED) {
18410                    throw new SecurityException("Requires permission "
18411                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18412                }
18413
18414                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18415                    throw new IllegalArgumentException("null profile info or fd");
18416                }
18417
18418                ProcessRecord proc = null;
18419                if (process != null) {
18420                    proc = findProcessLocked(process, userId, "profileControl");
18421                }
18422
18423                if (start && (proc == null || proc.thread == null)) {
18424                    throw new IllegalArgumentException("Unknown process: " + process);
18425                }
18426
18427                if (start) {
18428                    stopProfilerLocked(null, 0);
18429                    setProfileApp(proc.info, proc.processName, profilerInfo);
18430                    mProfileProc = proc;
18431                    mProfileType = profileType;
18432                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18433                    try {
18434                        fd = fd.dup();
18435                    } catch (IOException e) {
18436                        fd = null;
18437                    }
18438                    profilerInfo.profileFd = fd;
18439                    proc.thread.profilerControl(start, profilerInfo, profileType);
18440                    fd = null;
18441                    mProfileFd = null;
18442                } else {
18443                    stopProfilerLocked(proc, profileType);
18444                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18445                        try {
18446                            profilerInfo.profileFd.close();
18447                        } catch (IOException e) {
18448                        }
18449                    }
18450                }
18451
18452                return true;
18453            }
18454        } catch (RemoteException e) {
18455            throw new IllegalStateException("Process disappeared");
18456        } finally {
18457            if (profilerInfo != null && profilerInfo.profileFd != null) {
18458                try {
18459                    profilerInfo.profileFd.close();
18460                } catch (IOException e) {
18461                }
18462            }
18463        }
18464    }
18465
18466    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18467        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18468                userId, true, ALLOW_FULL_ONLY, callName, null);
18469        ProcessRecord proc = null;
18470        try {
18471            int pid = Integer.parseInt(process);
18472            synchronized (mPidsSelfLocked) {
18473                proc = mPidsSelfLocked.get(pid);
18474            }
18475        } catch (NumberFormatException e) {
18476        }
18477
18478        if (proc == null) {
18479            ArrayMap<String, SparseArray<ProcessRecord>> all
18480                    = mProcessNames.getMap();
18481            SparseArray<ProcessRecord> procs = all.get(process);
18482            if (procs != null && procs.size() > 0) {
18483                proc = procs.valueAt(0);
18484                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18485                    for (int i=1; i<procs.size(); i++) {
18486                        ProcessRecord thisProc = procs.valueAt(i);
18487                        if (thisProc.userId == userId) {
18488                            proc = thisProc;
18489                            break;
18490                        }
18491                    }
18492                }
18493            }
18494        }
18495
18496        return proc;
18497    }
18498
18499    public boolean dumpHeap(String process, int userId, boolean managed,
18500            String path, ParcelFileDescriptor fd) throws RemoteException {
18501
18502        try {
18503            synchronized (this) {
18504                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18505                // its own permission (same as profileControl).
18506                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18507                        != PackageManager.PERMISSION_GRANTED) {
18508                    throw new SecurityException("Requires permission "
18509                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18510                }
18511
18512                if (fd == null) {
18513                    throw new IllegalArgumentException("null fd");
18514                }
18515
18516                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18517                if (proc == null || proc.thread == null) {
18518                    throw new IllegalArgumentException("Unknown process: " + process);
18519                }
18520
18521                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18522                if (!isDebuggable) {
18523                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18524                        throw new SecurityException("Process not debuggable: " + proc);
18525                    }
18526                }
18527
18528                proc.thread.dumpHeap(managed, path, fd);
18529                fd = null;
18530                return true;
18531            }
18532        } catch (RemoteException e) {
18533            throw new IllegalStateException("Process disappeared");
18534        } finally {
18535            if (fd != null) {
18536                try {
18537                    fd.close();
18538                } catch (IOException e) {
18539                }
18540            }
18541        }
18542    }
18543
18544    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18545    public void monitor() {
18546        synchronized (this) { }
18547    }
18548
18549    void onCoreSettingsChange(Bundle settings) {
18550        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18551            ProcessRecord processRecord = mLruProcesses.get(i);
18552            try {
18553                if (processRecord.thread != null) {
18554                    processRecord.thread.setCoreSettings(settings);
18555                }
18556            } catch (RemoteException re) {
18557                /* ignore */
18558            }
18559        }
18560    }
18561
18562    // Multi-user methods
18563
18564    /**
18565     * Start user, if its not already running, but don't bring it to foreground.
18566     */
18567    @Override
18568    public boolean startUserInBackground(final int userId) {
18569        return startUser(userId, /* foreground */ false);
18570    }
18571
18572    /**
18573     * Start user, if its not already running, and bring it to foreground.
18574     */
18575    boolean startUserInForeground(final int userId, Dialog dlg) {
18576        boolean result = startUser(userId, /* foreground */ true);
18577        dlg.dismiss();
18578        return result;
18579    }
18580
18581    /**
18582     * Refreshes the list of users related to the current user when either a
18583     * user switch happens or when a new related user is started in the
18584     * background.
18585     */
18586    private void updateCurrentProfileIdsLocked() {
18587        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18588                mCurrentUserId, false /* enabledOnly */);
18589        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18590        for (int i = 0; i < currentProfileIds.length; i++) {
18591            currentProfileIds[i] = profiles.get(i).id;
18592        }
18593        mCurrentProfileIds = currentProfileIds;
18594
18595        synchronized (mUserProfileGroupIdsSelfLocked) {
18596            mUserProfileGroupIdsSelfLocked.clear();
18597            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18598            for (int i = 0; i < users.size(); i++) {
18599                UserInfo user = users.get(i);
18600                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18601                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18602                }
18603            }
18604        }
18605    }
18606
18607    private Set getProfileIdsLocked(int userId) {
18608        Set userIds = new HashSet<Integer>();
18609        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18610                userId, false /* enabledOnly */);
18611        for (UserInfo user : profiles) {
18612            userIds.add(Integer.valueOf(user.id));
18613        }
18614        return userIds;
18615    }
18616
18617    @Override
18618    public boolean switchUser(final int userId) {
18619        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18620        String userName;
18621        synchronized (this) {
18622            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18623            if (userInfo == null) {
18624                Slog.w(TAG, "No user info for user #" + userId);
18625                return false;
18626            }
18627            if (userInfo.isManagedProfile()) {
18628                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18629                return false;
18630            }
18631            userName = userInfo.name;
18632            mTargetUserId = userId;
18633        }
18634        mHandler.removeMessages(START_USER_SWITCH_MSG);
18635        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18636        return true;
18637    }
18638
18639    private void showUserSwitchDialog(int userId, String userName) {
18640        // The dialog will show and then initiate the user switch by calling startUserInForeground
18641        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18642                true /* above system */);
18643        d.show();
18644    }
18645
18646    private boolean startUser(final int userId, final boolean foreground) {
18647        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18648                != PackageManager.PERMISSION_GRANTED) {
18649            String msg = "Permission Denial: switchUser() from pid="
18650                    + Binder.getCallingPid()
18651                    + ", uid=" + Binder.getCallingUid()
18652                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18653            Slog.w(TAG, msg);
18654            throw new SecurityException(msg);
18655        }
18656
18657        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18658
18659        final long ident = Binder.clearCallingIdentity();
18660        try {
18661            synchronized (this) {
18662                final int oldUserId = mCurrentUserId;
18663                if (oldUserId == userId) {
18664                    return true;
18665                }
18666
18667                mStackSupervisor.setLockTaskModeLocked(null, false);
18668
18669                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18670                if (userInfo == null) {
18671                    Slog.w(TAG, "No user info for user #" + userId);
18672                    return false;
18673                }
18674                if (foreground && userInfo.isManagedProfile()) {
18675                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18676                    return false;
18677                }
18678
18679                if (foreground) {
18680                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18681                            R.anim.screen_user_enter);
18682                }
18683
18684                boolean needStart = false;
18685
18686                // If the user we are switching to is not currently started, then
18687                // we need to start it now.
18688                if (mStartedUsers.get(userId) == null) {
18689                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18690                    updateStartedUserArrayLocked();
18691                    needStart = true;
18692                }
18693
18694                final Integer userIdInt = Integer.valueOf(userId);
18695                mUserLru.remove(userIdInt);
18696                mUserLru.add(userIdInt);
18697
18698                if (foreground) {
18699                    mCurrentUserId = userId;
18700                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18701                    updateCurrentProfileIdsLocked();
18702                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18703                    // Once the internal notion of the active user has switched, we lock the device
18704                    // with the option to show the user switcher on the keyguard.
18705                    mWindowManager.lockNow(null);
18706                } else {
18707                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18708                    updateCurrentProfileIdsLocked();
18709                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18710                    mUserLru.remove(currentUserIdInt);
18711                    mUserLru.add(currentUserIdInt);
18712                }
18713
18714                final UserStartedState uss = mStartedUsers.get(userId);
18715
18716                // Make sure user is in the started state.  If it is currently
18717                // stopping, we need to knock that off.
18718                if (uss.mState == UserStartedState.STATE_STOPPING) {
18719                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18720                    // so we can just fairly silently bring the user back from
18721                    // the almost-dead.
18722                    uss.mState = UserStartedState.STATE_RUNNING;
18723                    updateStartedUserArrayLocked();
18724                    needStart = true;
18725                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18726                    // This means ACTION_SHUTDOWN has been sent, so we will
18727                    // need to treat this as a new boot of the user.
18728                    uss.mState = UserStartedState.STATE_BOOTING;
18729                    updateStartedUserArrayLocked();
18730                    needStart = true;
18731                }
18732
18733                if (uss.mState == UserStartedState.STATE_BOOTING) {
18734                    // Booting up a new user, need to tell system services about it.
18735                    // Note that this is on the same handler as scheduling of broadcasts,
18736                    // which is important because it needs to go first.
18737                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18738                }
18739
18740                if (foreground) {
18741                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18742                            oldUserId));
18743                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18744                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18745                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18746                            oldUserId, userId, uss));
18747                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18748                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18749                }
18750
18751                if (needStart) {
18752                    // Send USER_STARTED broadcast
18753                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18754                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18755                            | Intent.FLAG_RECEIVER_FOREGROUND);
18756                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18757                    broadcastIntentLocked(null, null, intent,
18758                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18759                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18760                }
18761
18762                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18763                    if (userId != UserHandle.USER_OWNER) {
18764                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18765                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18766                        broadcastIntentLocked(null, null, intent, null,
18767                                new IIntentReceiver.Stub() {
18768                                    public void performReceive(Intent intent, int resultCode,
18769                                            String data, Bundle extras, boolean ordered,
18770                                            boolean sticky, int sendingUser) {
18771                                        onUserInitialized(uss, foreground, oldUserId, userId);
18772                                    }
18773                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18774                                true, false, MY_PID, Process.SYSTEM_UID,
18775                                userId);
18776                        uss.initializing = true;
18777                    } else {
18778                        getUserManagerLocked().makeInitialized(userInfo.id);
18779                    }
18780                }
18781
18782                if (foreground) {
18783                    if (!uss.initializing) {
18784                        moveUserToForeground(uss, oldUserId, userId);
18785                    }
18786                } else {
18787                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18788                }
18789
18790                if (needStart) {
18791                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18792                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18793                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18794                    broadcastIntentLocked(null, null, intent,
18795                            null, new IIntentReceiver.Stub() {
18796                                @Override
18797                                public void performReceive(Intent intent, int resultCode, String data,
18798                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18799                                        throws RemoteException {
18800                                }
18801                            }, 0, null, null,
18802                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18803                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18804                }
18805            }
18806        } finally {
18807            Binder.restoreCallingIdentity(ident);
18808        }
18809
18810        return true;
18811    }
18812
18813    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18814        long ident = Binder.clearCallingIdentity();
18815        try {
18816            Intent intent;
18817            if (oldUserId >= 0) {
18818                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18819                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18820                int count = profiles.size();
18821                for (int i = 0; i < count; i++) {
18822                    int profileUserId = profiles.get(i).id;
18823                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18824                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18825                            | Intent.FLAG_RECEIVER_FOREGROUND);
18826                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18827                    broadcastIntentLocked(null, null, intent,
18828                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18829                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18830                }
18831            }
18832            if (newUserId >= 0) {
18833                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18834                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18835                int count = profiles.size();
18836                for (int i = 0; i < count; i++) {
18837                    int profileUserId = profiles.get(i).id;
18838                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18839                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18840                            | Intent.FLAG_RECEIVER_FOREGROUND);
18841                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18842                    broadcastIntentLocked(null, null, intent,
18843                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18844                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18845                }
18846                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18847                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18848                        | Intent.FLAG_RECEIVER_FOREGROUND);
18849                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18850                broadcastIntentLocked(null, null, intent,
18851                        null, null, 0, null, null,
18852                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18853                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18854            }
18855        } finally {
18856            Binder.restoreCallingIdentity(ident);
18857        }
18858    }
18859
18860    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18861            final int newUserId) {
18862        final int N = mUserSwitchObservers.beginBroadcast();
18863        if (N > 0) {
18864            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18865                int mCount = 0;
18866                @Override
18867                public void sendResult(Bundle data) throws RemoteException {
18868                    synchronized (ActivityManagerService.this) {
18869                        if (mCurUserSwitchCallback == this) {
18870                            mCount++;
18871                            if (mCount == N) {
18872                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18873                            }
18874                        }
18875                    }
18876                }
18877            };
18878            synchronized (this) {
18879                uss.switching = true;
18880                mCurUserSwitchCallback = callback;
18881            }
18882            for (int i=0; i<N; i++) {
18883                try {
18884                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18885                            newUserId, callback);
18886                } catch (RemoteException e) {
18887                }
18888            }
18889        } else {
18890            synchronized (this) {
18891                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18892            }
18893        }
18894        mUserSwitchObservers.finishBroadcast();
18895    }
18896
18897    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18898        synchronized (this) {
18899            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18900            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18901        }
18902    }
18903
18904    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18905        mCurUserSwitchCallback = null;
18906        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18907        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18908                oldUserId, newUserId, uss));
18909    }
18910
18911    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18912        synchronized (this) {
18913            if (foreground) {
18914                moveUserToForeground(uss, oldUserId, newUserId);
18915            }
18916        }
18917
18918        completeSwitchAndInitalize(uss, newUserId, true, false);
18919    }
18920
18921    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18922        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18923        if (homeInFront) {
18924            startHomeActivityLocked(newUserId);
18925        } else {
18926            mStackSupervisor.resumeTopActivitiesLocked();
18927        }
18928        EventLogTags.writeAmSwitchUser(newUserId);
18929        getUserManagerLocked().userForeground(newUserId);
18930        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18931    }
18932
18933    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18934        completeSwitchAndInitalize(uss, newUserId, false, true);
18935    }
18936
18937    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18938            boolean clearInitializing, boolean clearSwitching) {
18939        boolean unfrozen = false;
18940        synchronized (this) {
18941            if (clearInitializing) {
18942                uss.initializing = false;
18943                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18944            }
18945            if (clearSwitching) {
18946                uss.switching = false;
18947            }
18948            if (!uss.switching && !uss.initializing) {
18949                mWindowManager.stopFreezingScreen();
18950                unfrozen = true;
18951            }
18952        }
18953        if (unfrozen) {
18954            final int N = mUserSwitchObservers.beginBroadcast();
18955            for (int i=0; i<N; i++) {
18956                try {
18957                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18958                } catch (RemoteException e) {
18959                }
18960            }
18961            mUserSwitchObservers.finishBroadcast();
18962        }
18963        stopGuestUserIfBackground();
18964    }
18965
18966    /**
18967     * Stops the guest user if it has gone to the background.
18968     */
18969    private void stopGuestUserIfBackground() {
18970        synchronized (this) {
18971            final int num = mUserLru.size();
18972            for (int i = 0; i < num; i++) {
18973                Integer oldUserId = mUserLru.get(i);
18974                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18975                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
18976                        || oldUss.mState == UserStartedState.STATE_STOPPING
18977                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18978                    continue;
18979                }
18980                UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
18981                if (userInfo.isGuest()) {
18982                    // This is a user to be stopped.
18983                    stopUserLocked(oldUserId, null);
18984                    break;
18985                }
18986            }
18987        }
18988    }
18989
18990    void scheduleStartProfilesLocked() {
18991        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18992            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18993                    DateUtils.SECOND_IN_MILLIS);
18994        }
18995    }
18996
18997    void startProfilesLocked() {
18998        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18999        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19000                mCurrentUserId, false /* enabledOnly */);
19001        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19002        for (UserInfo user : profiles) {
19003            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19004                    && user.id != mCurrentUserId) {
19005                toStart.add(user);
19006            }
19007        }
19008        final int n = toStart.size();
19009        int i = 0;
19010        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19011            startUserInBackground(toStart.get(i).id);
19012        }
19013        if (i < n) {
19014            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19015        }
19016    }
19017
19018    void finishUserBoot(UserStartedState uss) {
19019        synchronized (this) {
19020            if (uss.mState == UserStartedState.STATE_BOOTING
19021                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19022                uss.mState = UserStartedState.STATE_RUNNING;
19023                final int userId = uss.mHandle.getIdentifier();
19024                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19025                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19026                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19027                broadcastIntentLocked(null, null, intent,
19028                        null, null, 0, null, null,
19029                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19030                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19031            }
19032        }
19033    }
19034
19035    void finishUserSwitch(UserStartedState uss) {
19036        synchronized (this) {
19037            finishUserBoot(uss);
19038
19039            startProfilesLocked();
19040
19041            int num = mUserLru.size();
19042            int i = 0;
19043            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19044                Integer oldUserId = mUserLru.get(i);
19045                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19046                if (oldUss == null) {
19047                    // Shouldn't happen, but be sane if it does.
19048                    mUserLru.remove(i);
19049                    num--;
19050                    continue;
19051                }
19052                if (oldUss.mState == UserStartedState.STATE_STOPPING
19053                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19054                    // This user is already stopping, doesn't count.
19055                    num--;
19056                    i++;
19057                    continue;
19058                }
19059                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19060                    // Owner and current can't be stopped, but count as running.
19061                    i++;
19062                    continue;
19063                }
19064                // This is a user to be stopped.
19065                stopUserLocked(oldUserId, null);
19066                num--;
19067                i++;
19068            }
19069        }
19070    }
19071
19072    @Override
19073    public int stopUser(final int userId, final IStopUserCallback callback) {
19074        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19075                != PackageManager.PERMISSION_GRANTED) {
19076            String msg = "Permission Denial: switchUser() from pid="
19077                    + Binder.getCallingPid()
19078                    + ", uid=" + Binder.getCallingUid()
19079                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19080            Slog.w(TAG, msg);
19081            throw new SecurityException(msg);
19082        }
19083        if (userId <= 0) {
19084            throw new IllegalArgumentException("Can't stop primary user " + userId);
19085        }
19086        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19087        synchronized (this) {
19088            return stopUserLocked(userId, callback);
19089        }
19090    }
19091
19092    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19093        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19094        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19095            return ActivityManager.USER_OP_IS_CURRENT;
19096        }
19097
19098        final UserStartedState uss = mStartedUsers.get(userId);
19099        if (uss == null) {
19100            // User is not started, nothing to do...  but we do need to
19101            // callback if requested.
19102            if (callback != null) {
19103                mHandler.post(new Runnable() {
19104                    @Override
19105                    public void run() {
19106                        try {
19107                            callback.userStopped(userId);
19108                        } catch (RemoteException e) {
19109                        }
19110                    }
19111                });
19112            }
19113            return ActivityManager.USER_OP_SUCCESS;
19114        }
19115
19116        if (callback != null) {
19117            uss.mStopCallbacks.add(callback);
19118        }
19119
19120        if (uss.mState != UserStartedState.STATE_STOPPING
19121                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19122            uss.mState = UserStartedState.STATE_STOPPING;
19123            updateStartedUserArrayLocked();
19124
19125            long ident = Binder.clearCallingIdentity();
19126            try {
19127                // We are going to broadcast ACTION_USER_STOPPING and then
19128                // once that is done send a final ACTION_SHUTDOWN and then
19129                // stop the user.
19130                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19131                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19132                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19133                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19134                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19135                // This is the result receiver for the final shutdown broadcast.
19136                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19137                    @Override
19138                    public void performReceive(Intent intent, int resultCode, String data,
19139                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19140                        finishUserStop(uss);
19141                    }
19142                };
19143                // This is the result receiver for the initial stopping broadcast.
19144                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19145                    @Override
19146                    public void performReceive(Intent intent, int resultCode, String data,
19147                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19148                        // On to the next.
19149                        synchronized (ActivityManagerService.this) {
19150                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19151                                // Whoops, we are being started back up.  Abort, abort!
19152                                return;
19153                            }
19154                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19155                        }
19156                        mBatteryStatsService.noteEvent(
19157                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19158                                Integer.toString(userId), userId);
19159                        mSystemServiceManager.stopUser(userId);
19160                        broadcastIntentLocked(null, null, shutdownIntent,
19161                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19162                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19163                    }
19164                };
19165                // Kick things off.
19166                broadcastIntentLocked(null, null, stoppingIntent,
19167                        null, stoppingReceiver, 0, null, null,
19168                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19169                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19170            } finally {
19171                Binder.restoreCallingIdentity(ident);
19172            }
19173        }
19174
19175        return ActivityManager.USER_OP_SUCCESS;
19176    }
19177
19178    void finishUserStop(UserStartedState uss) {
19179        final int userId = uss.mHandle.getIdentifier();
19180        boolean stopped;
19181        ArrayList<IStopUserCallback> callbacks;
19182        synchronized (this) {
19183            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19184            if (mStartedUsers.get(userId) != uss) {
19185                stopped = false;
19186            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19187                stopped = false;
19188            } else {
19189                stopped = true;
19190                // User can no longer run.
19191                mStartedUsers.remove(userId);
19192                mUserLru.remove(Integer.valueOf(userId));
19193                updateStartedUserArrayLocked();
19194
19195                // Clean up all state and processes associated with the user.
19196                // Kill all the processes for the user.
19197                forceStopUserLocked(userId, "finish user");
19198            }
19199
19200            // Explicitly remove the old information in mRecentTasks.
19201            removeRecentTasksForUserLocked(userId);
19202        }
19203
19204        for (int i=0; i<callbacks.size(); i++) {
19205            try {
19206                if (stopped) callbacks.get(i).userStopped(userId);
19207                else callbacks.get(i).userStopAborted(userId);
19208            } catch (RemoteException e) {
19209            }
19210        }
19211
19212        if (stopped) {
19213            mSystemServiceManager.cleanupUser(userId);
19214            synchronized (this) {
19215                mStackSupervisor.removeUserLocked(userId);
19216            }
19217        }
19218    }
19219
19220    @Override
19221    public UserInfo getCurrentUser() {
19222        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19223                != PackageManager.PERMISSION_GRANTED) && (
19224                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19225                != PackageManager.PERMISSION_GRANTED)) {
19226            String msg = "Permission Denial: getCurrentUser() from pid="
19227                    + Binder.getCallingPid()
19228                    + ", uid=" + Binder.getCallingUid()
19229                    + " requires " + INTERACT_ACROSS_USERS;
19230            Slog.w(TAG, msg);
19231            throw new SecurityException(msg);
19232        }
19233        synchronized (this) {
19234            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19235            return getUserManagerLocked().getUserInfo(userId);
19236        }
19237    }
19238
19239    int getCurrentUserIdLocked() {
19240        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19241    }
19242
19243    @Override
19244    public boolean isUserRunning(int userId, boolean orStopped) {
19245        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19246                != PackageManager.PERMISSION_GRANTED) {
19247            String msg = "Permission Denial: isUserRunning() from pid="
19248                    + Binder.getCallingPid()
19249                    + ", uid=" + Binder.getCallingUid()
19250                    + " requires " + INTERACT_ACROSS_USERS;
19251            Slog.w(TAG, msg);
19252            throw new SecurityException(msg);
19253        }
19254        synchronized (this) {
19255            return isUserRunningLocked(userId, orStopped);
19256        }
19257    }
19258
19259    boolean isUserRunningLocked(int userId, boolean orStopped) {
19260        UserStartedState state = mStartedUsers.get(userId);
19261        if (state == null) {
19262            return false;
19263        }
19264        if (orStopped) {
19265            return true;
19266        }
19267        return state.mState != UserStartedState.STATE_STOPPING
19268                && state.mState != UserStartedState.STATE_SHUTDOWN;
19269    }
19270
19271    @Override
19272    public int[] getRunningUserIds() {
19273        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19274                != PackageManager.PERMISSION_GRANTED) {
19275            String msg = "Permission Denial: isUserRunning() from pid="
19276                    + Binder.getCallingPid()
19277                    + ", uid=" + Binder.getCallingUid()
19278                    + " requires " + INTERACT_ACROSS_USERS;
19279            Slog.w(TAG, msg);
19280            throw new SecurityException(msg);
19281        }
19282        synchronized (this) {
19283            return mStartedUserArray;
19284        }
19285    }
19286
19287    private void updateStartedUserArrayLocked() {
19288        int num = 0;
19289        for (int i=0; i<mStartedUsers.size();  i++) {
19290            UserStartedState uss = mStartedUsers.valueAt(i);
19291            // This list does not include stopping users.
19292            if (uss.mState != UserStartedState.STATE_STOPPING
19293                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19294                num++;
19295            }
19296        }
19297        mStartedUserArray = new int[num];
19298        num = 0;
19299        for (int i=0; i<mStartedUsers.size();  i++) {
19300            UserStartedState uss = mStartedUsers.valueAt(i);
19301            if (uss.mState != UserStartedState.STATE_STOPPING
19302                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19303                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19304                num++;
19305            }
19306        }
19307    }
19308
19309    @Override
19310    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19311        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19312                != PackageManager.PERMISSION_GRANTED) {
19313            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19314                    + Binder.getCallingPid()
19315                    + ", uid=" + Binder.getCallingUid()
19316                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19317            Slog.w(TAG, msg);
19318            throw new SecurityException(msg);
19319        }
19320
19321        mUserSwitchObservers.register(observer);
19322    }
19323
19324    @Override
19325    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19326        mUserSwitchObservers.unregister(observer);
19327    }
19328
19329    private boolean userExists(int userId) {
19330        if (userId == 0) {
19331            return true;
19332        }
19333        UserManagerService ums = getUserManagerLocked();
19334        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19335    }
19336
19337    int[] getUsersLocked() {
19338        UserManagerService ums = getUserManagerLocked();
19339        return ums != null ? ums.getUserIds() : new int[] { 0 };
19340    }
19341
19342    UserManagerService getUserManagerLocked() {
19343        if (mUserManager == null) {
19344            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19345            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19346        }
19347        return mUserManager;
19348    }
19349
19350    private int applyUserId(int uid, int userId) {
19351        return UserHandle.getUid(userId, uid);
19352    }
19353
19354    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19355        if (info == null) return null;
19356        ApplicationInfo newInfo = new ApplicationInfo(info);
19357        newInfo.uid = applyUserId(info.uid, userId);
19358        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19359                + info.packageName;
19360        return newInfo;
19361    }
19362
19363    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19364        if (aInfo == null
19365                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19366            return aInfo;
19367        }
19368
19369        ActivityInfo info = new ActivityInfo(aInfo);
19370        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19371        return info;
19372    }
19373
19374    private final class LocalService extends ActivityManagerInternal {
19375        @Override
19376        public void onWakefulnessChanged(int wakefulness) {
19377            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19378        }
19379
19380        @Override
19381        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19382                String processName, String abiOverride, int uid, Runnable crashHandler) {
19383            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19384                    processName, abiOverride, uid, crashHandler);
19385        }
19386    }
19387
19388    /**
19389     * An implementation of IAppTask, that allows an app to manage its own tasks via
19390     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19391     * only the process that calls getAppTasks() can call the AppTask methods.
19392     */
19393    class AppTaskImpl extends IAppTask.Stub {
19394        private int mTaskId;
19395        private int mCallingUid;
19396
19397        public AppTaskImpl(int taskId, int callingUid) {
19398            mTaskId = taskId;
19399            mCallingUid = callingUid;
19400        }
19401
19402        private void checkCaller() {
19403            if (mCallingUid != Binder.getCallingUid()) {
19404                throw new SecurityException("Caller " + mCallingUid
19405                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19406            }
19407        }
19408
19409        @Override
19410        public void finishAndRemoveTask() {
19411            checkCaller();
19412
19413            synchronized (ActivityManagerService.this) {
19414                long origId = Binder.clearCallingIdentity();
19415                try {
19416                    if (!removeTaskByIdLocked(mTaskId, false)) {
19417                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19418                    }
19419                } finally {
19420                    Binder.restoreCallingIdentity(origId);
19421                }
19422            }
19423        }
19424
19425        @Override
19426        public ActivityManager.RecentTaskInfo getTaskInfo() {
19427            checkCaller();
19428
19429            synchronized (ActivityManagerService.this) {
19430                long origId = Binder.clearCallingIdentity();
19431                try {
19432                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19433                    if (tr == null) {
19434                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19435                    }
19436                    return createRecentTaskInfoFromTaskRecord(tr);
19437                } finally {
19438                    Binder.restoreCallingIdentity(origId);
19439                }
19440            }
19441        }
19442
19443        @Override
19444        public void moveToFront() {
19445            checkCaller();
19446
19447            final TaskRecord tr;
19448            synchronized (ActivityManagerService.this) {
19449                tr = recentTaskForIdLocked(mTaskId);
19450                if (tr == null) {
19451                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19452                }
19453                if (tr.getRootActivity() != null) {
19454                    moveTaskToFrontLocked(tr.taskId, 0, null);
19455                    return;
19456                }
19457            }
19458
19459            startActivityFromRecentsInner(tr.taskId, null);
19460        }
19461
19462        @Override
19463        public int startActivity(IBinder whoThread, String callingPackage,
19464                Intent intent, String resolvedType, Bundle options) {
19465            checkCaller();
19466
19467            int callingUser = UserHandle.getCallingUserId();
19468            TaskRecord tr;
19469            IApplicationThread appThread;
19470            synchronized (ActivityManagerService.this) {
19471                tr = recentTaskForIdLocked(mTaskId);
19472                if (tr == null) {
19473                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19474                }
19475                appThread = ApplicationThreadNative.asInterface(whoThread);
19476                if (appThread == null) {
19477                    throw new IllegalArgumentException("Bad app thread " + appThread);
19478                }
19479            }
19480            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19481                    resolvedType, null, null, null, null, 0, 0, null, null,
19482                    null, options, callingUser, null, tr);
19483        }
19484
19485        @Override
19486        public void setExcludeFromRecents(boolean exclude) {
19487            checkCaller();
19488
19489            synchronized (ActivityManagerService.this) {
19490                long origId = Binder.clearCallingIdentity();
19491                try {
19492                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19493                    if (tr == null) {
19494                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19495                    }
19496                    Intent intent = tr.getBaseIntent();
19497                    if (exclude) {
19498                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19499                    } else {
19500                        intent.setFlags(intent.getFlags()
19501                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19502                    }
19503                } finally {
19504                    Binder.restoreCallingIdentity(origId);
19505                }
19506            }
19507        }
19508    }
19509}
19510