ActivityManagerService.java revision 034ef013ecb14203a005f88abb1c765055b7d4f4
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35import android.Manifest;
36import android.app.AppOpsManager;
37import android.app.ApplicationThreadNative;
38import android.app.IActivityContainer;
39import android.app.IActivityContainerCallback;
40import android.app.IAppTask;
41import android.app.ITaskStackListener;
42import android.app.ProfilerInfo;
43import android.app.admin.DevicePolicyManager;
44import android.app.usage.UsageEvents;
45import android.app.usage.UsageStatsManagerInternal;
46import android.appwidget.AppWidgetManager;
47import android.content.res.Resources;
48import android.graphics.Bitmap;
49import android.graphics.Point;
50import android.graphics.Rect;
51import android.os.BatteryStats;
52import android.os.PersistableBundle;
53import android.os.storage.IMountService;
54import android.os.storage.StorageManager;
55import android.service.voice.IVoiceInteractionSession;
56import android.util.ArrayMap;
57import android.util.ArraySet;
58import android.util.SparseIntArray;
59
60import com.android.internal.R;
61import com.android.internal.annotations.GuardedBy;
62import com.android.internal.app.IAppOpsService;
63import com.android.internal.app.IVoiceInteractor;
64import com.android.internal.app.ProcessMap;
65import com.android.internal.app.ProcessStats;
66import com.android.internal.os.BackgroundThread;
67import com.android.internal.os.BatteryStatsImpl;
68import com.android.internal.os.ProcessCpuTracker;
69import com.android.internal.os.TransferPipe;
70import com.android.internal.os.Zygote;
71import com.android.internal.util.FastPrintWriter;
72import com.android.internal.util.FastXmlSerializer;
73import com.android.internal.util.MemInfoReader;
74import com.android.internal.util.Preconditions;
75import com.android.server.AppOpsService;
76import com.android.server.AttributeCache;
77import com.android.server.IntentResolver;
78import com.android.server.LocalServices;
79import com.android.server.ServiceThread;
80import com.android.server.SystemService;
81import com.android.server.SystemServiceManager;
82import com.android.server.Watchdog;
83import com.android.server.am.ActivityStack.ActivityState;
84import com.android.server.firewall.IntentFirewall;
85import com.android.server.pm.Installer;
86import com.android.server.pm.UserManagerService;
87import com.android.server.statusbar.StatusBarManagerInternal;
88import com.android.server.wm.AppTransition;
89import com.android.server.wm.WindowManagerService;
90import com.google.android.collect.Lists;
91import com.google.android.collect.Maps;
92
93import libcore.io.IoUtils;
94
95import org.xmlpull.v1.XmlPullParser;
96import org.xmlpull.v1.XmlPullParserException;
97import org.xmlpull.v1.XmlSerializer;
98
99import android.app.Activity;
100import android.app.ActivityManager;
101import android.app.ActivityManager.RunningTaskInfo;
102import android.app.ActivityManager.StackInfo;
103import android.app.ActivityManagerInternal;
104import android.app.ActivityManagerNative;
105import android.app.ActivityOptions;
106import android.app.ActivityThread;
107import android.app.AlertDialog;
108import android.app.AppGlobals;
109import android.app.ApplicationErrorReport;
110import android.app.Dialog;
111import android.app.IActivityController;
112import android.app.IApplicationThread;
113import android.app.IInstrumentationWatcher;
114import android.app.INotificationManager;
115import android.app.IProcessObserver;
116import android.app.IServiceConnection;
117import android.app.IStopUserCallback;
118import android.app.IUiAutomationConnection;
119import android.app.IUserSwitchObserver;
120import android.app.Instrumentation;
121import android.app.Notification;
122import android.app.NotificationManager;
123import android.app.PendingIntent;
124import android.app.backup.IBackupManager;
125import android.content.ActivityNotFoundException;
126import android.content.BroadcastReceiver;
127import android.content.ClipData;
128import android.content.ComponentCallbacks2;
129import android.content.ComponentName;
130import android.content.ContentProvider;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.DialogInterface;
134import android.content.IContentProvider;
135import android.content.IIntentReceiver;
136import android.content.IIntentSender;
137import android.content.Intent;
138import android.content.IntentFilter;
139import android.content.IntentSender;
140import android.content.pm.ActivityInfo;
141import android.content.pm.ApplicationInfo;
142import android.content.pm.ConfigurationInfo;
143import android.content.pm.IPackageDataObserver;
144import android.content.pm.IPackageManager;
145import android.content.pm.InstrumentationInfo;
146import android.content.pm.PackageInfo;
147import android.content.pm.PackageManager;
148import android.content.pm.ParceledListSlice;
149import android.content.pm.UserInfo;
150import android.content.pm.PackageManager.NameNotFoundException;
151import android.content.pm.PathPermission;
152import android.content.pm.ProviderInfo;
153import android.content.pm.ResolveInfo;
154import android.content.pm.ServiceInfo;
155import android.content.res.CompatibilityInfo;
156import android.content.res.Configuration;
157import android.net.Proxy;
158import android.net.ProxyInfo;
159import android.net.Uri;
160import android.os.Binder;
161import android.os.Build;
162import android.os.Bundle;
163import android.os.Debug;
164import android.os.DropBoxManager;
165import android.os.Environment;
166import android.os.FactoryTest;
167import android.os.FileObserver;
168import android.os.FileUtils;
169import android.os.Handler;
170import android.os.IBinder;
171import android.os.IPermissionController;
172import android.os.IRemoteCallback;
173import android.os.IUserManager;
174import android.os.Looper;
175import android.os.Message;
176import android.os.Parcel;
177import android.os.ParcelFileDescriptor;
178import android.os.PowerManagerInternal;
179import android.os.Process;
180import android.os.RemoteCallbackList;
181import android.os.RemoteException;
182import android.os.SELinux;
183import android.os.ServiceManager;
184import android.os.StrictMode;
185import android.os.SystemClock;
186import android.os.SystemProperties;
187import android.os.UpdateLock;
188import android.os.UserHandle;
189import android.os.UserManager;
190import android.provider.Settings;
191import android.text.format.DateUtils;
192import android.text.format.Time;
193import android.util.AtomicFile;
194import android.util.EventLog;
195import android.util.Log;
196import android.util.Pair;
197import android.util.PrintWriterPrinter;
198import android.util.Slog;
199import android.util.SparseArray;
200import android.util.TimeUtils;
201import android.util.Xml;
202import android.view.Gravity;
203import android.view.LayoutInflater;
204import android.view.View;
205import android.view.WindowManager;
206
207import dalvik.system.VMRuntime;
208
209import java.io.BufferedInputStream;
210import java.io.BufferedOutputStream;
211import java.io.DataInputStream;
212import java.io.DataOutputStream;
213import java.io.File;
214import java.io.FileDescriptor;
215import java.io.FileInputStream;
216import java.io.FileNotFoundException;
217import java.io.FileOutputStream;
218import java.io.IOException;
219import java.io.InputStreamReader;
220import java.io.PrintWriter;
221import java.io.StringWriter;
222import java.lang.ref.WeakReference;
223import java.util.ArrayList;
224import java.util.Arrays;
225import java.util.Collections;
226import java.util.Comparator;
227import java.util.HashMap;
228import java.util.HashSet;
229import java.util.Iterator;
230import java.util.List;
231import java.util.Locale;
232import java.util.Map;
233import java.util.Set;
234import java.util.concurrent.atomic.AtomicBoolean;
235import java.util.concurrent.atomic.AtomicLong;
236
237public final class ActivityManagerService extends ActivityManagerNative
238        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
239
240    private static final String USER_DATA_DIR = "/data/user/";
241    // File that stores last updated system version and called preboot receivers
242    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
243
244    static final String TAG = "ActivityManager";
245    static final String TAG_MU = "ActivityManagerServiceMU";
246    static final boolean DEBUG = false;
247    static final boolean localLOGV = DEBUG;
248    static final boolean DEBUG_BACKUP = localLOGV || false;
249    static final boolean DEBUG_BROADCAST = localLOGV || false;
250    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
251    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
252    static final boolean DEBUG_CLEANUP = localLOGV || false;
253    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
254    static final boolean DEBUG_FOCUS = false;
255    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
256    static final boolean DEBUG_MU = localLOGV || false;
257    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
258    static final boolean DEBUG_LRU = localLOGV || false;
259    static final boolean DEBUG_PAUSE = localLOGV || false;
260    static final boolean DEBUG_POWER = localLOGV || false;
261    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
262    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
263    static final boolean DEBUG_PROCESSES = localLOGV || false;
264    static final boolean DEBUG_PROVIDER = localLOGV || false;
265    static final boolean DEBUG_RESULTS = localLOGV || false;
266    static final boolean DEBUG_SERVICE = localLOGV || false;
267    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
268    static final boolean DEBUG_STACK = localLOGV || false;
269    static final boolean DEBUG_SWITCH = localLOGV || false;
270    static final boolean DEBUG_TASKS = localLOGV || false;
271    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
272    static final boolean DEBUG_TRANSITION = localLOGV || false;
273    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
274    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
275    static final boolean DEBUG_VISBILITY = localLOGV || false;
276    static final boolean DEBUG_PSS = localLOGV || false;
277    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
278    static final boolean DEBUG_RECENTS = localLOGV || false;
279    static final boolean VALIDATE_TOKENS = false;
280    static final boolean SHOW_ACTIVITY_START_TIME = true;
281
282    // Control over CPU and battery monitoring.
283    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
284    static final boolean MONITOR_CPU_USAGE = true;
285    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
286    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
287    static final boolean MONITOR_THREAD_CPU_USAGE = false;
288
289    // The flags that are set for all calls we make to the package manager.
290    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
291
292    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
293
294    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
295
296    // Maximum number recent bitmaps to keep in memory.
297    static final int MAX_RECENT_BITMAPS = 3;
298
299    // Amount of time after a call to stopAppSwitches() during which we will
300    // prevent further untrusted switches from happening.
301    static final long APP_SWITCH_DELAY_TIME = 5*1000;
302
303    // How long we wait for a launched process to attach to the activity manager
304    // before we decide it's never going to come up for real.
305    static final int PROC_START_TIMEOUT = 10*1000;
306
307    // How long we wait for a launched process to attach to the activity manager
308    // before we decide it's never going to come up for real, when the process was
309    // started with a wrapper for instrumentation (such as Valgrind) because it
310    // could take much longer than usual.
311    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
312
313    // How long to wait after going idle before forcing apps to GC.
314    static final int GC_TIMEOUT = 5*1000;
315
316    // The minimum amount of time between successive GC requests for a process.
317    static final int GC_MIN_INTERVAL = 60*1000;
318
319    // The minimum amount of time between successive PSS requests for a process.
320    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
321
322    // The minimum amount of time between successive PSS requests for a process
323    // when the request is due to the memory state being lowered.
324    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
325
326    // The rate at which we check for apps using excessive power -- 15 mins.
327    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
328
329    // The minimum sample duration we will allow before deciding we have
330    // enough data on wake locks to start killing things.
331    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
332
333    // The minimum sample duration we will allow before deciding we have
334    // enough data on CPU usage to start killing things.
335    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336
337    // How long we allow a receiver to run before giving up on it.
338    static final int BROADCAST_FG_TIMEOUT = 10*1000;
339    static final int BROADCAST_BG_TIMEOUT = 60*1000;
340
341    // How long we wait until we timeout on key dispatching.
342    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
343
344    // How long we wait until we timeout on key dispatching during instrumentation.
345    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
346
347    // Amount of time we wait for observers to handle a user switch before
348    // giving up on them and unfreezing the screen.
349    static final int USER_SWITCH_TIMEOUT = 2*1000;
350
351    // Maximum number of users we allow to be running at a time.
352    static final int MAX_RUNNING_USERS = 3;
353
354    // How long to wait in getAssistContextExtras for the activity and foreground services
355    // to respond with the result.
356    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
357
358    // Maximum number of persisted Uri grants a package is allowed
359    static final int MAX_PERSISTED_URI_GRANTS = 128;
360
361    static final int MY_PID = Process.myPid();
362
363    static final String[] EMPTY_STRING_ARRAY = new String[0];
364
365    // How many bytes to write into the dropbox log before truncating
366    static final int DROPBOX_MAX_SIZE = 256 * 1024;
367
368    // Access modes for handleIncomingUser.
369    static final int ALLOW_NON_FULL = 0;
370    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
371    static final int ALLOW_FULL_ONLY = 2;
372
373    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
374
375    // Delay in notifying task stack change listeners (in millis)
376    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
377
378    /** All system services */
379    SystemServiceManager mSystemServiceManager;
380
381    private Installer mInstaller;
382
383    /** Run all ActivityStacks through this */
384    ActivityStackSupervisor mStackSupervisor;
385
386    /** Task stack change listeners. */
387    private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
388            new RemoteCallbackList<ITaskStackListener>();
389
390    public IntentFirewall mIntentFirewall;
391
392    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
393    // default actuion automatically.  Important for devices without direct input
394    // devices.
395    private boolean mShowDialogs = true;
396
397    BroadcastQueue mFgBroadcastQueue;
398    BroadcastQueue mBgBroadcastQueue;
399    // Convenient for easy iteration over the queues. Foreground is first
400    // so that dispatch of foreground broadcasts gets precedence.
401    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
402
403    BroadcastQueue broadcastQueueForIntent(Intent intent) {
404        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
405        if (DEBUG_BACKGROUND_BROADCAST) {
406            Slog.i(TAG, "Broadcast intent " + intent + " on "
407                    + (isFg ? "foreground" : "background")
408                    + " queue");
409        }
410        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
411    }
412
413    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
414        for (BroadcastQueue queue : mBroadcastQueues) {
415            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
416            if (r != null) {
417                return r;
418            }
419        }
420        return null;
421    }
422
423    /**
424     * Activity we have told the window manager to have key focus.
425     */
426    ActivityRecord mFocusedActivity = null;
427
428    /**
429     * List of intents that were used to start the most recent tasks.
430     */
431    ArrayList<TaskRecord> mRecentTasks;
432    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
433
434    /**
435     * For addAppTask: cached of the last activity component that was added.
436     */
437    ComponentName mLastAddedTaskComponent;
438
439    /**
440     * For addAppTask: cached of the last activity uid that was added.
441     */
442    int mLastAddedTaskUid;
443
444    /**
445     * For addAppTask: cached of the last ActivityInfo that was added.
446     */
447    ActivityInfo mLastAddedTaskActivity;
448
449    public class PendingAssistExtras extends Binder implements Runnable {
450        public final ActivityRecord activity;
451        public final Bundle extras;
452        public final Intent intent;
453        public final String hint;
454        public final int userHandle;
455        public boolean haveResult = false;
456        public Bundle result = null;
457        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
458                String _hint, int _userHandle) {
459            activity = _activity;
460            extras = _extras;
461            intent = _intent;
462            hint = _hint;
463            userHandle = _userHandle;
464        }
465        @Override
466        public void run() {
467            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
468            synchronized (this) {
469                haveResult = true;
470                notifyAll();
471            }
472        }
473    }
474
475    final ArrayList<PendingAssistExtras> mPendingAssistExtras
476            = new ArrayList<PendingAssistExtras>();
477
478    /**
479     * Process management.
480     */
481    final ProcessList mProcessList = new ProcessList();
482
483    /**
484     * All of the applications we currently have running organized by name.
485     * The keys are strings of the application package name (as
486     * returned by the package manager), and the keys are ApplicationRecord
487     * objects.
488     */
489    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
490
491    /**
492     * Tracking long-term execution of processes to look for abuse and other
493     * bad app behavior.
494     */
495    final ProcessStatsService mProcessStats;
496
497    /**
498     * The currently running isolated processes.
499     */
500    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
501
502    /**
503     * Counter for assigning isolated process uids, to avoid frequently reusing the
504     * same ones.
505     */
506    int mNextIsolatedProcessUid = 0;
507
508    /**
509     * The currently running heavy-weight process, if any.
510     */
511    ProcessRecord mHeavyWeightProcess = null;
512
513    /**
514     * The last time that various processes have crashed.
515     */
516    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
517
518    /**
519     * Information about a process that is currently marked as bad.
520     */
521    static final class BadProcessInfo {
522        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
523            this.time = time;
524            this.shortMsg = shortMsg;
525            this.longMsg = longMsg;
526            this.stack = stack;
527        }
528
529        final long time;
530        final String shortMsg;
531        final String longMsg;
532        final String stack;
533    }
534
535    /**
536     * Set of applications that we consider to be bad, and will reject
537     * incoming broadcasts from (which the user has no control over).
538     * Processes are added to this set when they have crashed twice within
539     * a minimum amount of time; they are removed from it when they are
540     * later restarted (hopefully due to some user action).  The value is the
541     * time it was added to the list.
542     */
543    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
544
545    /**
546     * All of the processes we currently have running organized by pid.
547     * The keys are the pid running the application.
548     *
549     * <p>NOTE: This object is protected by its own lock, NOT the global
550     * activity manager lock!
551     */
552    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
553
554    /**
555     * All of the processes that have been forced to be foreground.  The key
556     * is the pid of the caller who requested it (we hold a death
557     * link on it).
558     */
559    abstract class ForegroundToken implements IBinder.DeathRecipient {
560        int pid;
561        IBinder token;
562    }
563    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
564
565    /**
566     * List of records for processes that someone had tried to start before the
567     * system was ready.  We don't start them at that point, but ensure they
568     * are started by the time booting is complete.
569     */
570    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
571
572    /**
573     * List of persistent applications that are in the process
574     * of being started.
575     */
576    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes that are being forcibly torn down.
580     */
581    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * List of running applications, sorted by recent usage.
585     * The first entry in the list is the least recently used.
586     */
587    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
588
589    /**
590     * Where in mLruProcesses that the processes hosting activities start.
591     */
592    int mLruProcessActivityStart = 0;
593
594    /**
595     * Where in mLruProcesses that the processes hosting services start.
596     * This is after (lower index) than mLruProcessesActivityStart.
597     */
598    int mLruProcessServiceStart = 0;
599
600    /**
601     * List of processes that should gc as soon as things are idle.
602     */
603    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
604
605    /**
606     * Processes we want to collect PSS data from.
607     */
608    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
609
610    /**
611     * Last time we requested PSS data of all processes.
612     */
613    long mLastFullPssTime = SystemClock.uptimeMillis();
614
615    /**
616     * If set, the next time we collect PSS data we should do a full collection
617     * with data from native processes and the kernel.
618     */
619    boolean mFullPssPending = false;
620
621    /**
622     * This is the process holding what we currently consider to be
623     * the "home" activity.
624     */
625    ProcessRecord mHomeProcess;
626
627    /**
628     * This is the process holding the activity the user last visited that
629     * is in a different process from the one they are currently in.
630     */
631    ProcessRecord mPreviousProcess;
632
633    /**
634     * The time at which the previous process was last visible.
635     */
636    long mPreviousProcessVisibleTime;
637
638    /**
639     * Which uses have been started, so are allowed to run code.
640     */
641    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
642
643    /**
644     * LRU list of history of current users.  Most recently current is at the end.
645     */
646    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
647
648    /**
649     * Constant array of the users that are currently started.
650     */
651    int[] mStartedUserArray = new int[] { 0 };
652
653    /**
654     * Registered observers of the user switching mechanics.
655     */
656    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
657            = new RemoteCallbackList<IUserSwitchObserver>();
658
659    /**
660     * Currently active user switch.
661     */
662    Object mCurUserSwitchCallback;
663
664    /**
665     * Packages that the user has asked to have run in screen size
666     * compatibility mode instead of filling the screen.
667     */
668    final CompatModePackages mCompatModePackages;
669
670    /**
671     * Set of IntentSenderRecord objects that are currently active.
672     */
673    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
674            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
675
676    /**
677     * Fingerprints (hashCode()) of stack traces that we've
678     * already logged DropBox entries for.  Guarded by itself.  If
679     * something (rogue user app) forces this over
680     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
681     */
682    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
683    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
684
685    /**
686     * Strict Mode background batched logging state.
687     *
688     * The string buffer is guarded by itself, and its lock is also
689     * used to determine if another batched write is already
690     * in-flight.
691     */
692    private final StringBuilder mStrictModeBuffer = new StringBuilder();
693
694    /**
695     * Keeps track of all IIntentReceivers that have been registered for
696     * broadcasts.  Hash keys are the receiver IBinder, hash value is
697     * a ReceiverList.
698     */
699    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
700            new HashMap<IBinder, ReceiverList>();
701
702    /**
703     * Resolver for broadcast intents to registered receivers.
704     * Holds BroadcastFilter (subclass of IntentFilter).
705     */
706    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
707            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
708        @Override
709        protected boolean allowFilterResult(
710                BroadcastFilter filter, List<BroadcastFilter> dest) {
711            IBinder target = filter.receiverList.receiver.asBinder();
712            for (int i=dest.size()-1; i>=0; i--) {
713                if (dest.get(i).receiverList.receiver.asBinder() == target) {
714                    return false;
715                }
716            }
717            return true;
718        }
719
720        @Override
721        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
722            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
723                    || userId == filter.owningUserId) {
724                return super.newResult(filter, match, userId);
725            }
726            return null;
727        }
728
729        @Override
730        protected BroadcastFilter[] newArray(int size) {
731            return new BroadcastFilter[size];
732        }
733
734        @Override
735        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
736            return packageName.equals(filter.packageName);
737        }
738    };
739
740    /**
741     * State of all active sticky broadcasts per user.  Keys are the action of the
742     * sticky Intent, values are an ArrayList of all broadcasted intents with
743     * that action (which should usually be one).  The SparseArray is keyed
744     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
745     * for stickies that are sent to all users.
746     */
747    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
748            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
749
750    final ActiveServices mServices;
751
752    /**
753     * Backup/restore process management
754     */
755    String mBackupAppName = null;
756    BackupRecord mBackupTarget = null;
757
758    final ProviderMap mProviderMap;
759
760    /**
761     * List of content providers who have clients waiting for them.  The
762     * application is currently being launched and the provider will be
763     * removed from this list once it is published.
764     */
765    final ArrayList<ContentProviderRecord> mLaunchingProviders
766            = new ArrayList<ContentProviderRecord>();
767
768    /**
769     * File storing persisted {@link #mGrantedUriPermissions}.
770     */
771    private final AtomicFile mGrantFile;
772
773    /** XML constants used in {@link #mGrantFile} */
774    private static final String TAG_URI_GRANTS = "uri-grants";
775    private static final String TAG_URI_GRANT = "uri-grant";
776    private static final String ATTR_USER_HANDLE = "userHandle";
777    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
778    private static final String ATTR_TARGET_USER_ID = "targetUserId";
779    private static final String ATTR_SOURCE_PKG = "sourcePkg";
780    private static final String ATTR_TARGET_PKG = "targetPkg";
781    private static final String ATTR_URI = "uri";
782    private static final String ATTR_MODE_FLAGS = "modeFlags";
783    private static final String ATTR_CREATED_TIME = "createdTime";
784    private static final String ATTR_PREFIX = "prefix";
785
786    /**
787     * Global set of specific {@link Uri} permissions that have been granted.
788     * This optimized lookup structure maps from {@link UriPermission#targetUid}
789     * to {@link UriPermission#uri} to {@link UriPermission}.
790     */
791    @GuardedBy("this")
792    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
793            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
794
795    public static class GrantUri {
796        public final int sourceUserId;
797        public final Uri uri;
798        public boolean prefix;
799
800        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
801            this.sourceUserId = sourceUserId;
802            this.uri = uri;
803            this.prefix = prefix;
804        }
805
806        @Override
807        public int hashCode() {
808            int hashCode = 1;
809            hashCode = 31 * hashCode + sourceUserId;
810            hashCode = 31 * hashCode + uri.hashCode();
811            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
812            return hashCode;
813        }
814
815        @Override
816        public boolean equals(Object o) {
817            if (o instanceof GrantUri) {
818                GrantUri other = (GrantUri) o;
819                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
820                        && prefix == other.prefix;
821            }
822            return false;
823        }
824
825        @Override
826        public String toString() {
827            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
828            if (prefix) result += " [prefix]";
829            return result;
830        }
831
832        public String toSafeString() {
833            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
834            if (prefix) result += " [prefix]";
835            return result;
836        }
837
838        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
839            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
840                    ContentProvider.getUriWithoutUserId(uri), false);
841        }
842    }
843
844    CoreSettingsObserver mCoreSettingsObserver;
845
846    /**
847     * Thread-local storage used to carry caller permissions over through
848     * indirect content-provider access.
849     */
850    private class Identity {
851        public final IBinder token;
852        public final int pid;
853        public final int uid;
854
855        Identity(IBinder _token, int _pid, int _uid) {
856            token = _token;
857            pid = _pid;
858            uid = _uid;
859        }
860    }
861
862    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
863
864    /**
865     * All information we have collected about the runtime performance of
866     * any user id that can impact battery performance.
867     */
868    final BatteryStatsService mBatteryStatsService;
869
870    /**
871     * Information about component usage
872     */
873    UsageStatsManagerInternal mUsageStatsService;
874
875    /**
876     * Information about and control over application operations
877     */
878    final AppOpsService mAppOpsService;
879
880    /**
881     * Save recent tasks information across reboots.
882     */
883    final TaskPersister mTaskPersister;
884
885    /**
886     * Current configuration information.  HistoryRecord objects are given
887     * a reference to this object to indicate which configuration they are
888     * currently running in, so this object must be kept immutable.
889     */
890    Configuration mConfiguration = new Configuration();
891
892    /**
893     * Current sequencing integer of the configuration, for skipping old
894     * configurations.
895     */
896    int mConfigurationSeq = 0;
897
898    /**
899     * Hardware-reported OpenGLES version.
900     */
901    final int GL_ES_VERSION;
902
903    /**
904     * List of initialization arguments to pass to all processes when binding applications to them.
905     * For example, references to the commonly used services.
906     */
907    HashMap<String, IBinder> mAppBindArgs;
908
909    /**
910     * Temporary to avoid allocations.  Protected by main lock.
911     */
912    final StringBuilder mStringBuilder = new StringBuilder(256);
913
914    /**
915     * Used to control how we initialize the service.
916     */
917    ComponentName mTopComponent;
918    String mTopAction = Intent.ACTION_MAIN;
919    String mTopData;
920    boolean mProcessesReady = false;
921    boolean mSystemReady = false;
922    boolean mBooting = false;
923    boolean mCallFinishBooting = false;
924    boolean mBootAnimationComplete = false;
925    boolean mWaitingUpdate = false;
926    boolean mDidUpdate = false;
927    boolean mOnBattery = false;
928    boolean mLaunchWarningShown = false;
929
930    Context mContext;
931
932    int mFactoryTest;
933
934    boolean mCheckedForSetup;
935
936    /**
937     * The time at which we will allow normal application switches again,
938     * after a call to {@link #stopAppSwitches()}.
939     */
940    long mAppSwitchesAllowedTime;
941
942    /**
943     * This is set to true after the first switch after mAppSwitchesAllowedTime
944     * is set; any switches after that will clear the time.
945     */
946    boolean mDidAppSwitch;
947
948    /**
949     * Last time (in realtime) at which we checked for power usage.
950     */
951    long mLastPowerCheckRealtime;
952
953    /**
954     * Last time (in uptime) at which we checked for power usage.
955     */
956    long mLastPowerCheckUptime;
957
958    /**
959     * Set while we are wanting to sleep, to prevent any
960     * activities from being started/resumed.
961     */
962    private boolean mSleeping = false;
963
964    /**
965     * Set while we are running a voice interaction.  This overrides
966     * sleeping while it is active.
967     */
968    private boolean mRunningVoice = false;
969
970    /**
971     * State of external calls telling us if the device is awake or asleep.
972     */
973    private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
974
975    static final int LOCK_SCREEN_HIDDEN = 0;
976    static final int LOCK_SCREEN_LEAVING = 1;
977    static final int LOCK_SCREEN_SHOWN = 2;
978    /**
979     * State of external call telling us if the lock screen is shown.
980     */
981    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
982
983    /**
984     * Set if we are shutting down the system, similar to sleeping.
985     */
986    boolean mShuttingDown = false;
987
988    /**
989     * Current sequence id for oom_adj computation traversal.
990     */
991    int mAdjSeq = 0;
992
993    /**
994     * Current sequence id for process LRU updating.
995     */
996    int mLruSeq = 0;
997
998    /**
999     * Keep track of the non-cached/empty process we last found, to help
1000     * determine how to distribute cached/empty processes next time.
1001     */
1002    int mNumNonCachedProcs = 0;
1003
1004    /**
1005     * Keep track of the number of cached hidden procs, to balance oom adj
1006     * distribution between those and empty procs.
1007     */
1008    int mNumCachedHiddenProcs = 0;
1009
1010    /**
1011     * Keep track of the number of service processes we last found, to
1012     * determine on the next iteration which should be B services.
1013     */
1014    int mNumServiceProcs = 0;
1015    int mNewNumAServiceProcs = 0;
1016    int mNewNumServiceProcs = 0;
1017
1018    /**
1019     * Allow the current computed overall memory level of the system to go down?
1020     * This is set to false when we are killing processes for reasons other than
1021     * memory management, so that the now smaller process list will not be taken as
1022     * an indication that memory is tighter.
1023     */
1024    boolean mAllowLowerMemLevel = false;
1025
1026    /**
1027     * The last computed memory level, for holding when we are in a state that
1028     * processes are going away for other reasons.
1029     */
1030    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1031
1032    /**
1033     * The last total number of process we have, to determine if changes actually look
1034     * like a shrinking number of process due to lower RAM.
1035     */
1036    int mLastNumProcesses;
1037
1038    /**
1039     * The uptime of the last time we performed idle maintenance.
1040     */
1041    long mLastIdleTime = SystemClock.uptimeMillis();
1042
1043    /**
1044     * Total time spent with RAM that has been added in the past since the last idle time.
1045     */
1046    long mLowRamTimeSinceLastIdle = 0;
1047
1048    /**
1049     * If RAM is currently low, when that horrible situation started.
1050     */
1051    long mLowRamStartTime = 0;
1052
1053    /**
1054     * For reporting to battery stats the current top application.
1055     */
1056    private String mCurResumedPackage = null;
1057    private int mCurResumedUid = -1;
1058
1059    /**
1060     * For reporting to battery stats the apps currently running foreground
1061     * service.  The ProcessMap is package/uid tuples; each of these contain
1062     * an array of the currently foreground processes.
1063     */
1064    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1065            = new ProcessMap<ArrayList<ProcessRecord>>();
1066
1067    /**
1068     * This is set if we had to do a delayed dexopt of an app before launching
1069     * it, to increase the ANR timeouts in that case.
1070     */
1071    boolean mDidDexOpt;
1072
1073    /**
1074     * Set if the systemServer made a call to enterSafeMode.
1075     */
1076    boolean mSafeMode;
1077
1078    /**
1079     * If true, we are running under a test environment so will sample PSS from processes
1080     * much more rapidly to try to collect better data when the tests are rapidly
1081     * running through apps.
1082     */
1083    boolean mTestPssMode = false;
1084
1085    String mDebugApp = null;
1086    boolean mWaitForDebugger = false;
1087    boolean mDebugTransient = false;
1088    String mOrigDebugApp = null;
1089    boolean mOrigWaitForDebugger = false;
1090    boolean mAlwaysFinishActivities = false;
1091    IActivityController mController = null;
1092    String mProfileApp = null;
1093    ProcessRecord mProfileProc = null;
1094    String mProfileFile;
1095    ParcelFileDescriptor mProfileFd;
1096    int mSamplingInterval = 0;
1097    boolean mAutoStopProfiler = false;
1098    int mProfileType = 0;
1099    String mOpenGlTraceApp = null;
1100
1101    final long[] mTmpLong = new long[1];
1102
1103    static class ProcessChangeItem {
1104        static final int CHANGE_ACTIVITIES = 1<<0;
1105        static final int CHANGE_PROCESS_STATE = 1<<1;
1106        int changes;
1107        int uid;
1108        int pid;
1109        int processState;
1110        boolean foregroundActivities;
1111    }
1112
1113    final RemoteCallbackList<IProcessObserver> mProcessObservers
1114            = new RemoteCallbackList<IProcessObserver>();
1115    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1116
1117    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1118            = new ArrayList<ProcessChangeItem>();
1119    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1120            = new ArrayList<ProcessChangeItem>();
1121
1122    /**
1123     * Runtime CPU use collection thread.  This object's lock is used to
1124     * perform synchronization with the thread (notifying it to run).
1125     */
1126    final Thread mProcessCpuThread;
1127
1128    /**
1129     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1130     * Must acquire this object's lock when accessing it.
1131     * NOTE: this lock will be held while doing long operations (trawling
1132     * through all processes in /proc), so it should never be acquired by
1133     * any critical paths such as when holding the main activity manager lock.
1134     */
1135    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1136            MONITOR_THREAD_CPU_USAGE);
1137    final AtomicLong mLastCpuTime = new AtomicLong(0);
1138    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1139
1140    long mLastWriteTime = 0;
1141
1142    /**
1143     * Used to retain an update lock when the foreground activity is in
1144     * immersive mode.
1145     */
1146    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1147
1148    /**
1149     * Set to true after the system has finished booting.
1150     */
1151    boolean mBooted = false;
1152
1153    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1154    int mProcessLimitOverride = -1;
1155
1156    WindowManagerService mWindowManager;
1157
1158    final ActivityThread mSystemThread;
1159
1160    // Holds the current foreground user's id
1161    int mCurrentUserId = 0;
1162    // Holds the target user's id during a user switch
1163    int mTargetUserId = UserHandle.USER_NULL;
1164    // If there are multiple profiles for the current user, their ids are here
1165    // Currently only the primary user can have managed profiles
1166    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1167
1168    /**
1169     * Mapping from each known user ID to the profile group ID it is associated with.
1170     */
1171    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1172
1173    private UserManagerService mUserManager;
1174
1175    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1176        final ProcessRecord mApp;
1177        final int mPid;
1178        final IApplicationThread mAppThread;
1179
1180        AppDeathRecipient(ProcessRecord app, int pid,
1181                IApplicationThread thread) {
1182            if (localLOGV) Slog.v(
1183                TAG, "New death recipient " + this
1184                + " for thread " + thread.asBinder());
1185            mApp = app;
1186            mPid = pid;
1187            mAppThread = thread;
1188        }
1189
1190        @Override
1191        public void binderDied() {
1192            if (localLOGV) Slog.v(
1193                TAG, "Death received in " + this
1194                + " for thread " + mAppThread.asBinder());
1195            synchronized(ActivityManagerService.this) {
1196                appDiedLocked(mApp, mPid, mAppThread);
1197            }
1198        }
1199    }
1200
1201    static final int SHOW_ERROR_MSG = 1;
1202    static final int SHOW_NOT_RESPONDING_MSG = 2;
1203    static final int SHOW_FACTORY_ERROR_MSG = 3;
1204    static final int UPDATE_CONFIGURATION_MSG = 4;
1205    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1206    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1207    static final int SERVICE_TIMEOUT_MSG = 12;
1208    static final int UPDATE_TIME_ZONE = 13;
1209    static final int SHOW_UID_ERROR_MSG = 14;
1210    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1211    static final int PROC_START_TIMEOUT_MSG = 20;
1212    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1213    static final int KILL_APPLICATION_MSG = 22;
1214    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1215    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1216    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1217    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1218    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1219    static final int CLEAR_DNS_CACHE_MSG = 28;
1220    static final int UPDATE_HTTP_PROXY_MSG = 29;
1221    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1222    static final int DISPATCH_PROCESSES_CHANGED = 31;
1223    static final int DISPATCH_PROCESS_DIED = 32;
1224    static final int REPORT_MEM_USAGE_MSG = 33;
1225    static final int REPORT_USER_SWITCH_MSG = 34;
1226    static final int CONTINUE_USER_SWITCH_MSG = 35;
1227    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1228    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1229    static final int PERSIST_URI_GRANTS_MSG = 38;
1230    static final int REQUEST_ALL_PSS_MSG = 39;
1231    static final int START_PROFILES_MSG = 40;
1232    static final int UPDATE_TIME = 41;
1233    static final int SYSTEM_USER_START_MSG = 42;
1234    static final int SYSTEM_USER_CURRENT_MSG = 43;
1235    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1236    static final int FINISH_BOOTING_MSG = 45;
1237    static final int START_USER_SWITCH_MSG = 46;
1238    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1239    static final int DISMISS_DIALOG_MSG = 48;
1240    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1241
1242    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1243    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1244    static final int FIRST_COMPAT_MODE_MSG = 300;
1245    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1246
1247    CompatModeDialog mCompatModeDialog;
1248    long mLastMemUsageReportTime = 0;
1249
1250    /**
1251     * Flag whether the current user is a "monkey", i.e. whether
1252     * the UI is driven by a UI automation tool.
1253     */
1254    private boolean mUserIsMonkey;
1255
1256    /** Flag whether the device has a Recents UI */
1257    boolean mHasRecents;
1258
1259    /** The dimensions of the thumbnails in the Recents UI. */
1260    int mThumbnailWidth;
1261    int mThumbnailHeight;
1262
1263    final ServiceThread mHandlerThread;
1264    final MainHandler mHandler;
1265
1266    final class MainHandler extends Handler {
1267        public MainHandler(Looper looper) {
1268            super(looper, null, true);
1269        }
1270
1271        @Override
1272        public void handleMessage(Message msg) {
1273            switch (msg.what) {
1274            case SHOW_ERROR_MSG: {
1275                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1276                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1277                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1278                synchronized (ActivityManagerService.this) {
1279                    ProcessRecord proc = (ProcessRecord)data.get("app");
1280                    AppErrorResult res = (AppErrorResult) data.get("result");
1281                    if (proc != null && proc.crashDialog != null) {
1282                        Slog.e(TAG, "App already has crash dialog: " + proc);
1283                        if (res != null) {
1284                            res.set(0);
1285                        }
1286                        return;
1287                    }
1288                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1289                            >= Process.FIRST_APPLICATION_UID
1290                            && proc.pid != MY_PID);
1291                    for (int userId : mCurrentProfileIds) {
1292                        isBackground &= (proc.userId != userId);
1293                    }
1294                    if (isBackground && !showBackground) {
1295                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1296                        if (res != null) {
1297                            res.set(0);
1298                        }
1299                        return;
1300                    }
1301                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1302                        Dialog d = new AppErrorDialog(mContext,
1303                                ActivityManagerService.this, res, proc);
1304                        d.show();
1305                        proc.crashDialog = d;
1306                    } else {
1307                        // The device is asleep, so just pretend that the user
1308                        // saw a crash dialog and hit "force quit".
1309                        if (res != null) {
1310                            res.set(0);
1311                        }
1312                    }
1313                }
1314
1315                ensureBootCompleted();
1316            } break;
1317            case SHOW_NOT_RESPONDING_MSG: {
1318                synchronized (ActivityManagerService.this) {
1319                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                    ProcessRecord proc = (ProcessRecord)data.get("app");
1321                    if (proc != null && proc.anrDialog != null) {
1322                        Slog.e(TAG, "App already has anr dialog: " + proc);
1323                        return;
1324                    }
1325
1326                    Intent intent = new Intent("android.intent.action.ANR");
1327                    if (!mProcessesReady) {
1328                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1329                                | Intent.FLAG_RECEIVER_FOREGROUND);
1330                    }
1331                    broadcastIntentLocked(null, null, intent,
1332                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1333                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1334
1335                    if (mShowDialogs) {
1336                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1337                                mContext, proc, (ActivityRecord)data.get("activity"),
1338                                msg.arg1 != 0);
1339                        d.show();
1340                        proc.anrDialog = d;
1341                    } else {
1342                        // Just kill the app if there is no dialog to be shown.
1343                        killAppAtUsersRequest(proc, null);
1344                    }
1345                }
1346
1347                ensureBootCompleted();
1348            } break;
1349            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1350                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1351                synchronized (ActivityManagerService.this) {
1352                    ProcessRecord proc = (ProcessRecord) data.get("app");
1353                    if (proc == null) {
1354                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1355                        break;
1356                    }
1357                    if (proc.crashDialog != null) {
1358                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1359                        return;
1360                    }
1361                    AppErrorResult res = (AppErrorResult) data.get("result");
1362                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1363                        Dialog d = new StrictModeViolationDialog(mContext,
1364                                ActivityManagerService.this, res, proc);
1365                        d.show();
1366                        proc.crashDialog = d;
1367                    } else {
1368                        // The device is asleep, so just pretend that the user
1369                        // saw a crash dialog and hit "force quit".
1370                        res.set(0);
1371                    }
1372                }
1373                ensureBootCompleted();
1374            } break;
1375            case SHOW_FACTORY_ERROR_MSG: {
1376                Dialog d = new FactoryErrorDialog(
1377                    mContext, msg.getData().getCharSequence("msg"));
1378                d.show();
1379                ensureBootCompleted();
1380            } break;
1381            case UPDATE_CONFIGURATION_MSG: {
1382                final ContentResolver resolver = mContext.getContentResolver();
1383                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1384            } break;
1385            case GC_BACKGROUND_PROCESSES_MSG: {
1386                synchronized (ActivityManagerService.this) {
1387                    performAppGcsIfAppropriateLocked();
1388                }
1389            } break;
1390            case WAIT_FOR_DEBUGGER_MSG: {
1391                synchronized (ActivityManagerService.this) {
1392                    ProcessRecord app = (ProcessRecord)msg.obj;
1393                    if (msg.arg1 != 0) {
1394                        if (!app.waitedForDebugger) {
1395                            Dialog d = new AppWaitingForDebuggerDialog(
1396                                    ActivityManagerService.this,
1397                                    mContext, app);
1398                            app.waitDialog = d;
1399                            app.waitedForDebugger = true;
1400                            d.show();
1401                        }
1402                    } else {
1403                        if (app.waitDialog != null) {
1404                            app.waitDialog.dismiss();
1405                            app.waitDialog = null;
1406                        }
1407                    }
1408                }
1409            } break;
1410            case SERVICE_TIMEOUT_MSG: {
1411                if (mDidDexOpt) {
1412                    mDidDexOpt = false;
1413                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1414                    nmsg.obj = msg.obj;
1415                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1416                    return;
1417                }
1418                mServices.serviceTimeout((ProcessRecord)msg.obj);
1419            } break;
1420            case UPDATE_TIME_ZONE: {
1421                synchronized (ActivityManagerService.this) {
1422                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1423                        ProcessRecord r = mLruProcesses.get(i);
1424                        if (r.thread != null) {
1425                            try {
1426                                r.thread.updateTimeZone();
1427                            } catch (RemoteException ex) {
1428                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1429                            }
1430                        }
1431                    }
1432                }
1433            } break;
1434            case CLEAR_DNS_CACHE_MSG: {
1435                synchronized (ActivityManagerService.this) {
1436                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1437                        ProcessRecord r = mLruProcesses.get(i);
1438                        if (r.thread != null) {
1439                            try {
1440                                r.thread.clearDnsCache();
1441                            } catch (RemoteException ex) {
1442                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1443                            }
1444                        }
1445                    }
1446                }
1447            } break;
1448            case UPDATE_HTTP_PROXY_MSG: {
1449                ProxyInfo proxy = (ProxyInfo)msg.obj;
1450                String host = "";
1451                String port = "";
1452                String exclList = "";
1453                Uri pacFileUrl = Uri.EMPTY;
1454                if (proxy != null) {
1455                    host = proxy.getHost();
1456                    port = Integer.toString(proxy.getPort());
1457                    exclList = proxy.getExclusionListAsString();
1458                    pacFileUrl = proxy.getPacFileUrl();
1459                }
1460                synchronized (ActivityManagerService.this) {
1461                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1462                        ProcessRecord r = mLruProcesses.get(i);
1463                        if (r.thread != null) {
1464                            try {
1465                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1466                            } catch (RemoteException ex) {
1467                                Slog.w(TAG, "Failed to update http proxy for: " +
1468                                        r.info.processName);
1469                            }
1470                        }
1471                    }
1472                }
1473            } break;
1474            case SHOW_UID_ERROR_MSG: {
1475                if (mShowDialogs) {
1476                    AlertDialog d = new BaseErrorDialog(mContext);
1477                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1478                    d.setCancelable(false);
1479                    d.setTitle(mContext.getText(R.string.android_system_label));
1480                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1481                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1482                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1483                    d.show();
1484                }
1485            } break;
1486            case SHOW_FINGERPRINT_ERROR_MSG: {
1487                if (mShowDialogs) {
1488                    AlertDialog d = new BaseErrorDialog(mContext);
1489                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1490                    d.setCancelable(false);
1491                    d.setTitle(mContext.getText(R.string.android_system_label));
1492                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1493                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1494                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1495                    d.show();
1496                }
1497            } break;
1498            case PROC_START_TIMEOUT_MSG: {
1499                if (mDidDexOpt) {
1500                    mDidDexOpt = false;
1501                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1502                    nmsg.obj = msg.obj;
1503                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1504                    return;
1505                }
1506                ProcessRecord app = (ProcessRecord)msg.obj;
1507                synchronized (ActivityManagerService.this) {
1508                    processStartTimedOutLocked(app);
1509                }
1510            } break;
1511            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1512                synchronized (ActivityManagerService.this) {
1513                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1514                }
1515            } break;
1516            case KILL_APPLICATION_MSG: {
1517                synchronized (ActivityManagerService.this) {
1518                    int appid = msg.arg1;
1519                    boolean restart = (msg.arg2 == 1);
1520                    Bundle bundle = (Bundle)msg.obj;
1521                    String pkg = bundle.getString("pkg");
1522                    String reason = bundle.getString("reason");
1523                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1524                            false, UserHandle.USER_ALL, reason);
1525                }
1526            } break;
1527            case FINALIZE_PENDING_INTENT_MSG: {
1528                ((PendingIntentRecord)msg.obj).completeFinalize();
1529            } break;
1530            case POST_HEAVY_NOTIFICATION_MSG: {
1531                INotificationManager inm = NotificationManager.getService();
1532                if (inm == null) {
1533                    return;
1534                }
1535
1536                ActivityRecord root = (ActivityRecord)msg.obj;
1537                ProcessRecord process = root.app;
1538                if (process == null) {
1539                    return;
1540                }
1541
1542                try {
1543                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1544                    String text = mContext.getString(R.string.heavy_weight_notification,
1545                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1546                    Notification notification = new Notification();
1547                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1548                    notification.when = 0;
1549                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1550                    notification.tickerText = text;
1551                    notification.defaults = 0; // please be quiet
1552                    notification.sound = null;
1553                    notification.vibrate = null;
1554                    notification.color = mContext.getResources().getColor(
1555                            com.android.internal.R.color.system_notification_accent_color);
1556                    notification.setLatestEventInfo(context, text,
1557                            mContext.getText(R.string.heavy_weight_notification_detail),
1558                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1559                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1560                                    new UserHandle(root.userId)));
1561
1562                    try {
1563                        int[] outId = new int[1];
1564                        inm.enqueueNotificationWithTag("android", "android", null,
1565                                R.string.heavy_weight_notification,
1566                                notification, outId, root.userId);
1567                    } catch (RuntimeException e) {
1568                        Slog.w(ActivityManagerService.TAG,
1569                                "Error showing notification for heavy-weight app", e);
1570                    } catch (RemoteException e) {
1571                    }
1572                } catch (NameNotFoundException e) {
1573                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1574                }
1575            } break;
1576            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1577                INotificationManager inm = NotificationManager.getService();
1578                if (inm == null) {
1579                    return;
1580                }
1581                try {
1582                    inm.cancelNotificationWithTag("android", null,
1583                            R.string.heavy_weight_notification,  msg.arg1);
1584                } catch (RuntimeException e) {
1585                    Slog.w(ActivityManagerService.TAG,
1586                            "Error canceling notification for service", e);
1587                } catch (RemoteException e) {
1588                }
1589            } break;
1590            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1591                synchronized (ActivityManagerService.this) {
1592                    checkExcessivePowerUsageLocked(true);
1593                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1594                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1595                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1596                }
1597            } break;
1598            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1599                synchronized (ActivityManagerService.this) {
1600                    ActivityRecord ar = (ActivityRecord)msg.obj;
1601                    if (mCompatModeDialog != null) {
1602                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1603                                ar.info.applicationInfo.packageName)) {
1604                            return;
1605                        }
1606                        mCompatModeDialog.dismiss();
1607                        mCompatModeDialog = null;
1608                    }
1609                    if (ar != null && false) {
1610                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1611                                ar.packageName)) {
1612                            int mode = mCompatModePackages.computeCompatModeLocked(
1613                                    ar.info.applicationInfo);
1614                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1615                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1616                                mCompatModeDialog = new CompatModeDialog(
1617                                        ActivityManagerService.this, mContext,
1618                                        ar.info.applicationInfo);
1619                                mCompatModeDialog.show();
1620                            }
1621                        }
1622                    }
1623                }
1624                break;
1625            }
1626            case DISPATCH_PROCESSES_CHANGED: {
1627                dispatchProcessesChanged();
1628                break;
1629            }
1630            case DISPATCH_PROCESS_DIED: {
1631                final int pid = msg.arg1;
1632                final int uid = msg.arg2;
1633                dispatchProcessDied(pid, uid);
1634                break;
1635            }
1636            case REPORT_MEM_USAGE_MSG: {
1637                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1638                Thread thread = new Thread() {
1639                    @Override public void run() {
1640                        reportMemUsage(memInfos);
1641                    }
1642                };
1643                thread.start();
1644                break;
1645            }
1646            case START_USER_SWITCH_MSG: {
1647                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1648                break;
1649            }
1650            case REPORT_USER_SWITCH_MSG: {
1651                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1652                break;
1653            }
1654            case CONTINUE_USER_SWITCH_MSG: {
1655                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1656                break;
1657            }
1658            case USER_SWITCH_TIMEOUT_MSG: {
1659                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1660                break;
1661            }
1662            case IMMERSIVE_MODE_LOCK_MSG: {
1663                final boolean nextState = (msg.arg1 != 0);
1664                if (mUpdateLock.isHeld() != nextState) {
1665                    if (DEBUG_IMMERSIVE) {
1666                        final ActivityRecord r = (ActivityRecord) msg.obj;
1667                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1668                    }
1669                    if (nextState) {
1670                        mUpdateLock.acquire();
1671                    } else {
1672                        mUpdateLock.release();
1673                    }
1674                }
1675                break;
1676            }
1677            case PERSIST_URI_GRANTS_MSG: {
1678                writeGrantedUriPermissions();
1679                break;
1680            }
1681            case REQUEST_ALL_PSS_MSG: {
1682                synchronized (ActivityManagerService.this) {
1683                    requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1684                }
1685                break;
1686            }
1687            case START_PROFILES_MSG: {
1688                synchronized (ActivityManagerService.this) {
1689                    startProfilesLocked();
1690                }
1691                break;
1692            }
1693            case UPDATE_TIME: {
1694                synchronized (ActivityManagerService.this) {
1695                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1696                        ProcessRecord r = mLruProcesses.get(i);
1697                        if (r.thread != null) {
1698                            try {
1699                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1700                            } catch (RemoteException ex) {
1701                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1702                            }
1703                        }
1704                    }
1705                }
1706                break;
1707            }
1708            case SYSTEM_USER_START_MSG: {
1709                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1710                        Integer.toString(msg.arg1), msg.arg1);
1711                mSystemServiceManager.startUser(msg.arg1);
1712                break;
1713            }
1714            case SYSTEM_USER_CURRENT_MSG: {
1715                mBatteryStatsService.noteEvent(
1716                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1717                        Integer.toString(msg.arg2), msg.arg2);
1718                mBatteryStatsService.noteEvent(
1719                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1720                        Integer.toString(msg.arg1), msg.arg1);
1721                mSystemServiceManager.switchUser(msg.arg1);
1722                break;
1723            }
1724            case ENTER_ANIMATION_COMPLETE_MSG: {
1725                synchronized (ActivityManagerService.this) {
1726                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1727                    if (r != null && r.app != null && r.app.thread != null) {
1728                        try {
1729                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1730                        } catch (RemoteException e) {
1731                        }
1732                    }
1733                }
1734                break;
1735            }
1736            case FINISH_BOOTING_MSG: {
1737                if (msg.arg1 != 0) {
1738                    finishBooting();
1739                }
1740                if (msg.arg2 != 0) {
1741                    enableScreenAfterBoot();
1742                }
1743                break;
1744            }
1745            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1746                try {
1747                    Locale l = (Locale) msg.obj;
1748                    IBinder service = ServiceManager.getService("mount");
1749                    IMountService mountService = IMountService.Stub.asInterface(service);
1750                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1751                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1752                } catch (RemoteException e) {
1753                    Log.e(TAG, "Error storing locale for decryption UI", e);
1754                }
1755                break;
1756            }
1757            case DISMISS_DIALOG_MSG: {
1758                final Dialog d = (Dialog) msg.obj;
1759                d.dismiss();
1760                break;
1761            }
1762            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1763                synchronized (ActivityManagerService.this) {
1764                    int i = mTaskStackListeners.beginBroadcast();
1765                    while (i > 0) {
1766                        i--;
1767                        try {
1768                            // Make a one-way callback to the listener
1769                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1770                        } catch (RemoteException e){
1771                            // Handled by the RemoteCallbackList
1772                        }
1773                    }
1774                    mTaskStackListeners.finishBroadcast();
1775                }
1776                break;
1777            }
1778            }
1779        }
1780    };
1781
1782    static final int COLLECT_PSS_BG_MSG = 1;
1783
1784    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1785        @Override
1786        public void handleMessage(Message msg) {
1787            switch (msg.what) {
1788            case COLLECT_PSS_BG_MSG: {
1789                long start = SystemClock.uptimeMillis();
1790                MemInfoReader memInfo = null;
1791                synchronized (ActivityManagerService.this) {
1792                    if (mFullPssPending) {
1793                        mFullPssPending = false;
1794                        memInfo = new MemInfoReader();
1795                    }
1796                }
1797                if (memInfo != null) {
1798                    updateCpuStatsNow();
1799                    long nativeTotalPss = 0;
1800                    synchronized (mProcessCpuTracker) {
1801                        final int N = mProcessCpuTracker.countStats();
1802                        for (int j=0; j<N; j++) {
1803                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1804                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1805                                // This is definitely an application process; skip it.
1806                                continue;
1807                            }
1808                            synchronized (mPidsSelfLocked) {
1809                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1810                                    // This is one of our own processes; skip it.
1811                                    continue;
1812                                }
1813                            }
1814                            nativeTotalPss += Debug.getPss(st.pid, null, null);
1815                        }
1816                    }
1817                    memInfo.readMemInfo();
1818                    synchronized (ActivityManagerService.this) {
1819                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1820                                + (SystemClock.uptimeMillis()-start) + "ms");
1821                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1822                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1823                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1824                    }
1825                }
1826
1827                int num = 0;
1828                long[] tmp = new long[1];
1829                do {
1830                    ProcessRecord proc;
1831                    int procState;
1832                    int pid;
1833                    long lastPssTime;
1834                    synchronized (ActivityManagerService.this) {
1835                        if (mPendingPssProcesses.size() <= 0) {
1836                            if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1837                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1838                            mPendingPssProcesses.clear();
1839                            return;
1840                        }
1841                        proc = mPendingPssProcesses.remove(0);
1842                        procState = proc.pssProcState;
1843                        lastPssTime = proc.lastPssTime;
1844                        if (proc.thread != null && procState == proc.setProcState) {
1845                            pid = proc.pid;
1846                        } else {
1847                            proc = null;
1848                            pid = 0;
1849                        }
1850                    }
1851                    if (proc != null) {
1852                        long pss = Debug.getPss(pid, tmp, null);
1853                        synchronized (ActivityManagerService.this) {
1854                            if (pss != 0 && proc.thread != null && proc.setProcState == procState
1855                                    && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1856                                num++;
1857                                recordPssSample(proc, procState, pss, tmp[0],
1858                                        SystemClock.uptimeMillis());
1859                            }
1860                        }
1861                    }
1862                } while (true);
1863            }
1864            }
1865        }
1866    };
1867
1868    public void setSystemProcess() {
1869        try {
1870            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1871            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1872            ServiceManager.addService("meminfo", new MemBinder(this));
1873            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1874            ServiceManager.addService("dbinfo", new DbBinder(this));
1875            if (MONITOR_CPU_USAGE) {
1876                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1877            }
1878            ServiceManager.addService("permission", new PermissionController(this));
1879
1880            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1881                    "android", STOCK_PM_FLAGS);
1882            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1883
1884            synchronized (this) {
1885                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1886                app.persistent = true;
1887                app.pid = MY_PID;
1888                app.maxAdj = ProcessList.SYSTEM_ADJ;
1889                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1890                mProcessNames.put(app.processName, app.uid, app);
1891                synchronized (mPidsSelfLocked) {
1892                    mPidsSelfLocked.put(app.pid, app);
1893                }
1894                updateLruProcessLocked(app, false, null);
1895                updateOomAdjLocked();
1896            }
1897        } catch (PackageManager.NameNotFoundException e) {
1898            throw new RuntimeException(
1899                    "Unable to find android system package", e);
1900        }
1901    }
1902
1903    public void setWindowManager(WindowManagerService wm) {
1904        mWindowManager = wm;
1905        mStackSupervisor.setWindowManager(wm);
1906    }
1907
1908    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1909        mUsageStatsService = usageStatsManager;
1910    }
1911
1912    public void startObservingNativeCrashes() {
1913        final NativeCrashListener ncl = new NativeCrashListener(this);
1914        ncl.start();
1915    }
1916
1917    public IAppOpsService getAppOpsService() {
1918        return mAppOpsService;
1919    }
1920
1921    static class MemBinder extends Binder {
1922        ActivityManagerService mActivityManagerService;
1923        MemBinder(ActivityManagerService activityManagerService) {
1924            mActivityManagerService = activityManagerService;
1925        }
1926
1927        @Override
1928        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1929            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1930                    != PackageManager.PERMISSION_GRANTED) {
1931                pw.println("Permission Denial: can't dump meminfo from from pid="
1932                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1933                        + " without permission " + android.Manifest.permission.DUMP);
1934                return;
1935            }
1936
1937            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1938        }
1939    }
1940
1941    static class GraphicsBinder extends Binder {
1942        ActivityManagerService mActivityManagerService;
1943        GraphicsBinder(ActivityManagerService activityManagerService) {
1944            mActivityManagerService = activityManagerService;
1945        }
1946
1947        @Override
1948        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1949            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1950                    != PackageManager.PERMISSION_GRANTED) {
1951                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1952                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1953                        + " without permission " + android.Manifest.permission.DUMP);
1954                return;
1955            }
1956
1957            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1958        }
1959    }
1960
1961    static class DbBinder extends Binder {
1962        ActivityManagerService mActivityManagerService;
1963        DbBinder(ActivityManagerService activityManagerService) {
1964            mActivityManagerService = activityManagerService;
1965        }
1966
1967        @Override
1968        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1969            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1970                    != PackageManager.PERMISSION_GRANTED) {
1971                pw.println("Permission Denial: can't dump dbinfo from from pid="
1972                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1973                        + " without permission " + android.Manifest.permission.DUMP);
1974                return;
1975            }
1976
1977            mActivityManagerService.dumpDbInfo(fd, pw, args);
1978        }
1979    }
1980
1981    static class CpuBinder extends Binder {
1982        ActivityManagerService mActivityManagerService;
1983        CpuBinder(ActivityManagerService activityManagerService) {
1984            mActivityManagerService = activityManagerService;
1985        }
1986
1987        @Override
1988        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1989            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1990                    != PackageManager.PERMISSION_GRANTED) {
1991                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1992                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1993                        + " without permission " + android.Manifest.permission.DUMP);
1994                return;
1995            }
1996
1997            synchronized (mActivityManagerService.mProcessCpuTracker) {
1998                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1999                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2000                        SystemClock.uptimeMillis()));
2001            }
2002        }
2003    }
2004
2005    public static final class Lifecycle extends SystemService {
2006        private final ActivityManagerService mService;
2007
2008        public Lifecycle(Context context) {
2009            super(context);
2010            mService = new ActivityManagerService(context);
2011        }
2012
2013        @Override
2014        public void onStart() {
2015            mService.start();
2016        }
2017
2018        public ActivityManagerService getService() {
2019            return mService;
2020        }
2021    }
2022
2023    // Note: This method is invoked on the main thread but may need to attach various
2024    // handlers to other threads.  So take care to be explicit about the looper.
2025    public ActivityManagerService(Context systemContext) {
2026        mContext = systemContext;
2027        mFactoryTest = FactoryTest.getMode();
2028        mSystemThread = ActivityThread.currentActivityThread();
2029
2030        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2031
2032        mHandlerThread = new ServiceThread(TAG,
2033                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2034        mHandlerThread.start();
2035        mHandler = new MainHandler(mHandlerThread.getLooper());
2036
2037        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2038                "foreground", BROADCAST_FG_TIMEOUT, false);
2039        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2040                "background", BROADCAST_BG_TIMEOUT, true);
2041        mBroadcastQueues[0] = mFgBroadcastQueue;
2042        mBroadcastQueues[1] = mBgBroadcastQueue;
2043
2044        mServices = new ActiveServices(this);
2045        mProviderMap = new ProviderMap(this);
2046
2047        // TODO: Move creation of battery stats service outside of activity manager service.
2048        File dataDir = Environment.getDataDirectory();
2049        File systemDir = new File(dataDir, "system");
2050        systemDir.mkdirs();
2051        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2052        mBatteryStatsService.getActiveStatistics().readLocked();
2053        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2054        mOnBattery = DEBUG_POWER ? true
2055                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2056        mBatteryStatsService.getActiveStatistics().setCallback(this);
2057
2058        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2059
2060        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2061
2062        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2063
2064        // User 0 is the first and only user that runs at boot.
2065        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2066        mUserLru.add(Integer.valueOf(0));
2067        updateStartedUserArrayLocked();
2068
2069        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2070            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2071
2072        mConfiguration.setToDefaults();
2073        mConfiguration.setLocale(Locale.getDefault());
2074
2075        mConfigurationSeq = mConfiguration.seq = 1;
2076        mProcessCpuTracker.init();
2077
2078        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2079        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2080        mStackSupervisor = new ActivityStackSupervisor(this);
2081        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2082
2083        mProcessCpuThread = new Thread("CpuTracker") {
2084            @Override
2085            public void run() {
2086                while (true) {
2087                    try {
2088                        try {
2089                            synchronized(this) {
2090                                final long now = SystemClock.uptimeMillis();
2091                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2092                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2093                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2094                                //        + ", write delay=" + nextWriteDelay);
2095                                if (nextWriteDelay < nextCpuDelay) {
2096                                    nextCpuDelay = nextWriteDelay;
2097                                }
2098                                if (nextCpuDelay > 0) {
2099                                    mProcessCpuMutexFree.set(true);
2100                                    this.wait(nextCpuDelay);
2101                                }
2102                            }
2103                        } catch (InterruptedException e) {
2104                        }
2105                        updateCpuStatsNow();
2106                    } catch (Exception e) {
2107                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2108                    }
2109                }
2110            }
2111        };
2112
2113        Watchdog.getInstance().addMonitor(this);
2114        Watchdog.getInstance().addThread(mHandler);
2115    }
2116
2117    public void setSystemServiceManager(SystemServiceManager mgr) {
2118        mSystemServiceManager = mgr;
2119    }
2120
2121    public void setInstaller(Installer installer) {
2122        mInstaller = installer;
2123    }
2124
2125    private void start() {
2126        Process.removeAllProcessGroups();
2127        mProcessCpuThread.start();
2128
2129        mBatteryStatsService.publish(mContext);
2130        mAppOpsService.publish(mContext);
2131        Slog.d("AppOps", "AppOpsService published");
2132        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2133    }
2134
2135    public void initPowerManagement() {
2136        mStackSupervisor.initPowerManagement();
2137        mBatteryStatsService.initPowerManagement();
2138    }
2139
2140    @Override
2141    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2142            throws RemoteException {
2143        if (code == SYSPROPS_TRANSACTION) {
2144            // We need to tell all apps about the system property change.
2145            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2146            synchronized(this) {
2147                final int NP = mProcessNames.getMap().size();
2148                for (int ip=0; ip<NP; ip++) {
2149                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2150                    final int NA = apps.size();
2151                    for (int ia=0; ia<NA; ia++) {
2152                        ProcessRecord app = apps.valueAt(ia);
2153                        if (app.thread != null) {
2154                            procs.add(app.thread.asBinder());
2155                        }
2156                    }
2157                }
2158            }
2159
2160            int N = procs.size();
2161            for (int i=0; i<N; i++) {
2162                Parcel data2 = Parcel.obtain();
2163                try {
2164                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2165                } catch (RemoteException e) {
2166                }
2167                data2.recycle();
2168            }
2169        }
2170        try {
2171            return super.onTransact(code, data, reply, flags);
2172        } catch (RuntimeException e) {
2173            // The activity manager only throws security exceptions, so let's
2174            // log all others.
2175            if (!(e instanceof SecurityException)) {
2176                Slog.wtf(TAG, "Activity Manager Crash", e);
2177            }
2178            throw e;
2179        }
2180    }
2181
2182    void updateCpuStats() {
2183        final long now = SystemClock.uptimeMillis();
2184        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2185            return;
2186        }
2187        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2188            synchronized (mProcessCpuThread) {
2189                mProcessCpuThread.notify();
2190            }
2191        }
2192    }
2193
2194    void updateCpuStatsNow() {
2195        synchronized (mProcessCpuTracker) {
2196            mProcessCpuMutexFree.set(false);
2197            final long now = SystemClock.uptimeMillis();
2198            boolean haveNewCpuStats = false;
2199
2200            if (MONITOR_CPU_USAGE &&
2201                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2202                mLastCpuTime.set(now);
2203                haveNewCpuStats = true;
2204                mProcessCpuTracker.update();
2205                //Slog.i(TAG, mProcessCpu.printCurrentState());
2206                //Slog.i(TAG, "Total CPU usage: "
2207                //        + mProcessCpu.getTotalCpuPercent() + "%");
2208
2209                // Slog the cpu usage if the property is set.
2210                if ("true".equals(SystemProperties.get("events.cpu"))) {
2211                    int user = mProcessCpuTracker.getLastUserTime();
2212                    int system = mProcessCpuTracker.getLastSystemTime();
2213                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2214                    int irq = mProcessCpuTracker.getLastIrqTime();
2215                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2216                    int idle = mProcessCpuTracker.getLastIdleTime();
2217
2218                    int total = user + system + iowait + irq + softIrq + idle;
2219                    if (total == 0) total = 1;
2220
2221                    EventLog.writeEvent(EventLogTags.CPU,
2222                            ((user+system+iowait+irq+softIrq) * 100) / total,
2223                            (user * 100) / total,
2224                            (system * 100) / total,
2225                            (iowait * 100) / total,
2226                            (irq * 100) / total,
2227                            (softIrq * 100) / total);
2228                }
2229            }
2230
2231            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2232            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2233            synchronized(bstats) {
2234                synchronized(mPidsSelfLocked) {
2235                    if (haveNewCpuStats) {
2236                        if (mOnBattery) {
2237                            int perc = bstats.startAddingCpuLocked();
2238                            int totalUTime = 0;
2239                            int totalSTime = 0;
2240                            final int N = mProcessCpuTracker.countStats();
2241                            for (int i=0; i<N; i++) {
2242                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2243                                if (!st.working) {
2244                                    continue;
2245                                }
2246                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2247                                int otherUTime = (st.rel_utime*perc)/100;
2248                                int otherSTime = (st.rel_stime*perc)/100;
2249                                totalUTime += otherUTime;
2250                                totalSTime += otherSTime;
2251                                if (pr != null) {
2252                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2253                                    if (ps == null || !ps.isActive()) {
2254                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2255                                                pr.info.uid, pr.processName);
2256                                    }
2257                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2258                                            st.rel_stime-otherSTime);
2259                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2260                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2261                                } else {
2262                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2263                                    if (ps == null || !ps.isActive()) {
2264                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2265                                                bstats.mapUid(st.uid), st.name);
2266                                    }
2267                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2268                                            st.rel_stime-otherSTime);
2269                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2270                                }
2271                            }
2272                            bstats.finishAddingCpuLocked(perc, totalUTime,
2273                                    totalSTime, cpuSpeedTimes);
2274                        }
2275                    }
2276                }
2277
2278                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2279                    mLastWriteTime = now;
2280                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2281                }
2282            }
2283        }
2284    }
2285
2286    @Override
2287    public void batteryNeedsCpuUpdate() {
2288        updateCpuStatsNow();
2289    }
2290
2291    @Override
2292    public void batteryPowerChanged(boolean onBattery) {
2293        // When plugging in, update the CPU stats first before changing
2294        // the plug state.
2295        updateCpuStatsNow();
2296        synchronized (this) {
2297            synchronized(mPidsSelfLocked) {
2298                mOnBattery = DEBUG_POWER ? true : onBattery;
2299            }
2300        }
2301    }
2302
2303    /**
2304     * Initialize the application bind args. These are passed to each
2305     * process when the bindApplication() IPC is sent to the process. They're
2306     * lazily setup to make sure the services are running when they're asked for.
2307     */
2308    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2309        if (mAppBindArgs == null) {
2310            mAppBindArgs = new HashMap<>();
2311
2312            // Isolated processes won't get this optimization, so that we don't
2313            // violate the rules about which services they have access to.
2314            if (!isolated) {
2315                // Setup the application init args
2316                mAppBindArgs.put("package", ServiceManager.getService("package"));
2317                mAppBindArgs.put("window", ServiceManager.getService("window"));
2318                mAppBindArgs.put(Context.ALARM_SERVICE,
2319                        ServiceManager.getService(Context.ALARM_SERVICE));
2320            }
2321        }
2322        return mAppBindArgs;
2323    }
2324
2325    final void setFocusedActivityLocked(ActivityRecord r) {
2326        if (mFocusedActivity != r) {
2327            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2328            mFocusedActivity = r;
2329            if (r.task != null && r.task.voiceInteractor != null) {
2330                startRunningVoiceLocked();
2331            } else {
2332                finishRunningVoiceLocked();
2333            }
2334            mStackSupervisor.setFocusedStack(r);
2335            if (r != null) {
2336                mWindowManager.setFocusedApp(r.appToken, true);
2337            }
2338            applyUpdateLockStateLocked(r);
2339        }
2340    }
2341
2342    final void clearFocusedActivity(ActivityRecord r) {
2343        if (mFocusedActivity == r) {
2344            mFocusedActivity = null;
2345        }
2346    }
2347
2348    @Override
2349    public void setFocusedStack(int stackId) {
2350        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2351        synchronized (ActivityManagerService.this) {
2352            ActivityStack stack = mStackSupervisor.getStack(stackId);
2353            if (stack != null) {
2354                ActivityRecord r = stack.topRunningActivityLocked(null);
2355                if (r != null) {
2356                    setFocusedActivityLocked(r);
2357                }
2358            }
2359        }
2360    }
2361
2362    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2363    @Override
2364    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2365        synchronized (ActivityManagerService.this) {
2366            if (listener != null) {
2367                mTaskStackListeners.register(listener);
2368            }
2369        }
2370    }
2371
2372    @Override
2373    public void notifyActivityDrawn(IBinder token) {
2374        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2375        synchronized (this) {
2376            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2377            if (r != null) {
2378                r.task.stack.notifyActivityDrawnLocked(r);
2379            }
2380        }
2381    }
2382
2383    final void applyUpdateLockStateLocked(ActivityRecord r) {
2384        // Modifications to the UpdateLock state are done on our handler, outside
2385        // the activity manager's locks.  The new state is determined based on the
2386        // state *now* of the relevant activity record.  The object is passed to
2387        // the handler solely for logging detail, not to be consulted/modified.
2388        final boolean nextState = r != null && r.immersive;
2389        mHandler.sendMessage(
2390                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2391    }
2392
2393    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2394        Message msg = Message.obtain();
2395        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2396        msg.obj = r.task.askedCompatMode ? null : r;
2397        mHandler.sendMessage(msg);
2398    }
2399
2400    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2401            String what, Object obj, ProcessRecord srcApp) {
2402        app.lastActivityTime = now;
2403
2404        if (app.activities.size() > 0) {
2405            // Don't want to touch dependent processes that are hosting activities.
2406            return index;
2407        }
2408
2409        int lrui = mLruProcesses.lastIndexOf(app);
2410        if (lrui < 0) {
2411            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2412                    + what + " " + obj + " from " + srcApp);
2413            return index;
2414        }
2415
2416        if (lrui >= index) {
2417            // Don't want to cause this to move dependent processes *back* in the
2418            // list as if they were less frequently used.
2419            return index;
2420        }
2421
2422        if (lrui >= mLruProcessActivityStart) {
2423            // Don't want to touch dependent processes that are hosting activities.
2424            return index;
2425        }
2426
2427        mLruProcesses.remove(lrui);
2428        if (index > 0) {
2429            index--;
2430        }
2431        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2432                + " in LRU list: " + app);
2433        mLruProcesses.add(index, app);
2434        return index;
2435    }
2436
2437    final void removeLruProcessLocked(ProcessRecord app) {
2438        int lrui = mLruProcesses.lastIndexOf(app);
2439        if (lrui >= 0) {
2440            if (!app.killed) {
2441                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2442                Process.killProcessQuiet(app.pid);
2443                Process.killProcessGroup(app.info.uid, app.pid);
2444            }
2445            if (lrui <= mLruProcessActivityStart) {
2446                mLruProcessActivityStart--;
2447            }
2448            if (lrui <= mLruProcessServiceStart) {
2449                mLruProcessServiceStart--;
2450            }
2451            mLruProcesses.remove(lrui);
2452        }
2453    }
2454
2455    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2456            ProcessRecord client) {
2457        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2458                || app.treatLikeActivity;
2459        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2460        if (!activityChange && hasActivity) {
2461            // The process has activities, so we are only allowing activity-based adjustments
2462            // to move it.  It should be kept in the front of the list with other
2463            // processes that have activities, and we don't want those to change their
2464            // order except due to activity operations.
2465            return;
2466        }
2467
2468        mLruSeq++;
2469        final long now = SystemClock.uptimeMillis();
2470        app.lastActivityTime = now;
2471
2472        // First a quick reject: if the app is already at the position we will
2473        // put it, then there is nothing to do.
2474        if (hasActivity) {
2475            final int N = mLruProcesses.size();
2476            if (N > 0 && mLruProcesses.get(N-1) == app) {
2477                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2478                return;
2479            }
2480        } else {
2481            if (mLruProcessServiceStart > 0
2482                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2483                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2484                return;
2485            }
2486        }
2487
2488        int lrui = mLruProcesses.lastIndexOf(app);
2489
2490        if (app.persistent && lrui >= 0) {
2491            // We don't care about the position of persistent processes, as long as
2492            // they are in the list.
2493            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2494            return;
2495        }
2496
2497        /* In progress: compute new position first, so we can avoid doing work
2498           if the process is not actually going to move.  Not yet working.
2499        int addIndex;
2500        int nextIndex;
2501        boolean inActivity = false, inService = false;
2502        if (hasActivity) {
2503            // Process has activities, put it at the very tipsy-top.
2504            addIndex = mLruProcesses.size();
2505            nextIndex = mLruProcessServiceStart;
2506            inActivity = true;
2507        } else if (hasService) {
2508            // Process has services, put it at the top of the service list.
2509            addIndex = mLruProcessActivityStart;
2510            nextIndex = mLruProcessServiceStart;
2511            inActivity = true;
2512            inService = true;
2513        } else  {
2514            // Process not otherwise of interest, it goes to the top of the non-service area.
2515            addIndex = mLruProcessServiceStart;
2516            if (client != null) {
2517                int clientIndex = mLruProcesses.lastIndexOf(client);
2518                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2519                        + app);
2520                if (clientIndex >= 0 && addIndex > clientIndex) {
2521                    addIndex = clientIndex;
2522                }
2523            }
2524            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2525        }
2526
2527        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2528                + mLruProcessActivityStart + "): " + app);
2529        */
2530
2531        if (lrui >= 0) {
2532            if (lrui < mLruProcessActivityStart) {
2533                mLruProcessActivityStart--;
2534            }
2535            if (lrui < mLruProcessServiceStart) {
2536                mLruProcessServiceStart--;
2537            }
2538            /*
2539            if (addIndex > lrui) {
2540                addIndex--;
2541            }
2542            if (nextIndex > lrui) {
2543                nextIndex--;
2544            }
2545            */
2546            mLruProcesses.remove(lrui);
2547        }
2548
2549        /*
2550        mLruProcesses.add(addIndex, app);
2551        if (inActivity) {
2552            mLruProcessActivityStart++;
2553        }
2554        if (inService) {
2555            mLruProcessActivityStart++;
2556        }
2557        */
2558
2559        int nextIndex;
2560        if (hasActivity) {
2561            final int N = mLruProcesses.size();
2562            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2563                // Process doesn't have activities, but has clients with
2564                // activities...  move it up, but one below the top (the top
2565                // should always have a real activity).
2566                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2567                mLruProcesses.add(N-1, app);
2568                // To keep it from spamming the LRU list (by making a bunch of clients),
2569                // we will push down any other entries owned by the app.
2570                final int uid = app.info.uid;
2571                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2572                    ProcessRecord subProc = mLruProcesses.get(i);
2573                    if (subProc.info.uid == uid) {
2574                        // We want to push this one down the list.  If the process after
2575                        // it is for the same uid, however, don't do so, because we don't
2576                        // want them internally to be re-ordered.
2577                        if (mLruProcesses.get(i-1).info.uid != uid) {
2578                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2579                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2580                            ProcessRecord tmp = mLruProcesses.get(i);
2581                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2582                            mLruProcesses.set(i-1, tmp);
2583                            i--;
2584                        }
2585                    } else {
2586                        // A gap, we can stop here.
2587                        break;
2588                    }
2589                }
2590            } else {
2591                // Process has activities, put it at the very tipsy-top.
2592                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2593                mLruProcesses.add(app);
2594            }
2595            nextIndex = mLruProcessServiceStart;
2596        } else if (hasService) {
2597            // Process has services, put it at the top of the service list.
2598            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2599            mLruProcesses.add(mLruProcessActivityStart, app);
2600            nextIndex = mLruProcessServiceStart;
2601            mLruProcessActivityStart++;
2602        } else  {
2603            // Process not otherwise of interest, it goes to the top of the non-service area.
2604            int index = mLruProcessServiceStart;
2605            if (client != null) {
2606                // If there is a client, don't allow the process to be moved up higher
2607                // in the list than that client.
2608                int clientIndex = mLruProcesses.lastIndexOf(client);
2609                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2610                        + " when updating " + app);
2611                if (clientIndex <= lrui) {
2612                    // Don't allow the client index restriction to push it down farther in the
2613                    // list than it already is.
2614                    clientIndex = lrui;
2615                }
2616                if (clientIndex >= 0 && index > clientIndex) {
2617                    index = clientIndex;
2618                }
2619            }
2620            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2621            mLruProcesses.add(index, app);
2622            nextIndex = index-1;
2623            mLruProcessActivityStart++;
2624            mLruProcessServiceStart++;
2625        }
2626
2627        // If the app is currently using a content provider or service,
2628        // bump those processes as well.
2629        for (int j=app.connections.size()-1; j>=0; j--) {
2630            ConnectionRecord cr = app.connections.valueAt(j);
2631            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2632                    && cr.binding.service.app != null
2633                    && cr.binding.service.app.lruSeq != mLruSeq
2634                    && !cr.binding.service.app.persistent) {
2635                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2636                        "service connection", cr, app);
2637            }
2638        }
2639        for (int j=app.conProviders.size()-1; j>=0; j--) {
2640            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2641            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2642                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2643                        "provider reference", cpr, app);
2644            }
2645        }
2646    }
2647
2648    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2649        if (uid == Process.SYSTEM_UID) {
2650            // The system gets to run in any process.  If there are multiple
2651            // processes with the same uid, just pick the first (this
2652            // should never happen).
2653            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2654            if (procs == null) return null;
2655            final int N = procs.size();
2656            for (int i = 0; i < N; i++) {
2657                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2658            }
2659        }
2660        ProcessRecord proc = mProcessNames.get(processName, uid);
2661        if (false && proc != null && !keepIfLarge
2662                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2663                && proc.lastCachedPss >= 4000) {
2664            // Turn this condition on to cause killing to happen regularly, for testing.
2665            if (proc.baseProcessTracker != null) {
2666                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2667            }
2668            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2669        } else if (proc != null && !keepIfLarge
2670                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2671                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2672            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2673            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2674                if (proc.baseProcessTracker != null) {
2675                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2676                }
2677                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2678            }
2679        }
2680        return proc;
2681    }
2682
2683    void ensurePackageDexOpt(String packageName) {
2684        IPackageManager pm = AppGlobals.getPackageManager();
2685        try {
2686            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2687                mDidDexOpt = true;
2688            }
2689        } catch (RemoteException e) {
2690        }
2691    }
2692
2693    boolean isNextTransitionForward() {
2694        int transit = mWindowManager.getPendingAppTransition();
2695        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2696                || transit == AppTransition.TRANSIT_TASK_OPEN
2697                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2698    }
2699
2700    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2701            String processName, String abiOverride, int uid, Runnable crashHandler) {
2702        synchronized(this) {
2703            ApplicationInfo info = new ApplicationInfo();
2704            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2705            // For isolated processes, the former contains the parent's uid and the latter the
2706            // actual uid of the isolated process.
2707            // In the special case introduced by this method (which is, starting an isolated
2708            // process directly from the SystemServer without an actual parent app process) the
2709            // closest thing to a parent's uid is SYSTEM_UID.
2710            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2711            // the |isolated| logic in the ProcessRecord constructor.
2712            info.uid = Process.SYSTEM_UID;
2713            info.processName = processName;
2714            info.className = entryPoint;
2715            info.packageName = "android";
2716            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2717                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2718                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2719                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2720                    crashHandler);
2721            return proc != null ? proc.pid : 0;
2722        }
2723    }
2724
2725    final ProcessRecord startProcessLocked(String processName,
2726            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2727            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2728            boolean isolated, boolean keepIfLarge) {
2729        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2730                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2731                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2732                null /* crashHandler */);
2733    }
2734
2735    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2736            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2737            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2738            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2739        long startTime = SystemClock.elapsedRealtime();
2740        ProcessRecord app;
2741        if (!isolated) {
2742            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2743            checkTime(startTime, "startProcess: after getProcessRecord");
2744        } else {
2745            // If this is an isolated process, it can't re-use an existing process.
2746            app = null;
2747        }
2748        // We don't have to do anything more if:
2749        // (1) There is an existing application record; and
2750        // (2) The caller doesn't think it is dead, OR there is no thread
2751        //     object attached to it so we know it couldn't have crashed; and
2752        // (3) There is a pid assigned to it, so it is either starting or
2753        //     already running.
2754        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2755                + " app=" + app + " knownToBeDead=" + knownToBeDead
2756                + " thread=" + (app != null ? app.thread : null)
2757                + " pid=" + (app != null ? app.pid : -1));
2758        if (app != null && app.pid > 0) {
2759            if (!knownToBeDead || app.thread == null) {
2760                // We already have the app running, or are waiting for it to
2761                // come up (we have a pid but not yet its thread), so keep it.
2762                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2763                // If this is a new package in the process, add the package to the list
2764                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2765                checkTime(startTime, "startProcess: done, added package to proc");
2766                return app;
2767            }
2768
2769            // An application record is attached to a previous process,
2770            // clean it up now.
2771            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2772            checkTime(startTime, "startProcess: bad proc running, killing");
2773            Process.killProcessGroup(app.info.uid, app.pid);
2774            handleAppDiedLocked(app, true, true);
2775            checkTime(startTime, "startProcess: done killing old proc");
2776        }
2777
2778        String hostingNameStr = hostingName != null
2779                ? hostingName.flattenToShortString() : null;
2780
2781        if (!isolated) {
2782            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2783                // If we are in the background, then check to see if this process
2784                // is bad.  If so, we will just silently fail.
2785                if (mBadProcesses.get(info.processName, info.uid) != null) {
2786                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2787                            + "/" + info.processName);
2788                    return null;
2789                }
2790            } else {
2791                // When the user is explicitly starting a process, then clear its
2792                // crash count so that we won't make it bad until they see at
2793                // least one crash dialog again, and make the process good again
2794                // if it had been bad.
2795                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2796                        + "/" + info.processName);
2797                mProcessCrashTimes.remove(info.processName, info.uid);
2798                if (mBadProcesses.get(info.processName, info.uid) != null) {
2799                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2800                            UserHandle.getUserId(info.uid), info.uid,
2801                            info.processName);
2802                    mBadProcesses.remove(info.processName, info.uid);
2803                    if (app != null) {
2804                        app.bad = false;
2805                    }
2806                }
2807            }
2808        }
2809
2810        if (app == null) {
2811            checkTime(startTime, "startProcess: creating new process record");
2812            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2813            if (app == null) {
2814                Slog.w(TAG, "Failed making new process record for "
2815                        + processName + "/" + info.uid + " isolated=" + isolated);
2816                return null;
2817            }
2818            app.crashHandler = crashHandler;
2819            mProcessNames.put(processName, app.uid, app);
2820            if (isolated) {
2821                mIsolatedProcesses.put(app.uid, app);
2822            }
2823            checkTime(startTime, "startProcess: done creating new process record");
2824        } else {
2825            // If this is a new package in the process, add the package to the list
2826            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2827            checkTime(startTime, "startProcess: added package to existing proc");
2828        }
2829
2830        // If the system is not ready yet, then hold off on starting this
2831        // process until it is.
2832        if (!mProcessesReady
2833                && !isAllowedWhileBooting(info)
2834                && !allowWhileBooting) {
2835            if (!mProcessesOnHold.contains(app)) {
2836                mProcessesOnHold.add(app);
2837            }
2838            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2839            checkTime(startTime, "startProcess: returning with proc on hold");
2840            return app;
2841        }
2842
2843        checkTime(startTime, "startProcess: stepping in to startProcess");
2844        startProcessLocked(
2845                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2846        checkTime(startTime, "startProcess: done starting proc!");
2847        return (app.pid != 0) ? app : null;
2848    }
2849
2850    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2851        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2852    }
2853
2854    private final void startProcessLocked(ProcessRecord app,
2855            String hostingType, String hostingNameStr) {
2856        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2857                null /* entryPoint */, null /* entryPointArgs */);
2858    }
2859
2860    private final void startProcessLocked(ProcessRecord app, String hostingType,
2861            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2862        long startTime = SystemClock.elapsedRealtime();
2863        if (app.pid > 0 && app.pid != MY_PID) {
2864            checkTime(startTime, "startProcess: removing from pids map");
2865            synchronized (mPidsSelfLocked) {
2866                mPidsSelfLocked.remove(app.pid);
2867                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2868            }
2869            checkTime(startTime, "startProcess: done removing from pids map");
2870            app.setPid(0);
2871        }
2872
2873        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2874                "startProcessLocked removing on hold: " + app);
2875        mProcessesOnHold.remove(app);
2876
2877        checkTime(startTime, "startProcess: starting to update cpu stats");
2878        updateCpuStats();
2879        checkTime(startTime, "startProcess: done updating cpu stats");
2880
2881        try {
2882            int uid = app.uid;
2883
2884            int[] gids = null;
2885            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2886            if (!app.isolated) {
2887                int[] permGids = null;
2888                try {
2889                    checkTime(startTime, "startProcess: getting gids from package manager");
2890                    final PackageManager pm = mContext.getPackageManager();
2891                    permGids = pm.getPackageGids(app.info.packageName);
2892
2893                    if (Environment.isExternalStorageEmulated()) {
2894                        checkTime(startTime, "startProcess: checking external storage perm");
2895                        if (pm.checkPermission(
2896                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2897                                app.info.packageName) == PERMISSION_GRANTED) {
2898                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2899                        } else {
2900                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2901                        }
2902                    }
2903                } catch (PackageManager.NameNotFoundException e) {
2904                    Slog.w(TAG, "Unable to retrieve gids", e);
2905                }
2906
2907                /*
2908                 * Add shared application and profile GIDs so applications can share some
2909                 * resources like shared libraries and access user-wide resources
2910                 */
2911                if (permGids == null) {
2912                    gids = new int[2];
2913                } else {
2914                    gids = new int[permGids.length + 2];
2915                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2916                }
2917                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2918                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2919            }
2920            checkTime(startTime, "startProcess: building args");
2921            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2922                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2923                        && mTopComponent != null
2924                        && app.processName.equals(mTopComponent.getPackageName())) {
2925                    uid = 0;
2926                }
2927                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2928                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2929                    uid = 0;
2930                }
2931            }
2932            int debugFlags = 0;
2933            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2934                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2935                // Also turn on CheckJNI for debuggable apps. It's quite
2936                // awkward to turn on otherwise.
2937                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2938            }
2939            // Run the app in safe mode if its manifest requests so or the
2940            // system is booted in safe mode.
2941            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2942                mSafeMode == true) {
2943                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2944            }
2945            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2946                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2947            }
2948            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2949                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2950            }
2951            if ("1".equals(SystemProperties.get("debug.assert"))) {
2952                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2953            }
2954
2955            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2956            if (requiredAbi == null) {
2957                requiredAbi = Build.SUPPORTED_ABIS[0];
2958            }
2959
2960            String instructionSet = null;
2961            if (app.info.primaryCpuAbi != null) {
2962                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2963            }
2964
2965            // Start the process.  It will either succeed and return a result containing
2966            // the PID of the new process, or else throw a RuntimeException.
2967            boolean isActivityProcess = (entryPoint == null);
2968            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2969            checkTime(startTime, "startProcess: asking zygote to start proc");
2970            Process.ProcessStartResult startResult = Process.start(entryPoint,
2971                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2972                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2973                    app.info.dataDir, entryPointArgs);
2974            checkTime(startTime, "startProcess: returned from zygote!");
2975
2976            if (app.isolated) {
2977                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2978            }
2979            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2980            checkTime(startTime, "startProcess: done updating battery stats");
2981
2982            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2983                    UserHandle.getUserId(uid), startResult.pid, uid,
2984                    app.processName, hostingType,
2985                    hostingNameStr != null ? hostingNameStr : "");
2986
2987            if (app.persistent) {
2988                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2989            }
2990
2991            checkTime(startTime, "startProcess: building log message");
2992            StringBuilder buf = mStringBuilder;
2993            buf.setLength(0);
2994            buf.append("Start proc ");
2995            buf.append(app.processName);
2996            if (!isActivityProcess) {
2997                buf.append(" [");
2998                buf.append(entryPoint);
2999                buf.append("]");
3000            }
3001            buf.append(" for ");
3002            buf.append(hostingType);
3003            if (hostingNameStr != null) {
3004                buf.append(" ");
3005                buf.append(hostingNameStr);
3006            }
3007            buf.append(": pid=");
3008            buf.append(startResult.pid);
3009            buf.append(" uid=");
3010            buf.append(uid);
3011            buf.append(" gids={");
3012            if (gids != null) {
3013                for (int gi=0; gi<gids.length; gi++) {
3014                    if (gi != 0) buf.append(", ");
3015                    buf.append(gids[gi]);
3016
3017                }
3018            }
3019            buf.append("}");
3020            if (requiredAbi != null) {
3021                buf.append(" abi=");
3022                buf.append(requiredAbi);
3023            }
3024            Slog.i(TAG, buf.toString());
3025            app.setPid(startResult.pid);
3026            app.usingWrapper = startResult.usingWrapper;
3027            app.removed = false;
3028            app.killed = false;
3029            app.killedByAm = false;
3030            checkTime(startTime, "startProcess: starting to update pids map");
3031            synchronized (mPidsSelfLocked) {
3032                this.mPidsSelfLocked.put(startResult.pid, app);
3033                if (isActivityProcess) {
3034                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3035                    msg.obj = app;
3036                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3037                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3038                }
3039            }
3040            checkTime(startTime, "startProcess: done updating pids map");
3041        } catch (RuntimeException e) {
3042            // XXX do better error recovery.
3043            app.setPid(0);
3044            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3045            if (app.isolated) {
3046                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3047            }
3048            Slog.e(TAG, "Failure starting process " + app.processName, e);
3049        }
3050    }
3051
3052    void updateUsageStats(ActivityRecord component, boolean resumed) {
3053        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3054        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3055        if (resumed) {
3056            if (mUsageStatsService != null) {
3057                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3058                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3059            }
3060            synchronized (stats) {
3061                stats.noteActivityResumedLocked(component.app.uid);
3062            }
3063        } else {
3064            if (mUsageStatsService != null) {
3065                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3066                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3067            }
3068            synchronized (stats) {
3069                stats.noteActivityPausedLocked(component.app.uid);
3070            }
3071        }
3072    }
3073
3074    Intent getHomeIntent() {
3075        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3076        intent.setComponent(mTopComponent);
3077        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3078            intent.addCategory(Intent.CATEGORY_HOME);
3079        }
3080        return intent;
3081    }
3082
3083    boolean startHomeActivityLocked(int userId) {
3084        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3085                && mTopAction == null) {
3086            // We are running in factory test mode, but unable to find
3087            // the factory test app, so just sit around displaying the
3088            // error message and don't try to start anything.
3089            return false;
3090        }
3091        Intent intent = getHomeIntent();
3092        ActivityInfo aInfo =
3093            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3094        if (aInfo != null) {
3095            intent.setComponent(new ComponentName(
3096                    aInfo.applicationInfo.packageName, aInfo.name));
3097            // Don't do this if the home app is currently being
3098            // instrumented.
3099            aInfo = new ActivityInfo(aInfo);
3100            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3101            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3102                    aInfo.applicationInfo.uid, true);
3103            if (app == null || app.instrumentationClass == null) {
3104                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3105                mStackSupervisor.startHomeActivity(intent, aInfo);
3106            }
3107        }
3108
3109        return true;
3110    }
3111
3112    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3113        ActivityInfo ai = null;
3114        ComponentName comp = intent.getComponent();
3115        try {
3116            if (comp != null) {
3117                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3118            } else {
3119                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3120                        intent,
3121                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3122                            flags, userId);
3123
3124                if (info != null) {
3125                    ai = info.activityInfo;
3126                }
3127            }
3128        } catch (RemoteException e) {
3129            // ignore
3130        }
3131
3132        return ai;
3133    }
3134
3135    /**
3136     * Starts the "new version setup screen" if appropriate.
3137     */
3138    void startSetupActivityLocked() {
3139        // Only do this once per boot.
3140        if (mCheckedForSetup) {
3141            return;
3142        }
3143
3144        // We will show this screen if the current one is a different
3145        // version than the last one shown, and we are not running in
3146        // low-level factory test mode.
3147        final ContentResolver resolver = mContext.getContentResolver();
3148        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3149                Settings.Global.getInt(resolver,
3150                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3151            mCheckedForSetup = true;
3152
3153            // See if we should be showing the platform update setup UI.
3154            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3155            List<ResolveInfo> ris = mContext.getPackageManager()
3156                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3157
3158            // We don't allow third party apps to replace this.
3159            ResolveInfo ri = null;
3160            for (int i=0; ris != null && i<ris.size(); i++) {
3161                if ((ris.get(i).activityInfo.applicationInfo.flags
3162                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3163                    ri = ris.get(i);
3164                    break;
3165                }
3166            }
3167
3168            if (ri != null) {
3169                String vers = ri.activityInfo.metaData != null
3170                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3171                        : null;
3172                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3173                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3174                            Intent.METADATA_SETUP_VERSION);
3175                }
3176                String lastVers = Settings.Secure.getString(
3177                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3178                if (vers != null && !vers.equals(lastVers)) {
3179                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3180                    intent.setComponent(new ComponentName(
3181                            ri.activityInfo.packageName, ri.activityInfo.name));
3182                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3183                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3184                            null);
3185                }
3186            }
3187        }
3188    }
3189
3190    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3191        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3192    }
3193
3194    void enforceNotIsolatedCaller(String caller) {
3195        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3196            throw new SecurityException("Isolated process not allowed to call " + caller);
3197        }
3198    }
3199
3200    void enforceShellRestriction(String restriction, int userHandle) {
3201        if (Binder.getCallingUid() == Process.SHELL_UID) {
3202            if (userHandle < 0
3203                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3204                throw new SecurityException("Shell does not have permission to access user "
3205                        + userHandle);
3206            }
3207        }
3208    }
3209
3210    @Override
3211    public int getFrontActivityScreenCompatMode() {
3212        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3213        synchronized (this) {
3214            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3215        }
3216    }
3217
3218    @Override
3219    public void setFrontActivityScreenCompatMode(int mode) {
3220        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3221                "setFrontActivityScreenCompatMode");
3222        synchronized (this) {
3223            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3224        }
3225    }
3226
3227    @Override
3228    public int getPackageScreenCompatMode(String packageName) {
3229        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3230        synchronized (this) {
3231            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3232        }
3233    }
3234
3235    @Override
3236    public void setPackageScreenCompatMode(String packageName, int mode) {
3237        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3238                "setPackageScreenCompatMode");
3239        synchronized (this) {
3240            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3241        }
3242    }
3243
3244    @Override
3245    public boolean getPackageAskScreenCompat(String packageName) {
3246        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3247        synchronized (this) {
3248            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3249        }
3250    }
3251
3252    @Override
3253    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3254        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3255                "setPackageAskScreenCompat");
3256        synchronized (this) {
3257            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3258        }
3259    }
3260
3261    private void dispatchProcessesChanged() {
3262        int N;
3263        synchronized (this) {
3264            N = mPendingProcessChanges.size();
3265            if (mActiveProcessChanges.length < N) {
3266                mActiveProcessChanges = new ProcessChangeItem[N];
3267            }
3268            mPendingProcessChanges.toArray(mActiveProcessChanges);
3269            mAvailProcessChanges.addAll(mPendingProcessChanges);
3270            mPendingProcessChanges.clear();
3271            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3272        }
3273
3274        int i = mProcessObservers.beginBroadcast();
3275        while (i > 0) {
3276            i--;
3277            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3278            if (observer != null) {
3279                try {
3280                    for (int j=0; j<N; j++) {
3281                        ProcessChangeItem item = mActiveProcessChanges[j];
3282                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3283                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3284                                    + item.pid + " uid=" + item.uid + ": "
3285                                    + item.foregroundActivities);
3286                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3287                                    item.foregroundActivities);
3288                        }
3289                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3290                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3291                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3292                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3293                        }
3294                    }
3295                } catch (RemoteException e) {
3296                }
3297            }
3298        }
3299        mProcessObservers.finishBroadcast();
3300    }
3301
3302    private void dispatchProcessDied(int pid, int uid) {
3303        int i = mProcessObservers.beginBroadcast();
3304        while (i > 0) {
3305            i--;
3306            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3307            if (observer != null) {
3308                try {
3309                    observer.onProcessDied(pid, uid);
3310                } catch (RemoteException e) {
3311                }
3312            }
3313        }
3314        mProcessObservers.finishBroadcast();
3315    }
3316
3317    @Override
3318    public final int startActivity(IApplicationThread caller, String callingPackage,
3319            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3320            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3321        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3322            resultWho, requestCode, startFlags, profilerInfo, options,
3323            UserHandle.getCallingUserId());
3324    }
3325
3326    @Override
3327    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3328            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3329            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3330        enforceNotIsolatedCaller("startActivity");
3331        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3332                false, ALLOW_FULL_ONLY, "startActivity", null);
3333        // TODO: Switch to user app stacks here.
3334        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3335                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3336                profilerInfo, null, null, options, userId, null, null);
3337    }
3338
3339    @Override
3340    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3341            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3342            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3343
3344        // This is very dangerous -- it allows you to perform a start activity (including
3345        // permission grants) as any app that may launch one of your own activities.  So
3346        // we will only allow this to be done from activities that are part of the core framework,
3347        // and then only when they are running as the system.
3348        final ActivityRecord sourceRecord;
3349        final int targetUid;
3350        final String targetPackage;
3351        synchronized (this) {
3352            if (resultTo == null) {
3353                throw new SecurityException("Must be called from an activity");
3354            }
3355            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3356            if (sourceRecord == null) {
3357                throw new SecurityException("Called with bad activity token: " + resultTo);
3358            }
3359            if (!sourceRecord.info.packageName.equals("android")) {
3360                throw new SecurityException(
3361                        "Must be called from an activity that is declared in the android package");
3362            }
3363            if (sourceRecord.app == null) {
3364                throw new SecurityException("Called without a process attached to activity");
3365            }
3366            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3367                // This is still okay, as long as this activity is running under the
3368                // uid of the original calling activity.
3369                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3370                    throw new SecurityException(
3371                            "Calling activity in uid " + sourceRecord.app.uid
3372                                    + " must be system uid or original calling uid "
3373                                    + sourceRecord.launchedFromUid);
3374                }
3375            }
3376            targetUid = sourceRecord.launchedFromUid;
3377            targetPackage = sourceRecord.launchedFromPackage;
3378        }
3379
3380        if (userId == UserHandle.USER_NULL) {
3381            userId = UserHandle.getUserId(sourceRecord.app.uid);
3382        }
3383
3384        // TODO: Switch to user app stacks here.
3385        try {
3386            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3387                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3388                    null, null, options, userId, null, null);
3389            return ret;
3390        } catch (SecurityException e) {
3391            // XXX need to figure out how to propagate to original app.
3392            // A SecurityException here is generally actually a fault of the original
3393            // calling activity (such as a fairly granting permissions), so propagate it
3394            // back to them.
3395            /*
3396            StringBuilder msg = new StringBuilder();
3397            msg.append("While launching");
3398            msg.append(intent.toString());
3399            msg.append(": ");
3400            msg.append(e.getMessage());
3401            */
3402            throw e;
3403        }
3404    }
3405
3406    @Override
3407    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3408            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3409            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3410        enforceNotIsolatedCaller("startActivityAndWait");
3411        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3412                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3413        WaitResult res = new WaitResult();
3414        // TODO: Switch to user app stacks here.
3415        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3416                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3417                options, userId, null, null);
3418        return res;
3419    }
3420
3421    @Override
3422    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3423            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3424            int startFlags, Configuration config, Bundle options, int userId) {
3425        enforceNotIsolatedCaller("startActivityWithConfig");
3426        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3427                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3428        // TODO: Switch to user app stacks here.
3429        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3430                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3431                null, null, config, options, userId, null, null);
3432        return ret;
3433    }
3434
3435    @Override
3436    public int startActivityIntentSender(IApplicationThread caller,
3437            IntentSender intent, Intent fillInIntent, String resolvedType,
3438            IBinder resultTo, String resultWho, int requestCode,
3439            int flagsMask, int flagsValues, Bundle options) {
3440        enforceNotIsolatedCaller("startActivityIntentSender");
3441        // Refuse possible leaked file descriptors
3442        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3443            throw new IllegalArgumentException("File descriptors passed in Intent");
3444        }
3445
3446        IIntentSender sender = intent.getTarget();
3447        if (!(sender instanceof PendingIntentRecord)) {
3448            throw new IllegalArgumentException("Bad PendingIntent object");
3449        }
3450
3451        PendingIntentRecord pir = (PendingIntentRecord)sender;
3452
3453        synchronized (this) {
3454            // If this is coming from the currently resumed activity, it is
3455            // effectively saying that app switches are allowed at this point.
3456            final ActivityStack stack = getFocusedStack();
3457            if (stack.mResumedActivity != null &&
3458                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3459                mAppSwitchesAllowedTime = 0;
3460            }
3461        }
3462        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3463                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3469            Intent intent, String resolvedType, IVoiceInteractionSession session,
3470            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3471            Bundle options, int userId) {
3472        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3473                != PackageManager.PERMISSION_GRANTED) {
3474            String msg = "Permission Denial: startVoiceActivity() from pid="
3475                    + Binder.getCallingPid()
3476                    + ", uid=" + Binder.getCallingUid()
3477                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3478            Slog.w(TAG, msg);
3479            throw new SecurityException(msg);
3480        }
3481        if (session == null || interactor == null) {
3482            throw new NullPointerException("null session or interactor");
3483        }
3484        userId = handleIncomingUser(callingPid, callingUid, userId,
3485                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3486        // TODO: Switch to user app stacks here.
3487        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3488                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3489                null, options, userId, null, null);
3490    }
3491
3492    @Override
3493    public boolean startNextMatchingActivity(IBinder callingActivity,
3494            Intent intent, Bundle options) {
3495        // Refuse possible leaked file descriptors
3496        if (intent != null && intent.hasFileDescriptors() == true) {
3497            throw new IllegalArgumentException("File descriptors passed in Intent");
3498        }
3499
3500        synchronized (this) {
3501            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3502            if (r == null) {
3503                ActivityOptions.abort(options);
3504                return false;
3505            }
3506            if (r.app == null || r.app.thread == null) {
3507                // The caller is not running...  d'oh!
3508                ActivityOptions.abort(options);
3509                return false;
3510            }
3511            intent = new Intent(intent);
3512            // The caller is not allowed to change the data.
3513            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3514            // And we are resetting to find the next component...
3515            intent.setComponent(null);
3516
3517            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3518
3519            ActivityInfo aInfo = null;
3520            try {
3521                List<ResolveInfo> resolves =
3522                    AppGlobals.getPackageManager().queryIntentActivities(
3523                            intent, r.resolvedType,
3524                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3525                            UserHandle.getCallingUserId());
3526
3527                // Look for the original activity in the list...
3528                final int N = resolves != null ? resolves.size() : 0;
3529                for (int i=0; i<N; i++) {
3530                    ResolveInfo rInfo = resolves.get(i);
3531                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3532                            && rInfo.activityInfo.name.equals(r.info.name)) {
3533                        // We found the current one...  the next matching is
3534                        // after it.
3535                        i++;
3536                        if (i<N) {
3537                            aInfo = resolves.get(i).activityInfo;
3538                        }
3539                        if (debug) {
3540                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3541                                    + "/" + r.info.name);
3542                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3543                                    + "/" + aInfo.name);
3544                        }
3545                        break;
3546                    }
3547                }
3548            } catch (RemoteException e) {
3549            }
3550
3551            if (aInfo == null) {
3552                // Nobody who is next!
3553                ActivityOptions.abort(options);
3554                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3555                return false;
3556            }
3557
3558            intent.setComponent(new ComponentName(
3559                    aInfo.applicationInfo.packageName, aInfo.name));
3560            intent.setFlags(intent.getFlags()&~(
3561                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3562                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3563                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3564                    Intent.FLAG_ACTIVITY_NEW_TASK));
3565
3566            // Okay now we need to start the new activity, replacing the
3567            // currently running activity.  This is a little tricky because
3568            // we want to start the new one as if the current one is finished,
3569            // but not finish the current one first so that there is no flicker.
3570            // And thus...
3571            final boolean wasFinishing = r.finishing;
3572            r.finishing = true;
3573
3574            // Propagate reply information over to the new activity.
3575            final ActivityRecord resultTo = r.resultTo;
3576            final String resultWho = r.resultWho;
3577            final int requestCode = r.requestCode;
3578            r.resultTo = null;
3579            if (resultTo != null) {
3580                resultTo.removeResultsLocked(r, resultWho, requestCode);
3581            }
3582
3583            final long origId = Binder.clearCallingIdentity();
3584            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3585                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3586                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3587                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3588            Binder.restoreCallingIdentity(origId);
3589
3590            r.finishing = wasFinishing;
3591            if (res != ActivityManager.START_SUCCESS) {
3592                return false;
3593            }
3594            return true;
3595        }
3596    }
3597
3598    @Override
3599    public final int startActivityFromRecents(int taskId, Bundle options) {
3600        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3601            String msg = "Permission Denial: startActivityFromRecents called without " +
3602                    START_TASKS_FROM_RECENTS;
3603            Slog.w(TAG, msg);
3604            throw new SecurityException(msg);
3605        }
3606        return startActivityFromRecentsInner(taskId, options);
3607    }
3608
3609    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3610        final TaskRecord task;
3611        final int callingUid;
3612        final String callingPackage;
3613        final Intent intent;
3614        final int userId;
3615        synchronized (this) {
3616            task = recentTaskForIdLocked(taskId);
3617            if (task == null) {
3618                throw new IllegalArgumentException("Task " + taskId + " not found.");
3619            }
3620            callingUid = task.mCallingUid;
3621            callingPackage = task.mCallingPackage;
3622            intent = task.intent;
3623            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3624            userId = task.userId;
3625        }
3626        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3627                options, userId, null, task);
3628    }
3629
3630    final int startActivityInPackage(int uid, String callingPackage,
3631            Intent intent, String resolvedType, IBinder resultTo,
3632            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3633            IActivityContainer container, TaskRecord inTask) {
3634
3635        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3636                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3637
3638        // TODO: Switch to user app stacks here.
3639        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3640                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3641                null, null, null, options, userId, container, inTask);
3642        return ret;
3643    }
3644
3645    @Override
3646    public final int startActivities(IApplicationThread caller, String callingPackage,
3647            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3648            int userId) {
3649        enforceNotIsolatedCaller("startActivities");
3650        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3651                false, ALLOW_FULL_ONLY, "startActivity", null);
3652        // TODO: Switch to user app stacks here.
3653        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3654                resolvedTypes, resultTo, options, userId);
3655        return ret;
3656    }
3657
3658    final int startActivitiesInPackage(int uid, String callingPackage,
3659            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3660            Bundle options, int userId) {
3661
3662        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3663                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3664        // TODO: Switch to user app stacks here.
3665        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3666                resultTo, options, userId);
3667        return ret;
3668    }
3669
3670    //explicitly remove thd old information in mRecentTasks when removing existing user.
3671    private void removeRecentTasksForUserLocked(int userId) {
3672        if(userId <= 0) {
3673            Slog.i(TAG, "Can't remove recent task on user " + userId);
3674            return;
3675        }
3676
3677        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3678            TaskRecord tr = mRecentTasks.get(i);
3679            if (tr.userId == userId) {
3680                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3681                        + " when finishing user" + userId);
3682                mRecentTasks.remove(i);
3683                tr.removedFromRecents();
3684            }
3685        }
3686
3687        // Remove tasks from persistent storage.
3688        notifyTaskPersisterLocked(null, true);
3689    }
3690
3691    // Sort by taskId
3692    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3693        @Override
3694        public int compare(TaskRecord lhs, TaskRecord rhs) {
3695            return rhs.taskId - lhs.taskId;
3696        }
3697    };
3698
3699    // Extract the affiliates of the chain containing mRecentTasks[start].
3700    private int processNextAffiliateChainLocked(int start) {
3701        final TaskRecord startTask = mRecentTasks.get(start);
3702        final int affiliateId = startTask.mAffiliatedTaskId;
3703
3704        // Quick identification of isolated tasks. I.e. those not launched behind.
3705        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3706                startTask.mNextAffiliate == null) {
3707            // There is still a slim chance that there are other tasks that point to this task
3708            // and that the chain is so messed up that this task no longer points to them but
3709            // the gain of this optimization outweighs the risk.
3710            startTask.inRecents = true;
3711            return start + 1;
3712        }
3713
3714        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3715        mTmpRecents.clear();
3716        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3717            final TaskRecord task = mRecentTasks.get(i);
3718            if (task.mAffiliatedTaskId == affiliateId) {
3719                mRecentTasks.remove(i);
3720                mTmpRecents.add(task);
3721            }
3722        }
3723
3724        // Sort them all by taskId. That is the order they were create in and that order will
3725        // always be correct.
3726        Collections.sort(mTmpRecents, mTaskRecordComparator);
3727
3728        // Go through and fix up the linked list.
3729        // The first one is the end of the chain and has no next.
3730        final TaskRecord first = mTmpRecents.get(0);
3731        first.inRecents = true;
3732        if (first.mNextAffiliate != null) {
3733            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3734            first.setNextAffiliate(null);
3735            notifyTaskPersisterLocked(first, false);
3736        }
3737        // Everything in the middle is doubly linked from next to prev.
3738        final int tmpSize = mTmpRecents.size();
3739        for (int i = 0; i < tmpSize - 1; ++i) {
3740            final TaskRecord next = mTmpRecents.get(i);
3741            final TaskRecord prev = mTmpRecents.get(i + 1);
3742            if (next.mPrevAffiliate != prev) {
3743                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3744                        " setting prev=" + prev);
3745                next.setPrevAffiliate(prev);
3746                notifyTaskPersisterLocked(next, false);
3747            }
3748            if (prev.mNextAffiliate != next) {
3749                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3750                        " setting next=" + next);
3751                prev.setNextAffiliate(next);
3752                notifyTaskPersisterLocked(prev, false);
3753            }
3754            prev.inRecents = true;
3755        }
3756        // The last one is the beginning of the list and has no prev.
3757        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3758        if (last.mPrevAffiliate != null) {
3759            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3760            last.setPrevAffiliate(null);
3761            notifyTaskPersisterLocked(last, false);
3762        }
3763
3764        // Insert the group back into mRecentTasks at start.
3765        mRecentTasks.addAll(start, mTmpRecents);
3766
3767        // Let the caller know where we left off.
3768        return start + tmpSize;
3769    }
3770
3771    /**
3772     * Update the recent tasks lists: make sure tasks should still be here (their
3773     * applications / activities still exist), update their availability, fixup ordering
3774     * of affiliations.
3775     */
3776    void cleanupRecentTasksLocked(int userId) {
3777        if (mRecentTasks == null) {
3778            // Happens when called from the packagemanager broadcast before boot.
3779            return;
3780        }
3781
3782        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3783        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3784        final IPackageManager pm = AppGlobals.getPackageManager();
3785        final ActivityInfo dummyAct = new ActivityInfo();
3786        final ApplicationInfo dummyApp = new ApplicationInfo();
3787
3788        int N = mRecentTasks.size();
3789
3790        int[] users = userId == UserHandle.USER_ALL
3791                ? getUsersLocked() : new int[] { userId };
3792        for (int user : users) {
3793            for (int i = 0; i < N; i++) {
3794                TaskRecord task = mRecentTasks.get(i);
3795                if (task.userId != user) {
3796                    // Only look at tasks for the user ID of interest.
3797                    continue;
3798                }
3799                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3800                    // This situation is broken, and we should just get rid of it now.
3801                    mRecentTasks.remove(i);
3802                    task.removedFromRecents();
3803                    i--;
3804                    N--;
3805                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3806                    continue;
3807                }
3808                // Check whether this activity is currently available.
3809                if (task.realActivity != null) {
3810                    ActivityInfo ai = availActCache.get(task.realActivity);
3811                    if (ai == null) {
3812                        try {
3813                            ai = pm.getActivityInfo(task.realActivity,
3814                                    PackageManager.GET_UNINSTALLED_PACKAGES
3815                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3816                        } catch (RemoteException e) {
3817                            // Will never happen.
3818                            continue;
3819                        }
3820                        if (ai == null) {
3821                            ai = dummyAct;
3822                        }
3823                        availActCache.put(task.realActivity, ai);
3824                    }
3825                    if (ai == dummyAct) {
3826                        // This could be either because the activity no longer exists, or the
3827                        // app is temporarily gone.  For the former we want to remove the recents
3828                        // entry; for the latter we want to mark it as unavailable.
3829                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3830                        if (app == null) {
3831                            try {
3832                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3833                                        PackageManager.GET_UNINSTALLED_PACKAGES
3834                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3835                            } catch (RemoteException e) {
3836                                // Will never happen.
3837                                continue;
3838                            }
3839                            if (app == null) {
3840                                app = dummyApp;
3841                            }
3842                            availAppCache.put(task.realActivity.getPackageName(), app);
3843                        }
3844                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3845                            // Doesn't exist any more!  Good-bye.
3846                            mRecentTasks.remove(i);
3847                            task.removedFromRecents();
3848                            i--;
3849                            N--;
3850                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3851                            continue;
3852                        } else {
3853                            // Otherwise just not available for now.
3854                            if (task.isAvailable) {
3855                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3856                                        + task);
3857                            }
3858                            task.isAvailable = false;
3859                        }
3860                    } else {
3861                        if (!ai.enabled || !ai.applicationInfo.enabled
3862                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3863                            if (task.isAvailable) {
3864                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3865                                        + task + " (enabled=" + ai.enabled + "/"
3866                                        + ai.applicationInfo.enabled +  " flags="
3867                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3868                            }
3869                            task.isAvailable = false;
3870                        } else {
3871                            if (!task.isAvailable) {
3872                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3873                                        + task);
3874                            }
3875                            task.isAvailable = true;
3876                        }
3877                    }
3878                }
3879            }
3880        }
3881
3882        // Verify the affiliate chain for each task.
3883        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3884        }
3885
3886        mTmpRecents.clear();
3887        // mRecentTasks is now in sorted, affiliated order.
3888    }
3889
3890    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3891        int N = mRecentTasks.size();
3892        TaskRecord top = task;
3893        int topIndex = taskIndex;
3894        while (top.mNextAffiliate != null && topIndex > 0) {
3895            top = top.mNextAffiliate;
3896            topIndex--;
3897        }
3898        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3899                + topIndex + " from intial " + taskIndex);
3900        // Find the end of the chain, doing a sanity check along the way.
3901        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3902        int endIndex = topIndex;
3903        TaskRecord prev = top;
3904        while (endIndex < N) {
3905            TaskRecord cur = mRecentTasks.get(endIndex);
3906            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3907                    + endIndex + " " + cur);
3908            if (cur == top) {
3909                // Verify start of the chain.
3910                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3911                    Slog.wtf(TAG, "Bad chain @" + endIndex
3912                            + ": first task has next affiliate: " + prev);
3913                    sane = false;
3914                    break;
3915                }
3916            } else {
3917                // Verify middle of the chain's next points back to the one before.
3918                if (cur.mNextAffiliate != prev
3919                        || cur.mNextAffiliateTaskId != prev.taskId) {
3920                    Slog.wtf(TAG, "Bad chain @" + endIndex
3921                            + ": middle task " + cur + " @" + endIndex
3922                            + " has bad next affiliate "
3923                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3924                            + ", expected " + prev);
3925                    sane = false;
3926                    break;
3927                }
3928            }
3929            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3930                // Chain ends here.
3931                if (cur.mPrevAffiliate != null) {
3932                    Slog.wtf(TAG, "Bad chain @" + endIndex
3933                            + ": last task " + cur + " has previous affiliate "
3934                            + cur.mPrevAffiliate);
3935                    sane = false;
3936                }
3937                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3938                break;
3939            } else {
3940                // Verify middle of the chain's prev points to a valid item.
3941                if (cur.mPrevAffiliate == null) {
3942                    Slog.wtf(TAG, "Bad chain @" + endIndex
3943                            + ": task " + cur + " has previous affiliate "
3944                            + cur.mPrevAffiliate + " but should be id "
3945                            + cur.mPrevAffiliate);
3946                    sane = false;
3947                    break;
3948                }
3949            }
3950            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3951                Slog.wtf(TAG, "Bad chain @" + endIndex
3952                        + ": task " + cur + " has affiliated id "
3953                        + cur.mAffiliatedTaskId + " but should be "
3954                        + task.mAffiliatedTaskId);
3955                sane = false;
3956                break;
3957            }
3958            prev = cur;
3959            endIndex++;
3960            if (endIndex >= N) {
3961                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3962                        + ": last task " + prev);
3963                sane = false;
3964                break;
3965            }
3966        }
3967        if (sane) {
3968            if (endIndex < taskIndex) {
3969                Slog.wtf(TAG, "Bad chain @" + endIndex
3970                        + ": did not extend to task " + task + " @" + taskIndex);
3971                sane = false;
3972            }
3973        }
3974        if (sane) {
3975            // All looks good, we can just move all of the affiliated tasks
3976            // to the top.
3977            for (int i=topIndex; i<=endIndex; i++) {
3978                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3979                        + " from " + i + " to " + (i-topIndex));
3980                TaskRecord cur = mRecentTasks.remove(i);
3981                mRecentTasks.add(i-topIndex, cur);
3982            }
3983            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3984                    + " to " + endIndex);
3985            return true;
3986        }
3987
3988        // Whoops, couldn't do it.
3989        return false;
3990    }
3991
3992    final void addRecentTaskLocked(TaskRecord task) {
3993        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3994                || task.mNextAffiliateTaskId != INVALID_TASK_ID
3995                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
3996
3997        int N = mRecentTasks.size();
3998        // Quick case: check if the top-most recent task is the same.
3999        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4000            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4001            return;
4002        }
4003        // Another quick case: check if this is part of a set of affiliated
4004        // tasks that are at the top.
4005        if (isAffiliated && N > 0 && task.inRecents
4006                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4007            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4008                    + " at top when adding " + task);
4009            return;
4010        }
4011        // Another quick case: never add voice sessions.
4012        if (task.voiceSession != null) {
4013            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4014            return;
4015        }
4016
4017        boolean needAffiliationFix = false;
4018
4019        // Slightly less quick case: the task is already in recents, so all we need
4020        // to do is move it.
4021        if (task.inRecents) {
4022            int taskIndex = mRecentTasks.indexOf(task);
4023            if (taskIndex >= 0) {
4024                if (!isAffiliated) {
4025                    // Simple case: this is not an affiliated task, so we just move it to the front.
4026                    mRecentTasks.remove(taskIndex);
4027                    mRecentTasks.add(0, task);
4028                    notifyTaskPersisterLocked(task, false);
4029                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4030                            + " from " + taskIndex);
4031                    return;
4032                } else {
4033                    // More complicated: need to keep all affiliated tasks together.
4034                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4035                        // All went well.
4036                        return;
4037                    }
4038
4039                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4040                    // everything and then go through our general path of adding a new task.
4041                    needAffiliationFix = true;
4042                }
4043            } else {
4044                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4045                needAffiliationFix = true;
4046            }
4047        }
4048
4049        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4050        trimRecentsForTaskLocked(task, true);
4051
4052        N = mRecentTasks.size();
4053        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4054            final TaskRecord tr = mRecentTasks.remove(N - 1);
4055            tr.removedFromRecents();
4056            N--;
4057        }
4058        task.inRecents = true;
4059        if (!isAffiliated || needAffiliationFix) {
4060            // If this is a simple non-affiliated task, or we had some failure trying to
4061            // handle it as part of an affilated task, then just place it at the top.
4062            mRecentTasks.add(0, task);
4063        } else if (isAffiliated) {
4064            // If this is a new affiliated task, then move all of the affiliated tasks
4065            // to the front and insert this new one.
4066            TaskRecord other = task.mNextAffiliate;
4067            if (other == null) {
4068                other = task.mPrevAffiliate;
4069            }
4070            if (other != null) {
4071                int otherIndex = mRecentTasks.indexOf(other);
4072                if (otherIndex >= 0) {
4073                    // Insert new task at appropriate location.
4074                    int taskIndex;
4075                    if (other == task.mNextAffiliate) {
4076                        // We found the index of our next affiliation, which is who is
4077                        // before us in the list, so add after that point.
4078                        taskIndex = otherIndex+1;
4079                    } else {
4080                        // We found the index of our previous affiliation, which is who is
4081                        // after us in the list, so add at their position.
4082                        taskIndex = otherIndex;
4083                    }
4084                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4085                            + taskIndex + ": " + task);
4086                    mRecentTasks.add(taskIndex, task);
4087
4088                    // Now move everything to the front.
4089                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4090                        // All went well.
4091                        return;
4092                    }
4093
4094                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4095                    // everything and then go through our general path of adding a new task.
4096                    needAffiliationFix = true;
4097                } else {
4098                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4099                            + other);
4100                    needAffiliationFix = true;
4101                }
4102            } else {
4103                if (DEBUG_RECENTS) Slog.d(TAG,
4104                        "addRecent: adding affiliated task without next/prev:" + task);
4105                needAffiliationFix = true;
4106            }
4107        }
4108        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4109
4110        if (needAffiliationFix) {
4111            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4112            cleanupRecentTasksLocked(task.userId);
4113        }
4114    }
4115
4116    /**
4117     * If needed, remove oldest existing entries in recents that are for the same kind
4118     * of task as the given one.
4119     */
4120    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4121        int N = mRecentTasks.size();
4122        final Intent intent = task.intent;
4123        final boolean document = intent != null && intent.isDocument();
4124
4125        int maxRecents = task.maxRecents - 1;
4126        for (int i=0; i<N; i++) {
4127            final TaskRecord tr = mRecentTasks.get(i);
4128            if (task != tr) {
4129                if (task.userId != tr.userId) {
4130                    continue;
4131                }
4132                if (i > MAX_RECENT_BITMAPS) {
4133                    tr.freeLastThumbnail();
4134                }
4135                final Intent trIntent = tr.intent;
4136                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4137                    (intent == null || !intent.filterEquals(trIntent))) {
4138                    continue;
4139                }
4140                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4141                if (document && trIsDocument) {
4142                    // These are the same document activity (not necessarily the same doc).
4143                    if (maxRecents > 0) {
4144                        --maxRecents;
4145                        continue;
4146                    }
4147                    // Hit the maximum number of documents for this task. Fall through
4148                    // and remove this document from recents.
4149                } else if (document || trIsDocument) {
4150                    // Only one of these is a document. Not the droid we're looking for.
4151                    continue;
4152                }
4153            }
4154
4155            if (!doTrim) {
4156                // If the caller is not actually asking for a trim, just tell them we reached
4157                // a point where the trim would happen.
4158                return i;
4159            }
4160
4161            // Either task and tr are the same or, their affinities match or their intents match
4162            // and neither of them is a document, or they are documents using the same activity
4163            // and their maxRecents has been reached.
4164            tr.disposeThumbnail();
4165            mRecentTasks.remove(i);
4166            if (task != tr) {
4167                tr.removedFromRecents();
4168            }
4169            i--;
4170            N--;
4171            if (task.intent == null) {
4172                // If the new recent task we are adding is not fully
4173                // specified, then replace it with the existing recent task.
4174                task = tr;
4175            }
4176            notifyTaskPersisterLocked(tr, false);
4177        }
4178
4179        return -1;
4180    }
4181
4182    @Override
4183    public void reportActivityFullyDrawn(IBinder token) {
4184        synchronized (this) {
4185            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4186            if (r == null) {
4187                return;
4188            }
4189            r.reportFullyDrawnLocked();
4190        }
4191    }
4192
4193    @Override
4194    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4195        synchronized (this) {
4196            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4197            if (r == null) {
4198                return;
4199            }
4200            final long origId = Binder.clearCallingIdentity();
4201            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4202            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4203                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4204            if (config != null) {
4205                r.frozenBeforeDestroy = true;
4206                if (!updateConfigurationLocked(config, r, false, false)) {
4207                    mStackSupervisor.resumeTopActivitiesLocked();
4208                }
4209            }
4210            Binder.restoreCallingIdentity(origId);
4211        }
4212    }
4213
4214    @Override
4215    public int getRequestedOrientation(IBinder token) {
4216        synchronized (this) {
4217            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4218            if (r == null) {
4219                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4220            }
4221            return mWindowManager.getAppOrientation(r.appToken);
4222        }
4223    }
4224
4225    /**
4226     * This is the internal entry point for handling Activity.finish().
4227     *
4228     * @param token The Binder token referencing the Activity we want to finish.
4229     * @param resultCode Result code, if any, from this Activity.
4230     * @param resultData Result data (Intent), if any, from this Activity.
4231     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4232     *            the root Activity in the task.
4233     *
4234     * @return Returns true if the activity successfully finished, or false if it is still running.
4235     */
4236    @Override
4237    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4238            boolean finishTask) {
4239        // Refuse possible leaked file descriptors
4240        if (resultData != null && resultData.hasFileDescriptors() == true) {
4241            throw new IllegalArgumentException("File descriptors passed in Intent");
4242        }
4243
4244        synchronized(this) {
4245            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4246            if (r == null) {
4247                return true;
4248            }
4249            // Keep track of the root activity of the task before we finish it
4250            TaskRecord tr = r.task;
4251            ActivityRecord rootR = tr.getRootActivity();
4252            if (rootR == null) {
4253                Slog.w(TAG, "Finishing task with all activities already finished");
4254            }
4255            // Do not allow task to finish in Lock Task mode.
4256            if (tr == mStackSupervisor.mLockTaskModeTask) {
4257                if (rootR == r) {
4258                    Slog.i(TAG, "Not finishing task in lock task mode");
4259                    mStackSupervisor.showLockTaskToast();
4260                    return false;
4261                }
4262            }
4263            if (mController != null) {
4264                // Find the first activity that is not finishing.
4265                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4266                if (next != null) {
4267                    // ask watcher if this is allowed
4268                    boolean resumeOK = true;
4269                    try {
4270                        resumeOK = mController.activityResuming(next.packageName);
4271                    } catch (RemoteException e) {
4272                        mController = null;
4273                        Watchdog.getInstance().setActivityController(null);
4274                    }
4275
4276                    if (!resumeOK) {
4277                        Slog.i(TAG, "Not finishing activity because controller resumed");
4278                        return false;
4279                    }
4280                }
4281            }
4282            final long origId = Binder.clearCallingIdentity();
4283            try {
4284                boolean res;
4285                if (finishTask && r == rootR) {
4286                    // If requested, remove the task that is associated to this activity only if it
4287                    // was the root activity in the task. The result code and data is ignored
4288                    // because we don't support returning them across task boundaries.
4289                    res = removeTaskByIdLocked(tr.taskId, false);
4290                    if (!res) {
4291                        Slog.i(TAG, "Removing task failed to finish activity");
4292                    }
4293                } else {
4294                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4295                            resultData, "app-request", true);
4296                    if (!res) {
4297                        Slog.i(TAG, "Failed to finish by app-request");
4298                    }
4299                }
4300                return res;
4301            } finally {
4302                Binder.restoreCallingIdentity(origId);
4303            }
4304        }
4305    }
4306
4307    @Override
4308    public final void finishHeavyWeightApp() {
4309        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4310                != PackageManager.PERMISSION_GRANTED) {
4311            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4312                    + Binder.getCallingPid()
4313                    + ", uid=" + Binder.getCallingUid()
4314                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4315            Slog.w(TAG, msg);
4316            throw new SecurityException(msg);
4317        }
4318
4319        synchronized(this) {
4320            if (mHeavyWeightProcess == null) {
4321                return;
4322            }
4323
4324            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4325                    mHeavyWeightProcess.activities);
4326            for (int i=0; i<activities.size(); i++) {
4327                ActivityRecord r = activities.get(i);
4328                if (!r.finishing) {
4329                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4330                            null, "finish-heavy", true);
4331                }
4332            }
4333
4334            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4335                    mHeavyWeightProcess.userId, 0));
4336            mHeavyWeightProcess = null;
4337        }
4338    }
4339
4340    @Override
4341    public void crashApplication(int uid, int initialPid, String packageName,
4342            String message) {
4343        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4344                != PackageManager.PERMISSION_GRANTED) {
4345            String msg = "Permission Denial: crashApplication() from pid="
4346                    + Binder.getCallingPid()
4347                    + ", uid=" + Binder.getCallingUid()
4348                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4349            Slog.w(TAG, msg);
4350            throw new SecurityException(msg);
4351        }
4352
4353        synchronized(this) {
4354            ProcessRecord proc = null;
4355
4356            // Figure out which process to kill.  We don't trust that initialPid
4357            // still has any relation to current pids, so must scan through the
4358            // list.
4359            synchronized (mPidsSelfLocked) {
4360                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4361                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4362                    if (p.uid != uid) {
4363                        continue;
4364                    }
4365                    if (p.pid == initialPid) {
4366                        proc = p;
4367                        break;
4368                    }
4369                    if (p.pkgList.containsKey(packageName)) {
4370                        proc = p;
4371                    }
4372                }
4373            }
4374
4375            if (proc == null) {
4376                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4377                        + " initialPid=" + initialPid
4378                        + " packageName=" + packageName);
4379                return;
4380            }
4381
4382            if (proc.thread != null) {
4383                if (proc.pid == Process.myPid()) {
4384                    Log.w(TAG, "crashApplication: trying to crash self!");
4385                    return;
4386                }
4387                long ident = Binder.clearCallingIdentity();
4388                try {
4389                    proc.thread.scheduleCrash(message);
4390                } catch (RemoteException e) {
4391                }
4392                Binder.restoreCallingIdentity(ident);
4393            }
4394        }
4395    }
4396
4397    @Override
4398    public final void finishSubActivity(IBinder token, String resultWho,
4399            int requestCode) {
4400        synchronized(this) {
4401            final long origId = Binder.clearCallingIdentity();
4402            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4403            if (r != null) {
4404                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4405            }
4406            Binder.restoreCallingIdentity(origId);
4407        }
4408    }
4409
4410    @Override
4411    public boolean finishActivityAffinity(IBinder token) {
4412        synchronized(this) {
4413            final long origId = Binder.clearCallingIdentity();
4414            try {
4415                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4416
4417                ActivityRecord rootR = r.task.getRootActivity();
4418                // Do not allow task to finish in Lock Task mode.
4419                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4420                    if (rootR == r) {
4421                        mStackSupervisor.showLockTaskToast();
4422                        return false;
4423                    }
4424                }
4425                boolean res = false;
4426                if (r != null) {
4427                    res = r.task.stack.finishActivityAffinityLocked(r);
4428                }
4429                return res;
4430            } finally {
4431                Binder.restoreCallingIdentity(origId);
4432            }
4433        }
4434    }
4435
4436    @Override
4437    public void finishVoiceTask(IVoiceInteractionSession session) {
4438        synchronized(this) {
4439            final long origId = Binder.clearCallingIdentity();
4440            try {
4441                mStackSupervisor.finishVoiceTask(session);
4442            } finally {
4443                Binder.restoreCallingIdentity(origId);
4444            }
4445        }
4446
4447    }
4448
4449    @Override
4450    public boolean releaseActivityInstance(IBinder token) {
4451        synchronized(this) {
4452            final long origId = Binder.clearCallingIdentity();
4453            try {
4454                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4455                if (r.task == null || r.task.stack == null) {
4456                    return false;
4457                }
4458                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4459            } finally {
4460                Binder.restoreCallingIdentity(origId);
4461            }
4462        }
4463    }
4464
4465    @Override
4466    public void releaseSomeActivities(IApplicationThread appInt) {
4467        synchronized(this) {
4468            final long origId = Binder.clearCallingIdentity();
4469            try {
4470                ProcessRecord app = getRecordForAppLocked(appInt);
4471                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4472            } finally {
4473                Binder.restoreCallingIdentity(origId);
4474            }
4475        }
4476    }
4477
4478    @Override
4479    public boolean willActivityBeVisible(IBinder token) {
4480        synchronized(this) {
4481            ActivityStack stack = ActivityRecord.getStackLocked(token);
4482            if (stack != null) {
4483                return stack.willActivityBeVisibleLocked(token);
4484            }
4485            return false;
4486        }
4487    }
4488
4489    @Override
4490    public void overridePendingTransition(IBinder token, String packageName,
4491            int enterAnim, int exitAnim) {
4492        synchronized(this) {
4493            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4494            if (self == null) {
4495                return;
4496            }
4497
4498            final long origId = Binder.clearCallingIdentity();
4499
4500            if (self.state == ActivityState.RESUMED
4501                    || self.state == ActivityState.PAUSING) {
4502                mWindowManager.overridePendingAppTransition(packageName,
4503                        enterAnim, exitAnim, null);
4504            }
4505
4506            Binder.restoreCallingIdentity(origId);
4507        }
4508    }
4509
4510    /**
4511     * Main function for removing an existing process from the activity manager
4512     * as a result of that process going away.  Clears out all connections
4513     * to the process.
4514     */
4515    private final void handleAppDiedLocked(ProcessRecord app,
4516            boolean restarting, boolean allowRestart) {
4517        int pid = app.pid;
4518        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4519        if (!kept && !restarting) {
4520            removeLruProcessLocked(app);
4521            if (pid > 0) {
4522                ProcessList.remove(pid);
4523            }
4524        }
4525
4526        if (mProfileProc == app) {
4527            clearProfilerLocked();
4528        }
4529
4530        // Remove this application's activities from active lists.
4531        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4532
4533        app.activities.clear();
4534
4535        if (app.instrumentationClass != null) {
4536            Slog.w(TAG, "Crash of app " + app.processName
4537                  + " running instrumentation " + app.instrumentationClass);
4538            Bundle info = new Bundle();
4539            info.putString("shortMsg", "Process crashed.");
4540            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4541        }
4542
4543        if (!restarting) {
4544            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4545                // If there was nothing to resume, and we are not already
4546                // restarting this process, but there is a visible activity that
4547                // is hosted by the process...  then make sure all visible
4548                // activities are running, taking care of restarting this
4549                // process.
4550                if (hasVisibleActivities) {
4551                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4552                }
4553            }
4554        }
4555    }
4556
4557    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4558        IBinder threadBinder = thread.asBinder();
4559        // Find the application record.
4560        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4561            ProcessRecord rec = mLruProcesses.get(i);
4562            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4563                return i;
4564            }
4565        }
4566        return -1;
4567    }
4568
4569    final ProcessRecord getRecordForAppLocked(
4570            IApplicationThread thread) {
4571        if (thread == null) {
4572            return null;
4573        }
4574
4575        int appIndex = getLRURecordIndexForAppLocked(thread);
4576        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4577    }
4578
4579    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4580        // If there are no longer any background processes running,
4581        // and the app that died was not running instrumentation,
4582        // then tell everyone we are now low on memory.
4583        boolean haveBg = false;
4584        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4585            ProcessRecord rec = mLruProcesses.get(i);
4586            if (rec.thread != null
4587                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4588                haveBg = true;
4589                break;
4590            }
4591        }
4592
4593        if (!haveBg) {
4594            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4595            if (doReport) {
4596                long now = SystemClock.uptimeMillis();
4597                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4598                    doReport = false;
4599                } else {
4600                    mLastMemUsageReportTime = now;
4601                }
4602            }
4603            final ArrayList<ProcessMemInfo> memInfos
4604                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4605            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4606            long now = SystemClock.uptimeMillis();
4607            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4608                ProcessRecord rec = mLruProcesses.get(i);
4609                if (rec == dyingProc || rec.thread == null) {
4610                    continue;
4611                }
4612                if (doReport) {
4613                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4614                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4615                }
4616                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4617                    // The low memory report is overriding any current
4618                    // state for a GC request.  Make sure to do
4619                    // heavy/important/visible/foreground processes first.
4620                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4621                        rec.lastRequestedGc = 0;
4622                    } else {
4623                        rec.lastRequestedGc = rec.lastLowMemory;
4624                    }
4625                    rec.reportLowMemory = true;
4626                    rec.lastLowMemory = now;
4627                    mProcessesToGc.remove(rec);
4628                    addProcessToGcListLocked(rec);
4629                }
4630            }
4631            if (doReport) {
4632                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4633                mHandler.sendMessage(msg);
4634            }
4635            scheduleAppGcsLocked();
4636        }
4637    }
4638
4639    final void appDiedLocked(ProcessRecord app) {
4640       appDiedLocked(app, app.pid, app.thread);
4641    }
4642
4643    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4644        // First check if this ProcessRecord is actually active for the pid.
4645        synchronized (mPidsSelfLocked) {
4646            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4647            if (curProc != app) {
4648                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4649                return;
4650            }
4651        }
4652
4653        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4654        synchronized (stats) {
4655            stats.noteProcessDiedLocked(app.info.uid, pid);
4656        }
4657
4658        if (!app.killed) {
4659            Process.killProcessQuiet(pid);
4660            Process.killProcessGroup(app.info.uid, pid);
4661            app.killed = true;
4662        }
4663
4664        // Clean up already done if the process has been re-started.
4665        if (app.pid == pid && app.thread != null &&
4666                app.thread.asBinder() == thread.asBinder()) {
4667            boolean doLowMem = app.instrumentationClass == null;
4668            boolean doOomAdj = doLowMem;
4669            if (!app.killedByAm) {
4670                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4671                        + ") has died");
4672                mAllowLowerMemLevel = true;
4673            } else {
4674                // Note that we always want to do oom adj to update our state with the
4675                // new number of procs.
4676                mAllowLowerMemLevel = false;
4677                doLowMem = false;
4678            }
4679            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4680            if (DEBUG_CLEANUP) Slog.v(
4681                TAG, "Dying app: " + app + ", pid: " + pid
4682                + ", thread: " + thread.asBinder());
4683            handleAppDiedLocked(app, false, true);
4684
4685            if (doOomAdj) {
4686                updateOomAdjLocked();
4687            }
4688            if (doLowMem) {
4689                doLowMemReportIfNeededLocked(app);
4690            }
4691        } else if (app.pid != pid) {
4692            // A new process has already been started.
4693            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4694                    + ") has died and restarted (pid " + app.pid + ").");
4695            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4696        } else if (DEBUG_PROCESSES) {
4697            Slog.d(TAG, "Received spurious death notification for thread "
4698                    + thread.asBinder());
4699        }
4700    }
4701
4702    /**
4703     * If a stack trace dump file is configured, dump process stack traces.
4704     * @param clearTraces causes the dump file to be erased prior to the new
4705     *    traces being written, if true; when false, the new traces will be
4706     *    appended to any existing file content.
4707     * @param firstPids of dalvik VM processes to dump stack traces for first
4708     * @param lastPids of dalvik VM processes to dump stack traces for last
4709     * @param nativeProcs optional list of native process names to dump stack crawls
4710     * @return file containing stack traces, or null if no dump file is configured
4711     */
4712    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4713            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4714        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4715        if (tracesPath == null || tracesPath.length() == 0) {
4716            return null;
4717        }
4718
4719        File tracesFile = new File(tracesPath);
4720        try {
4721            File tracesDir = tracesFile.getParentFile();
4722            if (!tracesDir.exists()) {
4723                tracesDir.mkdirs();
4724                if (!SELinux.restorecon(tracesDir)) {
4725                    return null;
4726                }
4727            }
4728            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4729
4730            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4731            tracesFile.createNewFile();
4732            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4733        } catch (IOException e) {
4734            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4735            return null;
4736        }
4737
4738        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4739        return tracesFile;
4740    }
4741
4742    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4743            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4744        // Use a FileObserver to detect when traces finish writing.
4745        // The order of traces is considered important to maintain for legibility.
4746        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4747            @Override
4748            public synchronized void onEvent(int event, String path) { notify(); }
4749        };
4750
4751        try {
4752            observer.startWatching();
4753
4754            // First collect all of the stacks of the most important pids.
4755            if (firstPids != null) {
4756                try {
4757                    int num = firstPids.size();
4758                    for (int i = 0; i < num; i++) {
4759                        synchronized (observer) {
4760                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4761                            observer.wait(200);  // Wait for write-close, give up after 200msec
4762                        }
4763                    }
4764                } catch (InterruptedException e) {
4765                    Slog.wtf(TAG, e);
4766                }
4767            }
4768
4769            // Next collect the stacks of the native pids
4770            if (nativeProcs != null) {
4771                int[] pids = Process.getPidsForCommands(nativeProcs);
4772                if (pids != null) {
4773                    for (int pid : pids) {
4774                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4775                    }
4776                }
4777            }
4778
4779            // Lastly, measure CPU usage.
4780            if (processCpuTracker != null) {
4781                processCpuTracker.init();
4782                System.gc();
4783                processCpuTracker.update();
4784                try {
4785                    synchronized (processCpuTracker) {
4786                        processCpuTracker.wait(500); // measure over 1/2 second.
4787                    }
4788                } catch (InterruptedException e) {
4789                }
4790                processCpuTracker.update();
4791
4792                // We'll take the stack crawls of just the top apps using CPU.
4793                final int N = processCpuTracker.countWorkingStats();
4794                int numProcs = 0;
4795                for (int i=0; i<N && numProcs<5; i++) {
4796                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4797                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4798                        numProcs++;
4799                        try {
4800                            synchronized (observer) {
4801                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4802                                observer.wait(200);  // Wait for write-close, give up after 200msec
4803                            }
4804                        } catch (InterruptedException e) {
4805                            Slog.wtf(TAG, e);
4806                        }
4807
4808                    }
4809                }
4810            }
4811        } finally {
4812            observer.stopWatching();
4813        }
4814    }
4815
4816    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4817        if (true || IS_USER_BUILD) {
4818            return;
4819        }
4820        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4821        if (tracesPath == null || tracesPath.length() == 0) {
4822            return;
4823        }
4824
4825        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4826        StrictMode.allowThreadDiskWrites();
4827        try {
4828            final File tracesFile = new File(tracesPath);
4829            final File tracesDir = tracesFile.getParentFile();
4830            final File tracesTmp = new File(tracesDir, "__tmp__");
4831            try {
4832                if (!tracesDir.exists()) {
4833                    tracesDir.mkdirs();
4834                    if (!SELinux.restorecon(tracesDir.getPath())) {
4835                        return;
4836                    }
4837                }
4838                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4839
4840                if (tracesFile.exists()) {
4841                    tracesTmp.delete();
4842                    tracesFile.renameTo(tracesTmp);
4843                }
4844                StringBuilder sb = new StringBuilder();
4845                Time tobj = new Time();
4846                tobj.set(System.currentTimeMillis());
4847                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4848                sb.append(": ");
4849                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4850                sb.append(" since ");
4851                sb.append(msg);
4852                FileOutputStream fos = new FileOutputStream(tracesFile);
4853                fos.write(sb.toString().getBytes());
4854                if (app == null) {
4855                    fos.write("\n*** No application process!".getBytes());
4856                }
4857                fos.close();
4858                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4859            } catch (IOException e) {
4860                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4861                return;
4862            }
4863
4864            if (app != null) {
4865                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4866                firstPids.add(app.pid);
4867                dumpStackTraces(tracesPath, firstPids, null, null, null);
4868            }
4869
4870            File lastTracesFile = null;
4871            File curTracesFile = null;
4872            for (int i=9; i>=0; i--) {
4873                String name = String.format(Locale.US, "slow%02d.txt", i);
4874                curTracesFile = new File(tracesDir, name);
4875                if (curTracesFile.exists()) {
4876                    if (lastTracesFile != null) {
4877                        curTracesFile.renameTo(lastTracesFile);
4878                    } else {
4879                        curTracesFile.delete();
4880                    }
4881                }
4882                lastTracesFile = curTracesFile;
4883            }
4884            tracesFile.renameTo(curTracesFile);
4885            if (tracesTmp.exists()) {
4886                tracesTmp.renameTo(tracesFile);
4887            }
4888        } finally {
4889            StrictMode.setThreadPolicy(oldPolicy);
4890        }
4891    }
4892
4893    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4894            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4895        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4896        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4897
4898        if (mController != null) {
4899            try {
4900                // 0 == continue, -1 = kill process immediately
4901                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4902                if (res < 0 && app.pid != MY_PID) {
4903                    app.kill("anr", true);
4904                }
4905            } catch (RemoteException e) {
4906                mController = null;
4907                Watchdog.getInstance().setActivityController(null);
4908            }
4909        }
4910
4911        long anrTime = SystemClock.uptimeMillis();
4912        if (MONITOR_CPU_USAGE) {
4913            updateCpuStatsNow();
4914        }
4915
4916        synchronized (this) {
4917            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4918            if (mShuttingDown) {
4919                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4920                return;
4921            } else if (app.notResponding) {
4922                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4923                return;
4924            } else if (app.crashing) {
4925                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4926                return;
4927            }
4928
4929            // In case we come through here for the same app before completing
4930            // this one, mark as anring now so we will bail out.
4931            app.notResponding = true;
4932
4933            // Log the ANR to the event log.
4934            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4935                    app.processName, app.info.flags, annotation);
4936
4937            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4938            firstPids.add(app.pid);
4939
4940            int parentPid = app.pid;
4941            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4942            if (parentPid != app.pid) firstPids.add(parentPid);
4943
4944            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4945
4946            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4947                ProcessRecord r = mLruProcesses.get(i);
4948                if (r != null && r.thread != null) {
4949                    int pid = r.pid;
4950                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4951                        if (r.persistent) {
4952                            firstPids.add(pid);
4953                        } else {
4954                            lastPids.put(pid, Boolean.TRUE);
4955                        }
4956                    }
4957                }
4958            }
4959        }
4960
4961        // Log the ANR to the main log.
4962        StringBuilder info = new StringBuilder();
4963        info.setLength(0);
4964        info.append("ANR in ").append(app.processName);
4965        if (activity != null && activity.shortComponentName != null) {
4966            info.append(" (").append(activity.shortComponentName).append(")");
4967        }
4968        info.append("\n");
4969        info.append("PID: ").append(app.pid).append("\n");
4970        if (annotation != null) {
4971            info.append("Reason: ").append(annotation).append("\n");
4972        }
4973        if (parent != null && parent != activity) {
4974            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4975        }
4976
4977        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4978
4979        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4980                NATIVE_STACKS_OF_INTEREST);
4981
4982        String cpuInfo = null;
4983        if (MONITOR_CPU_USAGE) {
4984            updateCpuStatsNow();
4985            synchronized (mProcessCpuTracker) {
4986                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4987            }
4988            info.append(processCpuTracker.printCurrentLoad());
4989            info.append(cpuInfo);
4990        }
4991
4992        info.append(processCpuTracker.printCurrentState(anrTime));
4993
4994        Slog.e(TAG, info.toString());
4995        if (tracesFile == null) {
4996            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4997            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4998        }
4999
5000        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5001                cpuInfo, tracesFile, null);
5002
5003        if (mController != null) {
5004            try {
5005                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5006                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5007                if (res != 0) {
5008                    if (res < 0 && app.pid != MY_PID) {
5009                        app.kill("anr", true);
5010                    } else {
5011                        synchronized (this) {
5012                            mServices.scheduleServiceTimeoutLocked(app);
5013                        }
5014                    }
5015                    return;
5016                }
5017            } catch (RemoteException e) {
5018                mController = null;
5019                Watchdog.getInstance().setActivityController(null);
5020            }
5021        }
5022
5023        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5024        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5025                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5026
5027        synchronized (this) {
5028            mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5029
5030            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5031                app.kill("bg anr", true);
5032                return;
5033            }
5034
5035            // Set the app's notResponding state, and look up the errorReportReceiver
5036            makeAppNotRespondingLocked(app,
5037                    activity != null ? activity.shortComponentName : null,
5038                    annotation != null ? "ANR " + annotation : "ANR",
5039                    info.toString());
5040
5041            // Bring up the infamous App Not Responding dialog
5042            Message msg = Message.obtain();
5043            HashMap<String, Object> map = new HashMap<String, Object>();
5044            msg.what = SHOW_NOT_RESPONDING_MSG;
5045            msg.obj = map;
5046            msg.arg1 = aboveSystem ? 1 : 0;
5047            map.put("app", app);
5048            if (activity != null) {
5049                map.put("activity", activity);
5050            }
5051
5052            mHandler.sendMessage(msg);
5053        }
5054    }
5055
5056    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5057        if (!mLaunchWarningShown) {
5058            mLaunchWarningShown = true;
5059            mHandler.post(new Runnable() {
5060                @Override
5061                public void run() {
5062                    synchronized (ActivityManagerService.this) {
5063                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5064                        d.show();
5065                        mHandler.postDelayed(new Runnable() {
5066                            @Override
5067                            public void run() {
5068                                synchronized (ActivityManagerService.this) {
5069                                    d.dismiss();
5070                                    mLaunchWarningShown = false;
5071                                }
5072                            }
5073                        }, 4000);
5074                    }
5075                }
5076            });
5077        }
5078    }
5079
5080    @Override
5081    public boolean clearApplicationUserData(final String packageName,
5082            final IPackageDataObserver observer, int userId) {
5083        enforceNotIsolatedCaller("clearApplicationUserData");
5084        int uid = Binder.getCallingUid();
5085        int pid = Binder.getCallingPid();
5086        userId = handleIncomingUser(pid, uid,
5087                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5088        long callingId = Binder.clearCallingIdentity();
5089        try {
5090            IPackageManager pm = AppGlobals.getPackageManager();
5091            int pkgUid = -1;
5092            synchronized(this) {
5093                try {
5094                    pkgUid = pm.getPackageUid(packageName, userId);
5095                } catch (RemoteException e) {
5096                }
5097                if (pkgUid == -1) {
5098                    Slog.w(TAG, "Invalid packageName: " + packageName);
5099                    if (observer != null) {
5100                        try {
5101                            observer.onRemoveCompleted(packageName, false);
5102                        } catch (RemoteException e) {
5103                            Slog.i(TAG, "Observer no longer exists.");
5104                        }
5105                    }
5106                    return false;
5107                }
5108                if (uid == pkgUid || checkComponentPermission(
5109                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5110                        pid, uid, -1, true)
5111                        == PackageManager.PERMISSION_GRANTED) {
5112                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5113                } else {
5114                    throw new SecurityException("PID " + pid + " does not have permission "
5115                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5116                                    + " of package " + packageName);
5117                }
5118
5119                // Remove all tasks match the cleared application package and user
5120                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5121                    final TaskRecord tr = mRecentTasks.get(i);
5122                    final String taskPackageName =
5123                            tr.getBaseIntent().getComponent().getPackageName();
5124                    if (tr.userId != userId) continue;
5125                    if (!taskPackageName.equals(packageName)) continue;
5126                    removeTaskByIdLocked(tr.taskId, false);
5127                }
5128            }
5129
5130            try {
5131                // Clear application user data
5132                pm.clearApplicationUserData(packageName, observer, userId);
5133
5134                synchronized(this) {
5135                    // Remove all permissions granted from/to this package
5136                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5137                }
5138
5139                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5140                        Uri.fromParts("package", packageName, null));
5141                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5142                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5143                        null, null, 0, null, null, null, false, false, userId);
5144            } catch (RemoteException e) {
5145            }
5146        } finally {
5147            Binder.restoreCallingIdentity(callingId);
5148        }
5149        return true;
5150    }
5151
5152    @Override
5153    public void killBackgroundProcesses(final String packageName, int userId) {
5154        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5155                != PackageManager.PERMISSION_GRANTED &&
5156                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5157                        != PackageManager.PERMISSION_GRANTED) {
5158            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5159                    + Binder.getCallingPid()
5160                    + ", uid=" + Binder.getCallingUid()
5161                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5162            Slog.w(TAG, msg);
5163            throw new SecurityException(msg);
5164        }
5165
5166        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5167                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5168        long callingId = Binder.clearCallingIdentity();
5169        try {
5170            IPackageManager pm = AppGlobals.getPackageManager();
5171            synchronized(this) {
5172                int appId = -1;
5173                try {
5174                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5175                } catch (RemoteException e) {
5176                }
5177                if (appId == -1) {
5178                    Slog.w(TAG, "Invalid packageName: " + packageName);
5179                    return;
5180                }
5181                killPackageProcessesLocked(packageName, appId, userId,
5182                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5183            }
5184        } finally {
5185            Binder.restoreCallingIdentity(callingId);
5186        }
5187    }
5188
5189    @Override
5190    public void killAllBackgroundProcesses() {
5191        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5192                != PackageManager.PERMISSION_GRANTED) {
5193            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5194                    + Binder.getCallingPid()
5195                    + ", uid=" + Binder.getCallingUid()
5196                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5197            Slog.w(TAG, msg);
5198            throw new SecurityException(msg);
5199        }
5200
5201        long callingId = Binder.clearCallingIdentity();
5202        try {
5203            synchronized(this) {
5204                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5205                final int NP = mProcessNames.getMap().size();
5206                for (int ip=0; ip<NP; ip++) {
5207                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5208                    final int NA = apps.size();
5209                    for (int ia=0; ia<NA; ia++) {
5210                        ProcessRecord app = apps.valueAt(ia);
5211                        if (app.persistent) {
5212                            // we don't kill persistent processes
5213                            continue;
5214                        }
5215                        if (app.removed) {
5216                            procs.add(app);
5217                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5218                            app.removed = true;
5219                            procs.add(app);
5220                        }
5221                    }
5222                }
5223
5224                int N = procs.size();
5225                for (int i=0; i<N; i++) {
5226                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5227                }
5228                mAllowLowerMemLevel = true;
5229                updateOomAdjLocked();
5230                doLowMemReportIfNeededLocked(null);
5231            }
5232        } finally {
5233            Binder.restoreCallingIdentity(callingId);
5234        }
5235    }
5236
5237    @Override
5238    public void forceStopPackage(final String packageName, int userId) {
5239        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5240                != PackageManager.PERMISSION_GRANTED) {
5241            String msg = "Permission Denial: forceStopPackage() from pid="
5242                    + Binder.getCallingPid()
5243                    + ", uid=" + Binder.getCallingUid()
5244                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5245            Slog.w(TAG, msg);
5246            throw new SecurityException(msg);
5247        }
5248        final int callingPid = Binder.getCallingPid();
5249        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5250                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5251        long callingId = Binder.clearCallingIdentity();
5252        try {
5253            IPackageManager pm = AppGlobals.getPackageManager();
5254            synchronized(this) {
5255                int[] users = userId == UserHandle.USER_ALL
5256                        ? getUsersLocked() : new int[] { userId };
5257                for (int user : users) {
5258                    int pkgUid = -1;
5259                    try {
5260                        pkgUid = pm.getPackageUid(packageName, user);
5261                    } catch (RemoteException e) {
5262                    }
5263                    if (pkgUid == -1) {
5264                        Slog.w(TAG, "Invalid packageName: " + packageName);
5265                        continue;
5266                    }
5267                    try {
5268                        pm.setPackageStoppedState(packageName, true, user);
5269                    } catch (RemoteException e) {
5270                    } catch (IllegalArgumentException e) {
5271                        Slog.w(TAG, "Failed trying to unstop package "
5272                                + packageName + ": " + e);
5273                    }
5274                    if (isUserRunningLocked(user, false)) {
5275                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5276                    }
5277                }
5278            }
5279        } finally {
5280            Binder.restoreCallingIdentity(callingId);
5281        }
5282    }
5283
5284    @Override
5285    public void addPackageDependency(String packageName) {
5286        synchronized (this) {
5287            int callingPid = Binder.getCallingPid();
5288            if (callingPid == Process.myPid()) {
5289                //  Yeah, um, no.
5290                Slog.w(TAG, "Can't addPackageDependency on system process");
5291                return;
5292            }
5293            ProcessRecord proc;
5294            synchronized (mPidsSelfLocked) {
5295                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5296            }
5297            if (proc != null) {
5298                if (proc.pkgDeps == null) {
5299                    proc.pkgDeps = new ArraySet<String>(1);
5300                }
5301                proc.pkgDeps.add(packageName);
5302            }
5303        }
5304    }
5305
5306    /*
5307     * The pkg name and app id have to be specified.
5308     */
5309    @Override
5310    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5311        if (pkg == null) {
5312            return;
5313        }
5314        // Make sure the uid is valid.
5315        if (appid < 0) {
5316            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5317            return;
5318        }
5319        int callerUid = Binder.getCallingUid();
5320        // Only the system server can kill an application
5321        if (callerUid == Process.SYSTEM_UID) {
5322            // Post an aysnc message to kill the application
5323            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5324            msg.arg1 = appid;
5325            msg.arg2 = 0;
5326            Bundle bundle = new Bundle();
5327            bundle.putString("pkg", pkg);
5328            bundle.putString("reason", reason);
5329            msg.obj = bundle;
5330            mHandler.sendMessage(msg);
5331        } else {
5332            throw new SecurityException(callerUid + " cannot kill pkg: " +
5333                    pkg);
5334        }
5335    }
5336
5337    @Override
5338    public void closeSystemDialogs(String reason) {
5339        enforceNotIsolatedCaller("closeSystemDialogs");
5340
5341        final int pid = Binder.getCallingPid();
5342        final int uid = Binder.getCallingUid();
5343        final long origId = Binder.clearCallingIdentity();
5344        try {
5345            synchronized (this) {
5346                // Only allow this from foreground processes, so that background
5347                // applications can't abuse it to prevent system UI from being shown.
5348                if (uid >= Process.FIRST_APPLICATION_UID) {
5349                    ProcessRecord proc;
5350                    synchronized (mPidsSelfLocked) {
5351                        proc = mPidsSelfLocked.get(pid);
5352                    }
5353                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5354                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5355                                + " from background process " + proc);
5356                        return;
5357                    }
5358                }
5359                closeSystemDialogsLocked(reason);
5360            }
5361        } finally {
5362            Binder.restoreCallingIdentity(origId);
5363        }
5364    }
5365
5366    void closeSystemDialogsLocked(String reason) {
5367        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5368        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5369                | Intent.FLAG_RECEIVER_FOREGROUND);
5370        if (reason != null) {
5371            intent.putExtra("reason", reason);
5372        }
5373        mWindowManager.closeSystemDialogs(reason);
5374
5375        mStackSupervisor.closeSystemDialogsLocked();
5376
5377        broadcastIntentLocked(null, null, intent, null,
5378                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5379                Process.SYSTEM_UID, UserHandle.USER_ALL);
5380    }
5381
5382    @Override
5383    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5384        enforceNotIsolatedCaller("getProcessMemoryInfo");
5385        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5386        for (int i=pids.length-1; i>=0; i--) {
5387            ProcessRecord proc;
5388            int oomAdj;
5389            synchronized (this) {
5390                synchronized (mPidsSelfLocked) {
5391                    proc = mPidsSelfLocked.get(pids[i]);
5392                    oomAdj = proc != null ? proc.setAdj : 0;
5393                }
5394            }
5395            infos[i] = new Debug.MemoryInfo();
5396            Debug.getMemoryInfo(pids[i], infos[i]);
5397            if (proc != null) {
5398                synchronized (this) {
5399                    if (proc.thread != null && proc.setAdj == oomAdj) {
5400                        // Record this for posterity if the process has been stable.
5401                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5402                                infos[i].getTotalUss(), false, proc.pkgList);
5403                    }
5404                }
5405            }
5406        }
5407        return infos;
5408    }
5409
5410    @Override
5411    public long[] getProcessPss(int[] pids) {
5412        enforceNotIsolatedCaller("getProcessPss");
5413        long[] pss = new long[pids.length];
5414        for (int i=pids.length-1; i>=0; i--) {
5415            ProcessRecord proc;
5416            int oomAdj;
5417            synchronized (this) {
5418                synchronized (mPidsSelfLocked) {
5419                    proc = mPidsSelfLocked.get(pids[i]);
5420                    oomAdj = proc != null ? proc.setAdj : 0;
5421                }
5422            }
5423            long[] tmpUss = new long[1];
5424            pss[i] = Debug.getPss(pids[i], tmpUss, null);
5425            if (proc != null) {
5426                synchronized (this) {
5427                    if (proc.thread != null && proc.setAdj == oomAdj) {
5428                        // Record this for posterity if the process has been stable.
5429                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5430                    }
5431                }
5432            }
5433        }
5434        return pss;
5435    }
5436
5437    @Override
5438    public void killApplicationProcess(String processName, int uid) {
5439        if (processName == null) {
5440            return;
5441        }
5442
5443        int callerUid = Binder.getCallingUid();
5444        // Only the system server can kill an application
5445        if (callerUid == Process.SYSTEM_UID) {
5446            synchronized (this) {
5447                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5448                if (app != null && app.thread != null) {
5449                    try {
5450                        app.thread.scheduleSuicide();
5451                    } catch (RemoteException e) {
5452                        // If the other end already died, then our work here is done.
5453                    }
5454                } else {
5455                    Slog.w(TAG, "Process/uid not found attempting kill of "
5456                            + processName + " / " + uid);
5457                }
5458            }
5459        } else {
5460            throw new SecurityException(callerUid + " cannot kill app process: " +
5461                    processName);
5462        }
5463    }
5464
5465    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5466        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5467                false, true, false, false, UserHandle.getUserId(uid), reason);
5468        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5469                Uri.fromParts("package", packageName, null));
5470        if (!mProcessesReady) {
5471            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5472                    | Intent.FLAG_RECEIVER_FOREGROUND);
5473        }
5474        intent.putExtra(Intent.EXTRA_UID, uid);
5475        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5476        broadcastIntentLocked(null, null, intent,
5477                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5478                false, false,
5479                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5480    }
5481
5482    private void forceStopUserLocked(int userId, String reason) {
5483        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5484        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5485        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5486                | Intent.FLAG_RECEIVER_FOREGROUND);
5487        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5488        broadcastIntentLocked(null, null, intent,
5489                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5490                false, false,
5491                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5492    }
5493
5494    private final boolean killPackageProcessesLocked(String packageName, int appId,
5495            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5496            boolean doit, boolean evenPersistent, String reason) {
5497        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5498
5499        // Remove all processes this package may have touched: all with the
5500        // same UID (except for the system or root user), and all whose name
5501        // matches the package name.
5502        final int NP = mProcessNames.getMap().size();
5503        for (int ip=0; ip<NP; ip++) {
5504            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5505            final int NA = apps.size();
5506            for (int ia=0; ia<NA; ia++) {
5507                ProcessRecord app = apps.valueAt(ia);
5508                if (app.persistent && !evenPersistent) {
5509                    // we don't kill persistent processes
5510                    continue;
5511                }
5512                if (app.removed) {
5513                    if (doit) {
5514                        procs.add(app);
5515                    }
5516                    continue;
5517                }
5518
5519                // Skip process if it doesn't meet our oom adj requirement.
5520                if (app.setAdj < minOomAdj) {
5521                    continue;
5522                }
5523
5524                // If no package is specified, we call all processes under the
5525                // give user id.
5526                if (packageName == null) {
5527                    if (app.userId != userId) {
5528                        continue;
5529                    }
5530                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5531                        continue;
5532                    }
5533                // Package has been specified, we want to hit all processes
5534                // that match it.  We need to qualify this by the processes
5535                // that are running under the specified app and user ID.
5536                } else {
5537                    final boolean isDep = app.pkgDeps != null
5538                            && app.pkgDeps.contains(packageName);
5539                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5540                        continue;
5541                    }
5542                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5543                        continue;
5544                    }
5545                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5546                        continue;
5547                    }
5548                }
5549
5550                // Process has passed all conditions, kill it!
5551                if (!doit) {
5552                    return true;
5553                }
5554                app.removed = true;
5555                procs.add(app);
5556            }
5557        }
5558
5559        int N = procs.size();
5560        for (int i=0; i<N; i++) {
5561            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5562        }
5563        updateOomAdjLocked();
5564        return N > 0;
5565    }
5566
5567    private final boolean forceStopPackageLocked(String name, int appId,
5568            boolean callerWillRestart, boolean purgeCache, boolean doit,
5569            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5570        int i;
5571        int N;
5572
5573        if (userId == UserHandle.USER_ALL && name == null) {
5574            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5575        }
5576
5577        if (appId < 0 && name != null) {
5578            try {
5579                appId = UserHandle.getAppId(
5580                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5581            } catch (RemoteException e) {
5582            }
5583        }
5584
5585        if (doit) {
5586            if (name != null) {
5587                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5588                        + " user=" + userId + ": " + reason);
5589            } else {
5590                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5591            }
5592
5593            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5594            for (int ip=pmap.size()-1; ip>=0; ip--) {
5595                SparseArray<Long> ba = pmap.valueAt(ip);
5596                for (i=ba.size()-1; i>=0; i--) {
5597                    boolean remove = false;
5598                    final int entUid = ba.keyAt(i);
5599                    if (name != null) {
5600                        if (userId == UserHandle.USER_ALL) {
5601                            if (UserHandle.getAppId(entUid) == appId) {
5602                                remove = true;
5603                            }
5604                        } else {
5605                            if (entUid == UserHandle.getUid(userId, appId)) {
5606                                remove = true;
5607                            }
5608                        }
5609                    } else if (UserHandle.getUserId(entUid) == userId) {
5610                        remove = true;
5611                    }
5612                    if (remove) {
5613                        ba.removeAt(i);
5614                    }
5615                }
5616                if (ba.size() == 0) {
5617                    pmap.removeAt(ip);
5618                }
5619            }
5620        }
5621
5622        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5623                -100, callerWillRestart, true, doit, evenPersistent,
5624                name == null ? ("stop user " + userId) : ("stop " + name));
5625
5626        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5627            if (!doit) {
5628                return true;
5629            }
5630            didSomething = true;
5631        }
5632
5633        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5634            if (!doit) {
5635                return true;
5636            }
5637            didSomething = true;
5638        }
5639
5640        if (name == null) {
5641            // Remove all sticky broadcasts from this user.
5642            mStickyBroadcasts.remove(userId);
5643        }
5644
5645        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5646        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5647                userId, providers)) {
5648            if (!doit) {
5649                return true;
5650            }
5651            didSomething = true;
5652        }
5653        N = providers.size();
5654        for (i=0; i<N; i++) {
5655            removeDyingProviderLocked(null, providers.get(i), true);
5656        }
5657
5658        // Remove transient permissions granted from/to this package/user
5659        removeUriPermissionsForPackageLocked(name, userId, false);
5660
5661        if (name == null || uninstalling) {
5662            // Remove pending intents.  For now we only do this when force
5663            // stopping users, because we have some problems when doing this
5664            // for packages -- app widgets are not currently cleaned up for
5665            // such packages, so they can be left with bad pending intents.
5666            if (mIntentSenderRecords.size() > 0) {
5667                Iterator<WeakReference<PendingIntentRecord>> it
5668                        = mIntentSenderRecords.values().iterator();
5669                while (it.hasNext()) {
5670                    WeakReference<PendingIntentRecord> wpir = it.next();
5671                    if (wpir == null) {
5672                        it.remove();
5673                        continue;
5674                    }
5675                    PendingIntentRecord pir = wpir.get();
5676                    if (pir == null) {
5677                        it.remove();
5678                        continue;
5679                    }
5680                    if (name == null) {
5681                        // Stopping user, remove all objects for the user.
5682                        if (pir.key.userId != userId) {
5683                            // Not the same user, skip it.
5684                            continue;
5685                        }
5686                    } else {
5687                        if (UserHandle.getAppId(pir.uid) != appId) {
5688                            // Different app id, skip it.
5689                            continue;
5690                        }
5691                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5692                            // Different user, skip it.
5693                            continue;
5694                        }
5695                        if (!pir.key.packageName.equals(name)) {
5696                            // Different package, skip it.
5697                            continue;
5698                        }
5699                    }
5700                    if (!doit) {
5701                        return true;
5702                    }
5703                    didSomething = true;
5704                    it.remove();
5705                    pir.canceled = true;
5706                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5707                        pir.key.activity.pendingResults.remove(pir.ref);
5708                    }
5709                }
5710            }
5711        }
5712
5713        if (doit) {
5714            if (purgeCache && name != null) {
5715                AttributeCache ac = AttributeCache.instance();
5716                if (ac != null) {
5717                    ac.removePackage(name);
5718                }
5719            }
5720            if (mBooted) {
5721                mStackSupervisor.resumeTopActivitiesLocked();
5722                mStackSupervisor.scheduleIdleLocked();
5723            }
5724        }
5725
5726        return didSomething;
5727    }
5728
5729    private final boolean removeProcessLocked(ProcessRecord app,
5730            boolean callerWillRestart, boolean allowRestart, String reason) {
5731        final String name = app.processName;
5732        final int uid = app.uid;
5733        if (DEBUG_PROCESSES) Slog.d(
5734            TAG, "Force removing proc " + app.toShortString() + " (" + name
5735            + "/" + uid + ")");
5736
5737        mProcessNames.remove(name, uid);
5738        mIsolatedProcesses.remove(app.uid);
5739        if (mHeavyWeightProcess == app) {
5740            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5741                    mHeavyWeightProcess.userId, 0));
5742            mHeavyWeightProcess = null;
5743        }
5744        boolean needRestart = false;
5745        if (app.pid > 0 && app.pid != MY_PID) {
5746            int pid = app.pid;
5747            synchronized (mPidsSelfLocked) {
5748                mPidsSelfLocked.remove(pid);
5749                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5750            }
5751            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5752            if (app.isolated) {
5753                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5754            }
5755            app.kill(reason, true);
5756            handleAppDiedLocked(app, true, allowRestart);
5757            removeLruProcessLocked(app);
5758
5759            if (app.persistent && !app.isolated) {
5760                if (!callerWillRestart) {
5761                    addAppLocked(app.info, false, null /* ABI override */);
5762                } else {
5763                    needRestart = true;
5764                }
5765            }
5766        } else {
5767            mRemovedProcesses.add(app);
5768        }
5769
5770        return needRestart;
5771    }
5772
5773    private final void processStartTimedOutLocked(ProcessRecord app) {
5774        final int pid = app.pid;
5775        boolean gone = false;
5776        synchronized (mPidsSelfLocked) {
5777            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5778            if (knownApp != null && knownApp.thread == null) {
5779                mPidsSelfLocked.remove(pid);
5780                gone = true;
5781            }
5782        }
5783
5784        if (gone) {
5785            Slog.w(TAG, "Process " + app + " failed to attach");
5786            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5787                    pid, app.uid, app.processName);
5788            mProcessNames.remove(app.processName, app.uid);
5789            mIsolatedProcesses.remove(app.uid);
5790            if (mHeavyWeightProcess == app) {
5791                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5792                        mHeavyWeightProcess.userId, 0));
5793                mHeavyWeightProcess = null;
5794            }
5795            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5796            if (app.isolated) {
5797                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5798            }
5799            // Take care of any launching providers waiting for this process.
5800            checkAppInLaunchingProvidersLocked(app, true);
5801            // Take care of any services that are waiting for the process.
5802            mServices.processStartTimedOutLocked(app);
5803            app.kill("start timeout", true);
5804            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5805                Slog.w(TAG, "Unattached app died before backup, skipping");
5806                try {
5807                    IBackupManager bm = IBackupManager.Stub.asInterface(
5808                            ServiceManager.getService(Context.BACKUP_SERVICE));
5809                    bm.agentDisconnected(app.info.packageName);
5810                } catch (RemoteException e) {
5811                    // Can't happen; the backup manager is local
5812                }
5813            }
5814            if (isPendingBroadcastProcessLocked(pid)) {
5815                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5816                skipPendingBroadcastLocked(pid);
5817            }
5818        } else {
5819            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5820        }
5821    }
5822
5823    private final boolean attachApplicationLocked(IApplicationThread thread,
5824            int pid) {
5825
5826        // Find the application record that is being attached...  either via
5827        // the pid if we are running in multiple processes, or just pull the
5828        // next app record if we are emulating process with anonymous threads.
5829        ProcessRecord app;
5830        if (pid != MY_PID && pid >= 0) {
5831            synchronized (mPidsSelfLocked) {
5832                app = mPidsSelfLocked.get(pid);
5833            }
5834        } else {
5835            app = null;
5836        }
5837
5838        if (app == null) {
5839            Slog.w(TAG, "No pending application record for pid " + pid
5840                    + " (IApplicationThread " + thread + "); dropping process");
5841            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5842            if (pid > 0 && pid != MY_PID) {
5843                Process.killProcessQuiet(pid);
5844                //TODO: Process.killProcessGroup(app.info.uid, pid);
5845            } else {
5846                try {
5847                    thread.scheduleExit();
5848                } catch (Exception e) {
5849                    // Ignore exceptions.
5850                }
5851            }
5852            return false;
5853        }
5854
5855        // If this application record is still attached to a previous
5856        // process, clean it up now.
5857        if (app.thread != null) {
5858            handleAppDiedLocked(app, true, true);
5859        }
5860
5861        // Tell the process all about itself.
5862
5863        if (localLOGV) Slog.v(
5864                TAG, "Binding process pid " + pid + " to record " + app);
5865
5866        final String processName = app.processName;
5867        try {
5868            AppDeathRecipient adr = new AppDeathRecipient(
5869                    app, pid, thread);
5870            thread.asBinder().linkToDeath(adr, 0);
5871            app.deathRecipient = adr;
5872        } catch (RemoteException e) {
5873            app.resetPackageList(mProcessStats);
5874            startProcessLocked(app, "link fail", processName);
5875            return false;
5876        }
5877
5878        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5879
5880        app.makeActive(thread, mProcessStats);
5881        app.curAdj = app.setAdj = -100;
5882        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5883        app.forcingToForeground = null;
5884        updateProcessForegroundLocked(app, false, false);
5885        app.hasShownUi = false;
5886        app.debugging = false;
5887        app.cached = false;
5888        app.killedByAm = false;
5889
5890        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5891
5892        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5893        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5894
5895        if (!normalMode) {
5896            Slog.i(TAG, "Launching preboot mode app: " + app);
5897        }
5898
5899        if (localLOGV) Slog.v(
5900            TAG, "New app record " + app
5901            + " thread=" + thread.asBinder() + " pid=" + pid);
5902        try {
5903            int testMode = IApplicationThread.DEBUG_OFF;
5904            if (mDebugApp != null && mDebugApp.equals(processName)) {
5905                testMode = mWaitForDebugger
5906                    ? IApplicationThread.DEBUG_WAIT
5907                    : IApplicationThread.DEBUG_ON;
5908                app.debugging = true;
5909                if (mDebugTransient) {
5910                    mDebugApp = mOrigDebugApp;
5911                    mWaitForDebugger = mOrigWaitForDebugger;
5912                }
5913            }
5914            String profileFile = app.instrumentationProfileFile;
5915            ParcelFileDescriptor profileFd = null;
5916            int samplingInterval = 0;
5917            boolean profileAutoStop = false;
5918            if (mProfileApp != null && mProfileApp.equals(processName)) {
5919                mProfileProc = app;
5920                profileFile = mProfileFile;
5921                profileFd = mProfileFd;
5922                samplingInterval = mSamplingInterval;
5923                profileAutoStop = mAutoStopProfiler;
5924            }
5925            boolean enableOpenGlTrace = false;
5926            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5927                enableOpenGlTrace = true;
5928                mOpenGlTraceApp = null;
5929            }
5930
5931            // If the app is being launched for restore or full backup, set it up specially
5932            boolean isRestrictedBackupMode = false;
5933            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5934                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5935                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5936                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5937            }
5938
5939            ensurePackageDexOpt(app.instrumentationInfo != null
5940                    ? app.instrumentationInfo.packageName
5941                    : app.info.packageName);
5942            if (app.instrumentationClass != null) {
5943                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5944            }
5945            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5946                    + processName + " with config " + mConfiguration);
5947            ApplicationInfo appInfo = app.instrumentationInfo != null
5948                    ? app.instrumentationInfo : app.info;
5949            app.compat = compatibilityInfoForPackageLocked(appInfo);
5950            if (profileFd != null) {
5951                profileFd = profileFd.dup();
5952            }
5953            ProfilerInfo profilerInfo = profileFile == null ? null
5954                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5955            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5956                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5957                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5958                    isRestrictedBackupMode || !normalMode, app.persistent,
5959                    new Configuration(mConfiguration), app.compat,
5960                    getCommonServicesLocked(app.isolated),
5961                    mCoreSettingsObserver.getCoreSettingsLocked());
5962            updateLruProcessLocked(app, false, null);
5963            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5964        } catch (Exception e) {
5965            // todo: Yikes!  What should we do?  For now we will try to
5966            // start another process, but that could easily get us in
5967            // an infinite loop of restarting processes...
5968            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5969
5970            app.resetPackageList(mProcessStats);
5971            app.unlinkDeathRecipient();
5972            startProcessLocked(app, "bind fail", processName);
5973            return false;
5974        }
5975
5976        // Remove this record from the list of starting applications.
5977        mPersistentStartingProcesses.remove(app);
5978        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5979                "Attach application locked removing on hold: " + app);
5980        mProcessesOnHold.remove(app);
5981
5982        boolean badApp = false;
5983        boolean didSomething = false;
5984
5985        // See if the top visible activity is waiting to run in this process...
5986        if (normalMode) {
5987            try {
5988                if (mStackSupervisor.attachApplicationLocked(app)) {
5989                    didSomething = true;
5990                }
5991            } catch (Exception e) {
5992                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5993                badApp = true;
5994            }
5995        }
5996
5997        // Find any services that should be running in this process...
5998        if (!badApp) {
5999            try {
6000                didSomething |= mServices.attachApplicationLocked(app, processName);
6001            } catch (Exception e) {
6002                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6003                badApp = true;
6004            }
6005        }
6006
6007        // Check if a next-broadcast receiver is in this process...
6008        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6009            try {
6010                didSomething |= sendPendingBroadcastsLocked(app);
6011            } catch (Exception e) {
6012                // If the app died trying to launch the receiver we declare it 'bad'
6013                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6014                badApp = true;
6015            }
6016        }
6017
6018        // Check whether the next backup agent is in this process...
6019        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6020            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6021            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6022            try {
6023                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6024                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6025                        mBackupTarget.backupMode);
6026            } catch (Exception e) {
6027                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6028                badApp = true;
6029            }
6030        }
6031
6032        if (badApp) {
6033            app.kill("error during init", true);
6034            handleAppDiedLocked(app, false, true);
6035            return false;
6036        }
6037
6038        if (!didSomething) {
6039            updateOomAdjLocked();
6040        }
6041
6042        return true;
6043    }
6044
6045    @Override
6046    public final void attachApplication(IApplicationThread thread) {
6047        synchronized (this) {
6048            int callingPid = Binder.getCallingPid();
6049            final long origId = Binder.clearCallingIdentity();
6050            attachApplicationLocked(thread, callingPid);
6051            Binder.restoreCallingIdentity(origId);
6052        }
6053    }
6054
6055    @Override
6056    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6057        final long origId = Binder.clearCallingIdentity();
6058        synchronized (this) {
6059            ActivityStack stack = ActivityRecord.getStackLocked(token);
6060            if (stack != null) {
6061                ActivityRecord r =
6062                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6063                if (stopProfiling) {
6064                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6065                        try {
6066                            mProfileFd.close();
6067                        } catch (IOException e) {
6068                        }
6069                        clearProfilerLocked();
6070                    }
6071                }
6072            }
6073        }
6074        Binder.restoreCallingIdentity(origId);
6075    }
6076
6077    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6078        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6079                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6080    }
6081
6082    void enableScreenAfterBoot() {
6083        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6084                SystemClock.uptimeMillis());
6085        mWindowManager.enableScreenAfterBoot();
6086
6087        synchronized (this) {
6088            updateEventDispatchingLocked();
6089        }
6090    }
6091
6092    @Override
6093    public void showBootMessage(final CharSequence msg, final boolean always) {
6094        enforceNotIsolatedCaller("showBootMessage");
6095        mWindowManager.showBootMessage(msg, always);
6096    }
6097
6098    @Override
6099    public void keyguardWaitingForActivityDrawn() {
6100        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6101        final long token = Binder.clearCallingIdentity();
6102        try {
6103            synchronized (this) {
6104                if (DEBUG_LOCKSCREEN) logLockScreen("");
6105                mWindowManager.keyguardWaitingForActivityDrawn();
6106                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6107                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6108                    updateSleepIfNeededLocked();
6109                }
6110            }
6111        } finally {
6112            Binder.restoreCallingIdentity(token);
6113        }
6114    }
6115
6116    final void finishBooting() {
6117        synchronized (this) {
6118            if (!mBootAnimationComplete) {
6119                mCallFinishBooting = true;
6120                return;
6121            }
6122            mCallFinishBooting = false;
6123        }
6124
6125        ArraySet<String> completedIsas = new ArraySet<String>();
6126        for (String abi : Build.SUPPORTED_ABIS) {
6127            Process.establishZygoteConnectionForAbi(abi);
6128            final String instructionSet = VMRuntime.getInstructionSet(abi);
6129            if (!completedIsas.contains(instructionSet)) {
6130                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6131                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6132                }
6133                completedIsas.add(instructionSet);
6134            }
6135        }
6136
6137        IntentFilter pkgFilter = new IntentFilter();
6138        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6139        pkgFilter.addDataScheme("package");
6140        mContext.registerReceiver(new BroadcastReceiver() {
6141            @Override
6142            public void onReceive(Context context, Intent intent) {
6143                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6144                if (pkgs != null) {
6145                    for (String pkg : pkgs) {
6146                        synchronized (ActivityManagerService.this) {
6147                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6148                                    0, "finished booting")) {
6149                                setResultCode(Activity.RESULT_OK);
6150                                return;
6151                            }
6152                        }
6153                    }
6154                }
6155            }
6156        }, pkgFilter);
6157
6158        // Let system services know.
6159        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6160
6161        synchronized (this) {
6162            // Ensure that any processes we had put on hold are now started
6163            // up.
6164            final int NP = mProcessesOnHold.size();
6165            if (NP > 0) {
6166                ArrayList<ProcessRecord> procs =
6167                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6168                for (int ip=0; ip<NP; ip++) {
6169                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6170                            + procs.get(ip));
6171                    startProcessLocked(procs.get(ip), "on-hold", null);
6172                }
6173            }
6174
6175            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6176                // Start looking for apps that are abusing wake locks.
6177                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6178                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6179                // Tell anyone interested that we are done booting!
6180                SystemProperties.set("sys.boot_completed", "1");
6181
6182                // And trigger dev.bootcomplete if we are not showing encryption progress
6183                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6184                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6185                    SystemProperties.set("dev.bootcomplete", "1");
6186                }
6187                for (int i=0; i<mStartedUsers.size(); i++) {
6188                    UserStartedState uss = mStartedUsers.valueAt(i);
6189                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6190                        uss.mState = UserStartedState.STATE_RUNNING;
6191                        final int userId = mStartedUsers.keyAt(i);
6192                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6193                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6194                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6195                        broadcastIntentLocked(null, null, intent, null,
6196                                new IIntentReceiver.Stub() {
6197                                    @Override
6198                                    public void performReceive(Intent intent, int resultCode,
6199                                            String data, Bundle extras, boolean ordered,
6200                                            boolean sticky, int sendingUser) {
6201                                        synchronized (ActivityManagerService.this) {
6202                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6203                                                    true, false);
6204                                        }
6205                                    }
6206                                },
6207                                0, null, null,
6208                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6209                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6210                                userId);
6211                    }
6212                }
6213                scheduleStartProfilesLocked();
6214            }
6215        }
6216    }
6217
6218    @Override
6219    public void bootAnimationComplete() {
6220        final boolean callFinishBooting;
6221        synchronized (this) {
6222            callFinishBooting = mCallFinishBooting;
6223            mBootAnimationComplete = true;
6224        }
6225        if (callFinishBooting) {
6226            finishBooting();
6227        }
6228    }
6229
6230    @Override
6231    public void systemBackupRestored() {
6232        synchronized (this) {
6233            if (mSystemReady) {
6234                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6235            } else {
6236                Slog.w(TAG, "System backup restored before system is ready");
6237            }
6238        }
6239    }
6240
6241    final void ensureBootCompleted() {
6242        boolean booting;
6243        boolean enableScreen;
6244        synchronized (this) {
6245            booting = mBooting;
6246            mBooting = false;
6247            enableScreen = !mBooted;
6248            mBooted = true;
6249        }
6250
6251        if (booting) {
6252            finishBooting();
6253        }
6254
6255        if (enableScreen) {
6256            enableScreenAfterBoot();
6257        }
6258    }
6259
6260    @Override
6261    public final void activityResumed(IBinder token) {
6262        final long origId = Binder.clearCallingIdentity();
6263        synchronized(this) {
6264            ActivityStack stack = ActivityRecord.getStackLocked(token);
6265            if (stack != null) {
6266                ActivityRecord.activityResumedLocked(token);
6267            }
6268        }
6269        Binder.restoreCallingIdentity(origId);
6270    }
6271
6272    @Override
6273    public final void activityPaused(IBinder token) {
6274        final long origId = Binder.clearCallingIdentity();
6275        synchronized(this) {
6276            ActivityStack stack = ActivityRecord.getStackLocked(token);
6277            if (stack != null) {
6278                stack.activityPausedLocked(token, false);
6279            }
6280        }
6281        Binder.restoreCallingIdentity(origId);
6282    }
6283
6284    @Override
6285    public final void activityStopped(IBinder token, Bundle icicle,
6286            PersistableBundle persistentState, CharSequence description) {
6287        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6288
6289        // Refuse possible leaked file descriptors
6290        if (icicle != null && icicle.hasFileDescriptors()) {
6291            throw new IllegalArgumentException("File descriptors passed in Bundle");
6292        }
6293
6294        final long origId = Binder.clearCallingIdentity();
6295
6296        synchronized (this) {
6297            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6298            if (r != null) {
6299                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6300            }
6301        }
6302
6303        trimApplications();
6304
6305        Binder.restoreCallingIdentity(origId);
6306    }
6307
6308    @Override
6309    public final void activityDestroyed(IBinder token) {
6310        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6311        synchronized (this) {
6312            ActivityStack stack = ActivityRecord.getStackLocked(token);
6313            if (stack != null) {
6314                stack.activityDestroyedLocked(token);
6315            }
6316        }
6317    }
6318
6319    @Override
6320    public final void backgroundResourcesReleased(IBinder token) {
6321        final long origId = Binder.clearCallingIdentity();
6322        try {
6323            synchronized (this) {
6324                ActivityStack stack = ActivityRecord.getStackLocked(token);
6325                if (stack != null) {
6326                    stack.backgroundResourcesReleased();
6327                }
6328            }
6329        } finally {
6330            Binder.restoreCallingIdentity(origId);
6331        }
6332    }
6333
6334    @Override
6335    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6336        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6337    }
6338
6339    @Override
6340    public final void notifyEnterAnimationComplete(IBinder token) {
6341        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6342    }
6343
6344    @Override
6345    public String getCallingPackage(IBinder token) {
6346        synchronized (this) {
6347            ActivityRecord r = getCallingRecordLocked(token);
6348            return r != null ? r.info.packageName : null;
6349        }
6350    }
6351
6352    @Override
6353    public ComponentName getCallingActivity(IBinder token) {
6354        synchronized (this) {
6355            ActivityRecord r = getCallingRecordLocked(token);
6356            return r != null ? r.intent.getComponent() : null;
6357        }
6358    }
6359
6360    private ActivityRecord getCallingRecordLocked(IBinder token) {
6361        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6362        if (r == null) {
6363            return null;
6364        }
6365        return r.resultTo;
6366    }
6367
6368    @Override
6369    public ComponentName getActivityClassForToken(IBinder token) {
6370        synchronized(this) {
6371            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6372            if (r == null) {
6373                return null;
6374            }
6375            return r.intent.getComponent();
6376        }
6377    }
6378
6379    @Override
6380    public String getPackageForToken(IBinder token) {
6381        synchronized(this) {
6382            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6383            if (r == null) {
6384                return null;
6385            }
6386            return r.packageName;
6387        }
6388    }
6389
6390    @Override
6391    public IIntentSender getIntentSender(int type,
6392            String packageName, IBinder token, String resultWho,
6393            int requestCode, Intent[] intents, String[] resolvedTypes,
6394            int flags, Bundle options, int userId) {
6395        enforceNotIsolatedCaller("getIntentSender");
6396        // Refuse possible leaked file descriptors
6397        if (intents != null) {
6398            if (intents.length < 1) {
6399                throw new IllegalArgumentException("Intents array length must be >= 1");
6400            }
6401            for (int i=0; i<intents.length; i++) {
6402                Intent intent = intents[i];
6403                if (intent != null) {
6404                    if (intent.hasFileDescriptors()) {
6405                        throw new IllegalArgumentException("File descriptors passed in Intent");
6406                    }
6407                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6408                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6409                        throw new IllegalArgumentException(
6410                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6411                    }
6412                    intents[i] = new Intent(intent);
6413                }
6414            }
6415            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6416                throw new IllegalArgumentException(
6417                        "Intent array length does not match resolvedTypes length");
6418            }
6419        }
6420        if (options != null) {
6421            if (options.hasFileDescriptors()) {
6422                throw new IllegalArgumentException("File descriptors passed in options");
6423            }
6424        }
6425
6426        synchronized(this) {
6427            int callingUid = Binder.getCallingUid();
6428            int origUserId = userId;
6429            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6430                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6431                    ALLOW_NON_FULL, "getIntentSender", null);
6432            if (origUserId == UserHandle.USER_CURRENT) {
6433                // We don't want to evaluate this until the pending intent is
6434                // actually executed.  However, we do want to always do the
6435                // security checking for it above.
6436                userId = UserHandle.USER_CURRENT;
6437            }
6438            try {
6439                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6440                    int uid = AppGlobals.getPackageManager()
6441                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6442                    if (!UserHandle.isSameApp(callingUid, uid)) {
6443                        String msg = "Permission Denial: getIntentSender() from pid="
6444                            + Binder.getCallingPid()
6445                            + ", uid=" + Binder.getCallingUid()
6446                            + ", (need uid=" + uid + ")"
6447                            + " is not allowed to send as package " + packageName;
6448                        Slog.w(TAG, msg);
6449                        throw new SecurityException(msg);
6450                    }
6451                }
6452
6453                return getIntentSenderLocked(type, packageName, callingUid, userId,
6454                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6455
6456            } catch (RemoteException e) {
6457                throw new SecurityException(e);
6458            }
6459        }
6460    }
6461
6462    IIntentSender getIntentSenderLocked(int type, String packageName,
6463            int callingUid, int userId, IBinder token, String resultWho,
6464            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6465            Bundle options) {
6466        if (DEBUG_MU)
6467            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6468        ActivityRecord activity = null;
6469        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6470            activity = ActivityRecord.isInStackLocked(token);
6471            if (activity == null) {
6472                return null;
6473            }
6474            if (activity.finishing) {
6475                return null;
6476            }
6477        }
6478
6479        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6480        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6481        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6482        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6483                |PendingIntent.FLAG_UPDATE_CURRENT);
6484
6485        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6486                type, packageName, activity, resultWho,
6487                requestCode, intents, resolvedTypes, flags, options, userId);
6488        WeakReference<PendingIntentRecord> ref;
6489        ref = mIntentSenderRecords.get(key);
6490        PendingIntentRecord rec = ref != null ? ref.get() : null;
6491        if (rec != null) {
6492            if (!cancelCurrent) {
6493                if (updateCurrent) {
6494                    if (rec.key.requestIntent != null) {
6495                        rec.key.requestIntent.replaceExtras(intents != null ?
6496                                intents[intents.length - 1] : null);
6497                    }
6498                    if (intents != null) {
6499                        intents[intents.length-1] = rec.key.requestIntent;
6500                        rec.key.allIntents = intents;
6501                        rec.key.allResolvedTypes = resolvedTypes;
6502                    } else {
6503                        rec.key.allIntents = null;
6504                        rec.key.allResolvedTypes = null;
6505                    }
6506                }
6507                return rec;
6508            }
6509            rec.canceled = true;
6510            mIntentSenderRecords.remove(key);
6511        }
6512        if (noCreate) {
6513            return rec;
6514        }
6515        rec = new PendingIntentRecord(this, key, callingUid);
6516        mIntentSenderRecords.put(key, rec.ref);
6517        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6518            if (activity.pendingResults == null) {
6519                activity.pendingResults
6520                        = new HashSet<WeakReference<PendingIntentRecord>>();
6521            }
6522            activity.pendingResults.add(rec.ref);
6523        }
6524        return rec;
6525    }
6526
6527    @Override
6528    public void cancelIntentSender(IIntentSender sender) {
6529        if (!(sender instanceof PendingIntentRecord)) {
6530            return;
6531        }
6532        synchronized(this) {
6533            PendingIntentRecord rec = (PendingIntentRecord)sender;
6534            try {
6535                int uid = AppGlobals.getPackageManager()
6536                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6537                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6538                    String msg = "Permission Denial: cancelIntentSender() from pid="
6539                        + Binder.getCallingPid()
6540                        + ", uid=" + Binder.getCallingUid()
6541                        + " is not allowed to cancel packges "
6542                        + rec.key.packageName;
6543                    Slog.w(TAG, msg);
6544                    throw new SecurityException(msg);
6545                }
6546            } catch (RemoteException e) {
6547                throw new SecurityException(e);
6548            }
6549            cancelIntentSenderLocked(rec, true);
6550        }
6551    }
6552
6553    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6554        rec.canceled = true;
6555        mIntentSenderRecords.remove(rec.key);
6556        if (cleanActivity && rec.key.activity != null) {
6557            rec.key.activity.pendingResults.remove(rec.ref);
6558        }
6559    }
6560
6561    @Override
6562    public String getPackageForIntentSender(IIntentSender pendingResult) {
6563        if (!(pendingResult instanceof PendingIntentRecord)) {
6564            return null;
6565        }
6566        try {
6567            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6568            return res.key.packageName;
6569        } catch (ClassCastException e) {
6570        }
6571        return null;
6572    }
6573
6574    @Override
6575    public int getUidForIntentSender(IIntentSender sender) {
6576        if (sender instanceof PendingIntentRecord) {
6577            try {
6578                PendingIntentRecord res = (PendingIntentRecord)sender;
6579                return res.uid;
6580            } catch (ClassCastException e) {
6581            }
6582        }
6583        return -1;
6584    }
6585
6586    @Override
6587    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6588        if (!(pendingResult instanceof PendingIntentRecord)) {
6589            return false;
6590        }
6591        try {
6592            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6593            if (res.key.allIntents == null) {
6594                return false;
6595            }
6596            for (int i=0; i<res.key.allIntents.length; i++) {
6597                Intent intent = res.key.allIntents[i];
6598                if (intent.getPackage() != null && intent.getComponent() != null) {
6599                    return false;
6600                }
6601            }
6602            return true;
6603        } catch (ClassCastException e) {
6604        }
6605        return false;
6606    }
6607
6608    @Override
6609    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6610        if (!(pendingResult instanceof PendingIntentRecord)) {
6611            return false;
6612        }
6613        try {
6614            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6615            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6616                return true;
6617            }
6618            return false;
6619        } catch (ClassCastException e) {
6620        }
6621        return false;
6622    }
6623
6624    @Override
6625    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6626        if (!(pendingResult instanceof PendingIntentRecord)) {
6627            return null;
6628        }
6629        try {
6630            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6631            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6632        } catch (ClassCastException e) {
6633        }
6634        return null;
6635    }
6636
6637    @Override
6638    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6639        if (!(pendingResult instanceof PendingIntentRecord)) {
6640            return null;
6641        }
6642        try {
6643            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6644            Intent intent = res.key.requestIntent;
6645            if (intent != null) {
6646                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6647                        || res.lastTagPrefix.equals(prefix))) {
6648                    return res.lastTag;
6649                }
6650                res.lastTagPrefix = prefix;
6651                StringBuilder sb = new StringBuilder(128);
6652                if (prefix != null) {
6653                    sb.append(prefix);
6654                }
6655                if (intent.getAction() != null) {
6656                    sb.append(intent.getAction());
6657                } else if (intent.getComponent() != null) {
6658                    intent.getComponent().appendShortString(sb);
6659                } else {
6660                    sb.append("?");
6661                }
6662                return res.lastTag = sb.toString();
6663            }
6664        } catch (ClassCastException e) {
6665        }
6666        return null;
6667    }
6668
6669    @Override
6670    public void setProcessLimit(int max) {
6671        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6672                "setProcessLimit()");
6673        synchronized (this) {
6674            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6675            mProcessLimitOverride = max;
6676        }
6677        trimApplications();
6678    }
6679
6680    @Override
6681    public int getProcessLimit() {
6682        synchronized (this) {
6683            return mProcessLimitOverride;
6684        }
6685    }
6686
6687    void foregroundTokenDied(ForegroundToken token) {
6688        synchronized (ActivityManagerService.this) {
6689            synchronized (mPidsSelfLocked) {
6690                ForegroundToken cur
6691                    = mForegroundProcesses.get(token.pid);
6692                if (cur != token) {
6693                    return;
6694                }
6695                mForegroundProcesses.remove(token.pid);
6696                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6697                if (pr == null) {
6698                    return;
6699                }
6700                pr.forcingToForeground = null;
6701                updateProcessForegroundLocked(pr, false, false);
6702            }
6703            updateOomAdjLocked();
6704        }
6705    }
6706
6707    @Override
6708    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6709        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6710                "setProcessForeground()");
6711        synchronized(this) {
6712            boolean changed = false;
6713
6714            synchronized (mPidsSelfLocked) {
6715                ProcessRecord pr = mPidsSelfLocked.get(pid);
6716                if (pr == null && isForeground) {
6717                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6718                    return;
6719                }
6720                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6721                if (oldToken != null) {
6722                    oldToken.token.unlinkToDeath(oldToken, 0);
6723                    mForegroundProcesses.remove(pid);
6724                    if (pr != null) {
6725                        pr.forcingToForeground = null;
6726                    }
6727                    changed = true;
6728                }
6729                if (isForeground && token != null) {
6730                    ForegroundToken newToken = new ForegroundToken() {
6731                        @Override
6732                        public void binderDied() {
6733                            foregroundTokenDied(this);
6734                        }
6735                    };
6736                    newToken.pid = pid;
6737                    newToken.token = token;
6738                    try {
6739                        token.linkToDeath(newToken, 0);
6740                        mForegroundProcesses.put(pid, newToken);
6741                        pr.forcingToForeground = token;
6742                        changed = true;
6743                    } catch (RemoteException e) {
6744                        // If the process died while doing this, we will later
6745                        // do the cleanup with the process death link.
6746                    }
6747                }
6748            }
6749
6750            if (changed) {
6751                updateOomAdjLocked();
6752            }
6753        }
6754    }
6755
6756    // =========================================================
6757    // PERMISSIONS
6758    // =========================================================
6759
6760    static class PermissionController extends IPermissionController.Stub {
6761        ActivityManagerService mActivityManagerService;
6762        PermissionController(ActivityManagerService activityManagerService) {
6763            mActivityManagerService = activityManagerService;
6764        }
6765
6766        @Override
6767        public boolean checkPermission(String permission, int pid, int uid) {
6768            return mActivityManagerService.checkPermission(permission, pid,
6769                    uid) == PackageManager.PERMISSION_GRANTED;
6770        }
6771    }
6772
6773    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6774        @Override
6775        public int checkComponentPermission(String permission, int pid, int uid,
6776                int owningUid, boolean exported) {
6777            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6778                    owningUid, exported);
6779        }
6780
6781        @Override
6782        public Object getAMSLock() {
6783            return ActivityManagerService.this;
6784        }
6785    }
6786
6787    /**
6788     * This can be called with or without the global lock held.
6789     */
6790    int checkComponentPermission(String permission, int pid, int uid,
6791            int owningUid, boolean exported) {
6792        if (pid == MY_PID) {
6793            return PackageManager.PERMISSION_GRANTED;
6794        }
6795        return ActivityManager.checkComponentPermission(permission, uid,
6796                owningUid, exported);
6797    }
6798
6799    /**
6800     * As the only public entry point for permissions checking, this method
6801     * can enforce the semantic that requesting a check on a null global
6802     * permission is automatically denied.  (Internally a null permission
6803     * string is used when calling {@link #checkComponentPermission} in cases
6804     * when only uid-based security is needed.)
6805     *
6806     * This can be called with or without the global lock held.
6807     */
6808    @Override
6809    public int checkPermission(String permission, int pid, int uid) {
6810        if (permission == null) {
6811            return PackageManager.PERMISSION_DENIED;
6812        }
6813        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6814    }
6815
6816    @Override
6817    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6818        if (permission == null) {
6819            return PackageManager.PERMISSION_DENIED;
6820        }
6821
6822        // We might be performing an operation on behalf of an indirect binder
6823        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6824        // client identity accordingly before proceeding.
6825        Identity tlsIdentity = sCallerIdentity.get();
6826        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6827            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6828                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6829            uid = tlsIdentity.uid;
6830            pid = tlsIdentity.pid;
6831        }
6832
6833        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6834    }
6835
6836    /**
6837     * Binder IPC calls go through the public entry point.
6838     * This can be called with or without the global lock held.
6839     */
6840    int checkCallingPermission(String permission) {
6841        return checkPermission(permission,
6842                Binder.getCallingPid(),
6843                UserHandle.getAppId(Binder.getCallingUid()));
6844    }
6845
6846    /**
6847     * This can be called with or without the global lock held.
6848     */
6849    void enforceCallingPermission(String permission, String func) {
6850        if (checkCallingPermission(permission)
6851                == PackageManager.PERMISSION_GRANTED) {
6852            return;
6853        }
6854
6855        String msg = "Permission Denial: " + func + " from pid="
6856                + Binder.getCallingPid()
6857                + ", uid=" + Binder.getCallingUid()
6858                + " requires " + permission;
6859        Slog.w(TAG, msg);
6860        throw new SecurityException(msg);
6861    }
6862
6863    /**
6864     * Determine if UID is holding permissions required to access {@link Uri} in
6865     * the given {@link ProviderInfo}. Final permission checking is always done
6866     * in {@link ContentProvider}.
6867     */
6868    private final boolean checkHoldingPermissionsLocked(
6869            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6870        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6871                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6872        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6873            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6874                    != PERMISSION_GRANTED) {
6875                return false;
6876            }
6877        }
6878        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6879    }
6880
6881    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6882            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6883        if (pi.applicationInfo.uid == uid) {
6884            return true;
6885        } else if (!pi.exported) {
6886            return false;
6887        }
6888
6889        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6890        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6891        try {
6892            // check if target holds top-level <provider> permissions
6893            if (!readMet && pi.readPermission != null && considerUidPermissions
6894                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6895                readMet = true;
6896            }
6897            if (!writeMet && pi.writePermission != null && considerUidPermissions
6898                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6899                writeMet = true;
6900            }
6901
6902            // track if unprotected read/write is allowed; any denied
6903            // <path-permission> below removes this ability
6904            boolean allowDefaultRead = pi.readPermission == null;
6905            boolean allowDefaultWrite = pi.writePermission == null;
6906
6907            // check if target holds any <path-permission> that match uri
6908            final PathPermission[] pps = pi.pathPermissions;
6909            if (pps != null) {
6910                final String path = grantUri.uri.getPath();
6911                int i = pps.length;
6912                while (i > 0 && (!readMet || !writeMet)) {
6913                    i--;
6914                    PathPermission pp = pps[i];
6915                    if (pp.match(path)) {
6916                        if (!readMet) {
6917                            final String pprperm = pp.getReadPermission();
6918                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6919                                    + pprperm + " for " + pp.getPath()
6920                                    + ": match=" + pp.match(path)
6921                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6922                            if (pprperm != null) {
6923                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6924                                        == PERMISSION_GRANTED) {
6925                                    readMet = true;
6926                                } else {
6927                                    allowDefaultRead = false;
6928                                }
6929                            }
6930                        }
6931                        if (!writeMet) {
6932                            final String ppwperm = pp.getWritePermission();
6933                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6934                                    + ppwperm + " for " + pp.getPath()
6935                                    + ": match=" + pp.match(path)
6936                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6937                            if (ppwperm != null) {
6938                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6939                                        == PERMISSION_GRANTED) {
6940                                    writeMet = true;
6941                                } else {
6942                                    allowDefaultWrite = false;
6943                                }
6944                            }
6945                        }
6946                    }
6947                }
6948            }
6949
6950            // grant unprotected <provider> read/write, if not blocked by
6951            // <path-permission> above
6952            if (allowDefaultRead) readMet = true;
6953            if (allowDefaultWrite) writeMet = true;
6954
6955        } catch (RemoteException e) {
6956            return false;
6957        }
6958
6959        return readMet && writeMet;
6960    }
6961
6962    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6963        ProviderInfo pi = null;
6964        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6965        if (cpr != null) {
6966            pi = cpr.info;
6967        } else {
6968            try {
6969                pi = AppGlobals.getPackageManager().resolveContentProvider(
6970                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6971            } catch (RemoteException ex) {
6972            }
6973        }
6974        return pi;
6975    }
6976
6977    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6978        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6979        if (targetUris != null) {
6980            return targetUris.get(grantUri);
6981        }
6982        return null;
6983    }
6984
6985    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6986            String targetPkg, int targetUid, GrantUri grantUri) {
6987        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6988        if (targetUris == null) {
6989            targetUris = Maps.newArrayMap();
6990            mGrantedUriPermissions.put(targetUid, targetUris);
6991        }
6992
6993        UriPermission perm = targetUris.get(grantUri);
6994        if (perm == null) {
6995            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6996            targetUris.put(grantUri, perm);
6997        }
6998
6999        return perm;
7000    }
7001
7002    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7003            final int modeFlags) {
7004        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7005        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7006                : UriPermission.STRENGTH_OWNED;
7007
7008        // Root gets to do everything.
7009        if (uid == 0) {
7010            return true;
7011        }
7012
7013        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7014        if (perms == null) return false;
7015
7016        // First look for exact match
7017        final UriPermission exactPerm = perms.get(grantUri);
7018        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7019            return true;
7020        }
7021
7022        // No exact match, look for prefixes
7023        final int N = perms.size();
7024        for (int i = 0; i < N; i++) {
7025            final UriPermission perm = perms.valueAt(i);
7026            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7027                    && perm.getStrength(modeFlags) >= minStrength) {
7028                return true;
7029            }
7030        }
7031
7032        return false;
7033    }
7034
7035    /**
7036     * @param uri This uri must NOT contain an embedded userId.
7037     * @param userId The userId in which the uri is to be resolved.
7038     */
7039    @Override
7040    public int checkUriPermission(Uri uri, int pid, int uid,
7041            final int modeFlags, int userId, IBinder callerToken) {
7042        enforceNotIsolatedCaller("checkUriPermission");
7043
7044        // Another redirected-binder-call permissions check as in
7045        // {@link checkPermissionWithToken}.
7046        Identity tlsIdentity = sCallerIdentity.get();
7047        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7048            uid = tlsIdentity.uid;
7049            pid = tlsIdentity.pid;
7050        }
7051
7052        // Our own process gets to do everything.
7053        if (pid == MY_PID) {
7054            return PackageManager.PERMISSION_GRANTED;
7055        }
7056        synchronized (this) {
7057            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7058                    ? PackageManager.PERMISSION_GRANTED
7059                    : PackageManager.PERMISSION_DENIED;
7060        }
7061    }
7062
7063    /**
7064     * Check if the targetPkg can be granted permission to access uri by
7065     * the callingUid using the given modeFlags.  Throws a security exception
7066     * if callingUid is not allowed to do this.  Returns the uid of the target
7067     * if the URI permission grant should be performed; returns -1 if it is not
7068     * needed (for example targetPkg already has permission to access the URI).
7069     * If you already know the uid of the target, you can supply it in
7070     * lastTargetUid else set that to -1.
7071     */
7072    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7073            final int modeFlags, int lastTargetUid) {
7074        if (!Intent.isAccessUriMode(modeFlags)) {
7075            return -1;
7076        }
7077
7078        if (targetPkg != null) {
7079            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7080                    "Checking grant " + targetPkg + " permission to " + grantUri);
7081        }
7082
7083        final IPackageManager pm = AppGlobals.getPackageManager();
7084
7085        // If this is not a content: uri, we can't do anything with it.
7086        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7087            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7088                    "Can't grant URI permission for non-content URI: " + grantUri);
7089            return -1;
7090        }
7091
7092        final String authority = grantUri.uri.getAuthority();
7093        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7094        if (pi == null) {
7095            Slog.w(TAG, "No content provider found for permission check: " +
7096                    grantUri.uri.toSafeString());
7097            return -1;
7098        }
7099
7100        int targetUid = lastTargetUid;
7101        if (targetUid < 0 && targetPkg != null) {
7102            try {
7103                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7104                if (targetUid < 0) {
7105                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7106                            "Can't grant URI permission no uid for: " + targetPkg);
7107                    return -1;
7108                }
7109            } catch (RemoteException ex) {
7110                return -1;
7111            }
7112        }
7113
7114        if (targetUid >= 0) {
7115            // First...  does the target actually need this permission?
7116            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7117                // No need to grant the target this permission.
7118                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7119                        "Target " + targetPkg + " already has full permission to " + grantUri);
7120                return -1;
7121            }
7122        } else {
7123            // First...  there is no target package, so can anyone access it?
7124            boolean allowed = pi.exported;
7125            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7126                if (pi.readPermission != null) {
7127                    allowed = false;
7128                }
7129            }
7130            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7131                if (pi.writePermission != null) {
7132                    allowed = false;
7133                }
7134            }
7135            if (allowed) {
7136                return -1;
7137            }
7138        }
7139
7140        /* There is a special cross user grant if:
7141         * - The target is on another user.
7142         * - Apps on the current user can access the uri without any uid permissions.
7143         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7144         * grant uri permissions.
7145         */
7146        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7147                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7148                modeFlags, false /*without considering the uid permissions*/);
7149
7150        // Second...  is the provider allowing granting of URI permissions?
7151        if (!specialCrossUserGrant) {
7152            if (!pi.grantUriPermissions) {
7153                throw new SecurityException("Provider " + pi.packageName
7154                        + "/" + pi.name
7155                        + " does not allow granting of Uri permissions (uri "
7156                        + grantUri + ")");
7157            }
7158            if (pi.uriPermissionPatterns != null) {
7159                final int N = pi.uriPermissionPatterns.length;
7160                boolean allowed = false;
7161                for (int i=0; i<N; i++) {
7162                    if (pi.uriPermissionPatterns[i] != null
7163                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7164                        allowed = true;
7165                        break;
7166                    }
7167                }
7168                if (!allowed) {
7169                    throw new SecurityException("Provider " + pi.packageName
7170                            + "/" + pi.name
7171                            + " does not allow granting of permission to path of Uri "
7172                            + grantUri);
7173                }
7174            }
7175        }
7176
7177        // Third...  does the caller itself have permission to access
7178        // this uri?
7179        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7180            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7181                // Require they hold a strong enough Uri permission
7182                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7183                    throw new SecurityException("Uid " + callingUid
7184                            + " does not have permission to uri " + grantUri);
7185                }
7186            }
7187        }
7188        return targetUid;
7189    }
7190
7191    /**
7192     * @param uri This uri must NOT contain an embedded userId.
7193     * @param userId The userId in which the uri is to be resolved.
7194     */
7195    @Override
7196    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7197            final int modeFlags, int userId) {
7198        enforceNotIsolatedCaller("checkGrantUriPermission");
7199        synchronized(this) {
7200            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7201                    new GrantUri(userId, uri, false), modeFlags, -1);
7202        }
7203    }
7204
7205    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7206            final int modeFlags, UriPermissionOwner owner) {
7207        if (!Intent.isAccessUriMode(modeFlags)) {
7208            return;
7209        }
7210
7211        // So here we are: the caller has the assumed permission
7212        // to the uri, and the target doesn't.  Let's now give this to
7213        // the target.
7214
7215        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7216                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7217
7218        final String authority = grantUri.uri.getAuthority();
7219        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7220        if (pi == null) {
7221            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7222            return;
7223        }
7224
7225        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7226            grantUri.prefix = true;
7227        }
7228        final UriPermission perm = findOrCreateUriPermissionLocked(
7229                pi.packageName, targetPkg, targetUid, grantUri);
7230        perm.grantModes(modeFlags, owner);
7231    }
7232
7233    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7234            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7235        if (targetPkg == null) {
7236            throw new NullPointerException("targetPkg");
7237        }
7238        int targetUid;
7239        final IPackageManager pm = AppGlobals.getPackageManager();
7240        try {
7241            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7242        } catch (RemoteException ex) {
7243            return;
7244        }
7245
7246        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7247                targetUid);
7248        if (targetUid < 0) {
7249            return;
7250        }
7251
7252        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7253                owner);
7254    }
7255
7256    static class NeededUriGrants extends ArrayList<GrantUri> {
7257        final String targetPkg;
7258        final int targetUid;
7259        final int flags;
7260
7261        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7262            this.targetPkg = targetPkg;
7263            this.targetUid = targetUid;
7264            this.flags = flags;
7265        }
7266    }
7267
7268    /**
7269     * Like checkGrantUriPermissionLocked, but takes an Intent.
7270     */
7271    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7272            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7273        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7274                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7275                + " clip=" + (intent != null ? intent.getClipData() : null)
7276                + " from " + intent + "; flags=0x"
7277                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7278
7279        if (targetPkg == null) {
7280            throw new NullPointerException("targetPkg");
7281        }
7282
7283        if (intent == null) {
7284            return null;
7285        }
7286        Uri data = intent.getData();
7287        ClipData clip = intent.getClipData();
7288        if (data == null && clip == null) {
7289            return null;
7290        }
7291        // Default userId for uris in the intent (if they don't specify it themselves)
7292        int contentUserHint = intent.getContentUserHint();
7293        if (contentUserHint == UserHandle.USER_CURRENT) {
7294            contentUserHint = UserHandle.getUserId(callingUid);
7295        }
7296        final IPackageManager pm = AppGlobals.getPackageManager();
7297        int targetUid;
7298        if (needed != null) {
7299            targetUid = needed.targetUid;
7300        } else {
7301            try {
7302                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7303            } catch (RemoteException ex) {
7304                return null;
7305            }
7306            if (targetUid < 0) {
7307                if (DEBUG_URI_PERMISSION) {
7308                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7309                            + " on user " + targetUserId);
7310                }
7311                return null;
7312            }
7313        }
7314        if (data != null) {
7315            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7316            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7317                    targetUid);
7318            if (targetUid > 0) {
7319                if (needed == null) {
7320                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7321                }
7322                needed.add(grantUri);
7323            }
7324        }
7325        if (clip != null) {
7326            for (int i=0; i<clip.getItemCount(); i++) {
7327                Uri uri = clip.getItemAt(i).getUri();
7328                if (uri != null) {
7329                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7330                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7331                            targetUid);
7332                    if (targetUid > 0) {
7333                        if (needed == null) {
7334                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7335                        }
7336                        needed.add(grantUri);
7337                    }
7338                } else {
7339                    Intent clipIntent = clip.getItemAt(i).getIntent();
7340                    if (clipIntent != null) {
7341                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7342                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7343                        if (newNeeded != null) {
7344                            needed = newNeeded;
7345                        }
7346                    }
7347                }
7348            }
7349        }
7350
7351        return needed;
7352    }
7353
7354    /**
7355     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7356     */
7357    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7358            UriPermissionOwner owner) {
7359        if (needed != null) {
7360            for (int i=0; i<needed.size(); i++) {
7361                GrantUri grantUri = needed.get(i);
7362                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7363                        grantUri, needed.flags, owner);
7364            }
7365        }
7366    }
7367
7368    void grantUriPermissionFromIntentLocked(int callingUid,
7369            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7370        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7371                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7372        if (needed == null) {
7373            return;
7374        }
7375
7376        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7377    }
7378
7379    /**
7380     * @param uri This uri must NOT contain an embedded userId.
7381     * @param userId The userId in which the uri is to be resolved.
7382     */
7383    @Override
7384    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7385            final int modeFlags, int userId) {
7386        enforceNotIsolatedCaller("grantUriPermission");
7387        GrantUri grantUri = new GrantUri(userId, uri, false);
7388        synchronized(this) {
7389            final ProcessRecord r = getRecordForAppLocked(caller);
7390            if (r == null) {
7391                throw new SecurityException("Unable to find app for caller "
7392                        + caller
7393                        + " when granting permission to uri " + grantUri);
7394            }
7395            if (targetPkg == null) {
7396                throw new IllegalArgumentException("null target");
7397            }
7398            if (grantUri == null) {
7399                throw new IllegalArgumentException("null uri");
7400            }
7401
7402            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7403                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7404                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7405                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7406
7407            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7408                    UserHandle.getUserId(r.uid));
7409        }
7410    }
7411
7412    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7413        if (perm.modeFlags == 0) {
7414            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7415                    perm.targetUid);
7416            if (perms != null) {
7417                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7418                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7419
7420                perms.remove(perm.uri);
7421                if (perms.isEmpty()) {
7422                    mGrantedUriPermissions.remove(perm.targetUid);
7423                }
7424            }
7425        }
7426    }
7427
7428    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7429        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7430
7431        final IPackageManager pm = AppGlobals.getPackageManager();
7432        final String authority = grantUri.uri.getAuthority();
7433        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7434        if (pi == null) {
7435            Slog.w(TAG, "No content provider found for permission revoke: "
7436                    + grantUri.toSafeString());
7437            return;
7438        }
7439
7440        // Does the caller have this permission on the URI?
7441        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7442            // If they don't have direct access to the URI, then revoke any
7443            // ownerless URI permissions that have been granted to them.
7444            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7445            if (perms != null) {
7446                boolean persistChanged = false;
7447                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7448                    final UriPermission perm = it.next();
7449                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7450                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7451                        if (DEBUG_URI_PERMISSION)
7452                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7453                                    " permission to " + perm.uri);
7454                        persistChanged |= perm.revokeModes(
7455                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7456                        if (perm.modeFlags == 0) {
7457                            it.remove();
7458                        }
7459                    }
7460                }
7461                if (perms.isEmpty()) {
7462                    mGrantedUriPermissions.remove(callingUid);
7463                }
7464                if (persistChanged) {
7465                    schedulePersistUriGrants();
7466                }
7467            }
7468            return;
7469        }
7470
7471        boolean persistChanged = false;
7472
7473        // Go through all of the permissions and remove any that match.
7474        int N = mGrantedUriPermissions.size();
7475        for (int i = 0; i < N; i++) {
7476            final int targetUid = mGrantedUriPermissions.keyAt(i);
7477            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7478
7479            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7480                final UriPermission perm = it.next();
7481                if (perm.uri.sourceUserId == grantUri.sourceUserId
7482                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7483                    if (DEBUG_URI_PERMISSION)
7484                        Slog.v(TAG,
7485                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7486                    persistChanged |= perm.revokeModes(
7487                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7488                    if (perm.modeFlags == 0) {
7489                        it.remove();
7490                    }
7491                }
7492            }
7493
7494            if (perms.isEmpty()) {
7495                mGrantedUriPermissions.remove(targetUid);
7496                N--;
7497                i--;
7498            }
7499        }
7500
7501        if (persistChanged) {
7502            schedulePersistUriGrants();
7503        }
7504    }
7505
7506    /**
7507     * @param uri This uri must NOT contain an embedded userId.
7508     * @param userId The userId in which the uri is to be resolved.
7509     */
7510    @Override
7511    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7512            int userId) {
7513        enforceNotIsolatedCaller("revokeUriPermission");
7514        synchronized(this) {
7515            final ProcessRecord r = getRecordForAppLocked(caller);
7516            if (r == null) {
7517                throw new SecurityException("Unable to find app for caller "
7518                        + caller
7519                        + " when revoking permission to uri " + uri);
7520            }
7521            if (uri == null) {
7522                Slog.w(TAG, "revokeUriPermission: null uri");
7523                return;
7524            }
7525
7526            if (!Intent.isAccessUriMode(modeFlags)) {
7527                return;
7528            }
7529
7530            final IPackageManager pm = AppGlobals.getPackageManager();
7531            final String authority = uri.getAuthority();
7532            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7533            if (pi == null) {
7534                Slog.w(TAG, "No content provider found for permission revoke: "
7535                        + uri.toSafeString());
7536                return;
7537            }
7538
7539            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7540        }
7541    }
7542
7543    /**
7544     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7545     * given package.
7546     *
7547     * @param packageName Package name to match, or {@code null} to apply to all
7548     *            packages.
7549     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7550     *            to all users.
7551     * @param persistable If persistable grants should be removed.
7552     */
7553    private void removeUriPermissionsForPackageLocked(
7554            String packageName, int userHandle, boolean persistable) {
7555        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7556            throw new IllegalArgumentException("Must narrow by either package or user");
7557        }
7558
7559        boolean persistChanged = false;
7560
7561        int N = mGrantedUriPermissions.size();
7562        for (int i = 0; i < N; i++) {
7563            final int targetUid = mGrantedUriPermissions.keyAt(i);
7564            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7565
7566            // Only inspect grants matching user
7567            if (userHandle == UserHandle.USER_ALL
7568                    || userHandle == UserHandle.getUserId(targetUid)) {
7569                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7570                    final UriPermission perm = it.next();
7571
7572                    // Only inspect grants matching package
7573                    if (packageName == null || perm.sourcePkg.equals(packageName)
7574                            || perm.targetPkg.equals(packageName)) {
7575                        persistChanged |= perm.revokeModes(persistable
7576                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7577
7578                        // Only remove when no modes remain; any persisted grants
7579                        // will keep this alive.
7580                        if (perm.modeFlags == 0) {
7581                            it.remove();
7582                        }
7583                    }
7584                }
7585
7586                if (perms.isEmpty()) {
7587                    mGrantedUriPermissions.remove(targetUid);
7588                    N--;
7589                    i--;
7590                }
7591            }
7592        }
7593
7594        if (persistChanged) {
7595            schedulePersistUriGrants();
7596        }
7597    }
7598
7599    @Override
7600    public IBinder newUriPermissionOwner(String name) {
7601        enforceNotIsolatedCaller("newUriPermissionOwner");
7602        synchronized(this) {
7603            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7604            return owner.getExternalTokenLocked();
7605        }
7606    }
7607
7608    /**
7609     * @param uri This uri must NOT contain an embedded userId.
7610     * @param sourceUserId The userId in which the uri is to be resolved.
7611     * @param targetUserId The userId of the app that receives the grant.
7612     */
7613    @Override
7614    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7615            final int modeFlags, int sourceUserId, int targetUserId) {
7616        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7617                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7618        synchronized(this) {
7619            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7620            if (owner == null) {
7621                throw new IllegalArgumentException("Unknown owner: " + token);
7622            }
7623            if (fromUid != Binder.getCallingUid()) {
7624                if (Binder.getCallingUid() != Process.myUid()) {
7625                    // Only system code can grant URI permissions on behalf
7626                    // of other users.
7627                    throw new SecurityException("nice try");
7628                }
7629            }
7630            if (targetPkg == null) {
7631                throw new IllegalArgumentException("null target");
7632            }
7633            if (uri == null) {
7634                throw new IllegalArgumentException("null uri");
7635            }
7636
7637            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7638                    modeFlags, owner, targetUserId);
7639        }
7640    }
7641
7642    /**
7643     * @param uri This uri must NOT contain an embedded userId.
7644     * @param userId The userId in which the uri is to be resolved.
7645     */
7646    @Override
7647    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7648        synchronized(this) {
7649            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7650            if (owner == null) {
7651                throw new IllegalArgumentException("Unknown owner: " + token);
7652            }
7653
7654            if (uri == null) {
7655                owner.removeUriPermissionsLocked(mode);
7656            } else {
7657                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7658            }
7659        }
7660    }
7661
7662    private void schedulePersistUriGrants() {
7663        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7664            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7665                    10 * DateUtils.SECOND_IN_MILLIS);
7666        }
7667    }
7668
7669    private void writeGrantedUriPermissions() {
7670        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7671
7672        // Snapshot permissions so we can persist without lock
7673        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7674        synchronized (this) {
7675            final int size = mGrantedUriPermissions.size();
7676            for (int i = 0; i < size; i++) {
7677                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7678                for (UriPermission perm : perms.values()) {
7679                    if (perm.persistedModeFlags != 0) {
7680                        persist.add(perm.snapshot());
7681                    }
7682                }
7683            }
7684        }
7685
7686        FileOutputStream fos = null;
7687        try {
7688            fos = mGrantFile.startWrite();
7689
7690            XmlSerializer out = new FastXmlSerializer();
7691            out.setOutput(fos, "utf-8");
7692            out.startDocument(null, true);
7693            out.startTag(null, TAG_URI_GRANTS);
7694            for (UriPermission.Snapshot perm : persist) {
7695                out.startTag(null, TAG_URI_GRANT);
7696                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7697                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7698                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7699                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7700                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7701                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7702                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7703                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7704                out.endTag(null, TAG_URI_GRANT);
7705            }
7706            out.endTag(null, TAG_URI_GRANTS);
7707            out.endDocument();
7708
7709            mGrantFile.finishWrite(fos);
7710        } catch (IOException e) {
7711            if (fos != null) {
7712                mGrantFile.failWrite(fos);
7713            }
7714        }
7715    }
7716
7717    private void readGrantedUriPermissionsLocked() {
7718        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7719
7720        final long now = System.currentTimeMillis();
7721
7722        FileInputStream fis = null;
7723        try {
7724            fis = mGrantFile.openRead();
7725            final XmlPullParser in = Xml.newPullParser();
7726            in.setInput(fis, null);
7727
7728            int type;
7729            while ((type = in.next()) != END_DOCUMENT) {
7730                final String tag = in.getName();
7731                if (type == START_TAG) {
7732                    if (TAG_URI_GRANT.equals(tag)) {
7733                        final int sourceUserId;
7734                        final int targetUserId;
7735                        final int userHandle = readIntAttribute(in,
7736                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7737                        if (userHandle != UserHandle.USER_NULL) {
7738                            // For backwards compatibility.
7739                            sourceUserId = userHandle;
7740                            targetUserId = userHandle;
7741                        } else {
7742                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7743                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7744                        }
7745                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7746                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7747                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7748                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7749                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7750                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7751
7752                        // Sanity check that provider still belongs to source package
7753                        final ProviderInfo pi = getProviderInfoLocked(
7754                                uri.getAuthority(), sourceUserId);
7755                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7756                            int targetUid = -1;
7757                            try {
7758                                targetUid = AppGlobals.getPackageManager()
7759                                        .getPackageUid(targetPkg, targetUserId);
7760                            } catch (RemoteException e) {
7761                            }
7762                            if (targetUid != -1) {
7763                                final UriPermission perm = findOrCreateUriPermissionLocked(
7764                                        sourcePkg, targetPkg, targetUid,
7765                                        new GrantUri(sourceUserId, uri, prefix));
7766                                perm.initPersistedModes(modeFlags, createdTime);
7767                            }
7768                        } else {
7769                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7770                                    + " but instead found " + pi);
7771                        }
7772                    }
7773                }
7774            }
7775        } catch (FileNotFoundException e) {
7776            // Missing grants is okay
7777        } catch (IOException e) {
7778            Slog.wtf(TAG, "Failed reading Uri grants", e);
7779        } catch (XmlPullParserException e) {
7780            Slog.wtf(TAG, "Failed reading Uri grants", e);
7781        } finally {
7782            IoUtils.closeQuietly(fis);
7783        }
7784    }
7785
7786    /**
7787     * @param uri This uri must NOT contain an embedded userId.
7788     * @param userId The userId in which the uri is to be resolved.
7789     */
7790    @Override
7791    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7792        enforceNotIsolatedCaller("takePersistableUriPermission");
7793
7794        Preconditions.checkFlagsArgument(modeFlags,
7795                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7796
7797        synchronized (this) {
7798            final int callingUid = Binder.getCallingUid();
7799            boolean persistChanged = false;
7800            GrantUri grantUri = new GrantUri(userId, uri, false);
7801
7802            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7803                    new GrantUri(userId, uri, false));
7804            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7805                    new GrantUri(userId, uri, true));
7806
7807            final boolean exactValid = (exactPerm != null)
7808                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7809            final boolean prefixValid = (prefixPerm != null)
7810                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7811
7812            if (!(exactValid || prefixValid)) {
7813                throw new SecurityException("No persistable permission grants found for UID "
7814                        + callingUid + " and Uri " + grantUri.toSafeString());
7815            }
7816
7817            if (exactValid) {
7818                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7819            }
7820            if (prefixValid) {
7821                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7822            }
7823
7824            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7825
7826            if (persistChanged) {
7827                schedulePersistUriGrants();
7828            }
7829        }
7830    }
7831
7832    /**
7833     * @param uri This uri must NOT contain an embedded userId.
7834     * @param userId The userId in which the uri is to be resolved.
7835     */
7836    @Override
7837    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7838        enforceNotIsolatedCaller("releasePersistableUriPermission");
7839
7840        Preconditions.checkFlagsArgument(modeFlags,
7841                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7842
7843        synchronized (this) {
7844            final int callingUid = Binder.getCallingUid();
7845            boolean persistChanged = false;
7846
7847            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7848                    new GrantUri(userId, uri, false));
7849            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7850                    new GrantUri(userId, uri, true));
7851            if (exactPerm == null && prefixPerm == null) {
7852                throw new SecurityException("No permission grants found for UID " + callingUid
7853                        + " and Uri " + uri.toSafeString());
7854            }
7855
7856            if (exactPerm != null) {
7857                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7858                removeUriPermissionIfNeededLocked(exactPerm);
7859            }
7860            if (prefixPerm != null) {
7861                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7862                removeUriPermissionIfNeededLocked(prefixPerm);
7863            }
7864
7865            if (persistChanged) {
7866                schedulePersistUriGrants();
7867            }
7868        }
7869    }
7870
7871    /**
7872     * Prune any older {@link UriPermission} for the given UID until outstanding
7873     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7874     *
7875     * @return if any mutations occured that require persisting.
7876     */
7877    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7878        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7879        if (perms == null) return false;
7880        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7881
7882        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7883        for (UriPermission perm : perms.values()) {
7884            if (perm.persistedModeFlags != 0) {
7885                persisted.add(perm);
7886            }
7887        }
7888
7889        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7890        if (trimCount <= 0) return false;
7891
7892        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7893        for (int i = 0; i < trimCount; i++) {
7894            final UriPermission perm = persisted.get(i);
7895
7896            if (DEBUG_URI_PERMISSION) {
7897                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7898            }
7899
7900            perm.releasePersistableModes(~0);
7901            removeUriPermissionIfNeededLocked(perm);
7902        }
7903
7904        return true;
7905    }
7906
7907    @Override
7908    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7909            String packageName, boolean incoming) {
7910        enforceNotIsolatedCaller("getPersistedUriPermissions");
7911        Preconditions.checkNotNull(packageName, "packageName");
7912
7913        final int callingUid = Binder.getCallingUid();
7914        final IPackageManager pm = AppGlobals.getPackageManager();
7915        try {
7916            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7917            if (packageUid != callingUid) {
7918                throw new SecurityException(
7919                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7920            }
7921        } catch (RemoteException e) {
7922            throw new SecurityException("Failed to verify package name ownership");
7923        }
7924
7925        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7926        synchronized (this) {
7927            if (incoming) {
7928                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7929                        callingUid);
7930                if (perms == null) {
7931                    Slog.w(TAG, "No permission grants found for " + packageName);
7932                } else {
7933                    for (UriPermission perm : perms.values()) {
7934                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7935                            result.add(perm.buildPersistedPublicApiObject());
7936                        }
7937                    }
7938                }
7939            } else {
7940                final int size = mGrantedUriPermissions.size();
7941                for (int i = 0; i < size; i++) {
7942                    final ArrayMap<GrantUri, UriPermission> perms =
7943                            mGrantedUriPermissions.valueAt(i);
7944                    for (UriPermission perm : perms.values()) {
7945                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7946                            result.add(perm.buildPersistedPublicApiObject());
7947                        }
7948                    }
7949                }
7950            }
7951        }
7952        return new ParceledListSlice<android.content.UriPermission>(result);
7953    }
7954
7955    @Override
7956    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7957        synchronized (this) {
7958            ProcessRecord app =
7959                who != null ? getRecordForAppLocked(who) : null;
7960            if (app == null) return;
7961
7962            Message msg = Message.obtain();
7963            msg.what = WAIT_FOR_DEBUGGER_MSG;
7964            msg.obj = app;
7965            msg.arg1 = waiting ? 1 : 0;
7966            mHandler.sendMessage(msg);
7967        }
7968    }
7969
7970    @Override
7971    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7972        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7973        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7974        outInfo.availMem = Process.getFreeMemory();
7975        outInfo.totalMem = Process.getTotalMemory();
7976        outInfo.threshold = homeAppMem;
7977        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7978        outInfo.hiddenAppThreshold = cachedAppMem;
7979        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7980                ProcessList.SERVICE_ADJ);
7981        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7982                ProcessList.VISIBLE_APP_ADJ);
7983        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7984                ProcessList.FOREGROUND_APP_ADJ);
7985    }
7986
7987    // =========================================================
7988    // TASK MANAGEMENT
7989    // =========================================================
7990
7991    @Override
7992    public List<IAppTask> getAppTasks(String callingPackage) {
7993        int callingUid = Binder.getCallingUid();
7994        long ident = Binder.clearCallingIdentity();
7995
7996        synchronized(this) {
7997            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7998            try {
7999                if (localLOGV) Slog.v(TAG, "getAppTasks");
8000
8001                final int N = mRecentTasks.size();
8002                for (int i = 0; i < N; i++) {
8003                    TaskRecord tr = mRecentTasks.get(i);
8004                    // Skip tasks that do not match the caller.  We don't need to verify
8005                    // callingPackage, because we are also limiting to callingUid and know
8006                    // that will limit to the correct security sandbox.
8007                    if (tr.effectiveUid != callingUid) {
8008                        continue;
8009                    }
8010                    Intent intent = tr.getBaseIntent();
8011                    if (intent == null ||
8012                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8013                        continue;
8014                    }
8015                    ActivityManager.RecentTaskInfo taskInfo =
8016                            createRecentTaskInfoFromTaskRecord(tr);
8017                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8018                    list.add(taskImpl);
8019                }
8020            } finally {
8021                Binder.restoreCallingIdentity(ident);
8022            }
8023            return list;
8024        }
8025    }
8026
8027    @Override
8028    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8029        final int callingUid = Binder.getCallingUid();
8030        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8031
8032        synchronized(this) {
8033            if (localLOGV) Slog.v(
8034                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8035
8036            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8037                    callingUid);
8038
8039            // TODO: Improve with MRU list from all ActivityStacks.
8040            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8041        }
8042
8043        return list;
8044    }
8045
8046    /**
8047     * Creates a new RecentTaskInfo from a TaskRecord.
8048     */
8049    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8050        // Update the task description to reflect any changes in the task stack
8051        tr.updateTaskDescription();
8052
8053        // Compose the recent task info
8054        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8055        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8056        rti.persistentId = tr.taskId;
8057        rti.baseIntent = new Intent(tr.getBaseIntent());
8058        rti.origActivity = tr.origActivity;
8059        rti.description = tr.lastDescription;
8060        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8061        rti.userId = tr.userId;
8062        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8063        rti.firstActiveTime = tr.firstActiveTime;
8064        rti.lastActiveTime = tr.lastActiveTime;
8065        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8066        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8067        return rti;
8068    }
8069
8070    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8071        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8072                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8073        if (!allowed) {
8074            if (checkPermission(android.Manifest.permission.GET_TASKS,
8075                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8076                // Temporary compatibility: some existing apps on the system image may
8077                // still be requesting the old permission and not switched to the new
8078                // one; if so, we'll still allow them full access.  This means we need
8079                // to see if they are holding the old permission and are a system app.
8080                try {
8081                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8082                        allowed = true;
8083                        Slog.w(TAG, caller + ": caller " + callingUid
8084                                + " is using old GET_TASKS but privileged; allowing");
8085                    }
8086                } catch (RemoteException e) {
8087                }
8088            }
8089        }
8090        if (!allowed) {
8091            Slog.w(TAG, caller + ": caller " + callingUid
8092                    + " does not hold GET_TASKS; limiting output");
8093        }
8094        return allowed;
8095    }
8096
8097    @Override
8098    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8099        final int callingUid = Binder.getCallingUid();
8100        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8101                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8102
8103        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8104        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8105        synchronized (this) {
8106            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8107                    callingUid);
8108            final boolean detailed = checkCallingPermission(
8109                    android.Manifest.permission.GET_DETAILED_TASKS)
8110                    == PackageManager.PERMISSION_GRANTED;
8111
8112            final int N = mRecentTasks.size();
8113            ArrayList<ActivityManager.RecentTaskInfo> res
8114                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8115                            maxNum < N ? maxNum : N);
8116
8117            final Set<Integer> includedUsers;
8118            if (includeProfiles) {
8119                includedUsers = getProfileIdsLocked(userId);
8120            } else {
8121                includedUsers = new HashSet<Integer>();
8122            }
8123            includedUsers.add(Integer.valueOf(userId));
8124
8125            for (int i=0; i<N && maxNum > 0; i++) {
8126                TaskRecord tr = mRecentTasks.get(i);
8127                // Only add calling user or related users recent tasks
8128                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8129                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8130                    continue;
8131                }
8132
8133                // Return the entry if desired by the caller.  We always return
8134                // the first entry, because callers always expect this to be the
8135                // foreground app.  We may filter others if the caller has
8136                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8137                // we should exclude the entry.
8138
8139                if (i == 0
8140                        || withExcluded
8141                        || (tr.intent == null)
8142                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8143                                == 0)) {
8144                    if (!allowed) {
8145                        // If the caller doesn't have the GET_TASKS permission, then only
8146                        // allow them to see a small subset of tasks -- their own and home.
8147                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8148                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8149                            continue;
8150                        }
8151                    }
8152                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8153                        if (tr.stack != null && tr.stack.isHomeStack()) {
8154                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8155                            continue;
8156                        }
8157                    }
8158                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8159                        // Don't include auto remove tasks that are finished or finishing.
8160                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8161                                + tr);
8162                        continue;
8163                    }
8164                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8165                            && !tr.isAvailable) {
8166                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8167                        continue;
8168                    }
8169
8170                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8171                    if (!detailed) {
8172                        rti.baseIntent.replaceExtras((Bundle)null);
8173                    }
8174
8175                    res.add(rti);
8176                    maxNum--;
8177                }
8178            }
8179            return res;
8180        }
8181    }
8182
8183    private TaskRecord taskForIdLocked(int id) {
8184        final TaskRecord task = recentTaskForIdLocked(id);
8185        if (task != null) {
8186            return task;
8187        }
8188
8189        // Don't give up. Sometimes it just hasn't made it to recents yet.
8190        return mStackSupervisor.anyTaskForIdLocked(id);
8191    }
8192
8193    private TaskRecord recentTaskForIdLocked(int id) {
8194        final int N = mRecentTasks.size();
8195            for (int i=0; i<N; i++) {
8196                TaskRecord tr = mRecentTasks.get(i);
8197                if (tr.taskId == id) {
8198                    return tr;
8199                }
8200            }
8201            return null;
8202    }
8203
8204    @Override
8205    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8206        synchronized (this) {
8207            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8208                    "getTaskThumbnail()");
8209            TaskRecord tr = recentTaskForIdLocked(id);
8210            if (tr != null) {
8211                return tr.getTaskThumbnailLocked();
8212            }
8213        }
8214        return null;
8215    }
8216
8217    @Override
8218    public int addAppTask(IBinder activityToken, Intent intent,
8219            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8220        final int callingUid = Binder.getCallingUid();
8221        final long callingIdent = Binder.clearCallingIdentity();
8222
8223        try {
8224            synchronized (this) {
8225                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8226                if (r == null) {
8227                    throw new IllegalArgumentException("Activity does not exist; token="
8228                            + activityToken);
8229                }
8230                ComponentName comp = intent.getComponent();
8231                if (comp == null) {
8232                    throw new IllegalArgumentException("Intent " + intent
8233                            + " must specify explicit component");
8234                }
8235                if (thumbnail.getWidth() != mThumbnailWidth
8236                        || thumbnail.getHeight() != mThumbnailHeight) {
8237                    throw new IllegalArgumentException("Bad thumbnail size: got "
8238                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8239                            + mThumbnailWidth + "x" + mThumbnailHeight);
8240                }
8241                if (intent.getSelector() != null) {
8242                    intent.setSelector(null);
8243                }
8244                if (intent.getSourceBounds() != null) {
8245                    intent.setSourceBounds(null);
8246                }
8247                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8248                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8249                        // The caller has added this as an auto-remove task...  that makes no
8250                        // sense, so turn off auto-remove.
8251                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8252                    }
8253                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8254                    // Must be a new task.
8255                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8256                }
8257                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8258                    mLastAddedTaskActivity = null;
8259                }
8260                ActivityInfo ainfo = mLastAddedTaskActivity;
8261                if (ainfo == null) {
8262                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8263                            comp, 0, UserHandle.getUserId(callingUid));
8264                    if (ainfo.applicationInfo.uid != callingUid) {
8265                        throw new SecurityException(
8266                                "Can't add task for another application: target uid="
8267                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8268                    }
8269                }
8270
8271                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8272                        intent, description);
8273
8274                int trimIdx = trimRecentsForTaskLocked(task, false);
8275                if (trimIdx >= 0) {
8276                    // If this would have caused a trim, then we'll abort because that
8277                    // means it would be added at the end of the list but then just removed.
8278                    return INVALID_TASK_ID;
8279                }
8280
8281                final int N = mRecentTasks.size();
8282                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8283                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8284                    tr.removedFromRecents();
8285                }
8286
8287                task.inRecents = true;
8288                mRecentTasks.add(task);
8289                r.task.stack.addTask(task, false, false);
8290
8291                task.setLastThumbnail(thumbnail);
8292                task.freeLastThumbnail();
8293
8294                return task.taskId;
8295            }
8296        } finally {
8297            Binder.restoreCallingIdentity(callingIdent);
8298        }
8299    }
8300
8301    @Override
8302    public Point getAppTaskThumbnailSize() {
8303        synchronized (this) {
8304            return new Point(mThumbnailWidth,  mThumbnailHeight);
8305        }
8306    }
8307
8308    @Override
8309    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8310        synchronized (this) {
8311            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8312            if (r != null) {
8313                r.setTaskDescription(td);
8314                r.task.updateTaskDescription();
8315            }
8316        }
8317    }
8318
8319    @Override
8320    public Bitmap getTaskDescriptionIcon(String filename) {
8321        if (!FileUtils.isValidExtFilename(filename)
8322                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8323            throw new IllegalArgumentException("Bad filename: " + filename);
8324        }
8325        return mTaskPersister.getTaskDescriptionIcon(filename);
8326    }
8327
8328    @Override
8329    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8330            throws RemoteException {
8331        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8332                opts.getCustomInPlaceResId() == 0) {
8333            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8334                    "with valid animation");
8335        }
8336        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8337        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8338                opts.getCustomInPlaceResId());
8339        mWindowManager.executeAppTransition();
8340    }
8341
8342    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8343        mRecentTasks.remove(tr);
8344        tr.removedFromRecents();
8345        ComponentName component = tr.getBaseIntent().getComponent();
8346        if (component == null) {
8347            Slog.w(TAG, "No component for base intent of task: " + tr);
8348            return;
8349        }
8350
8351        if (!killProcess) {
8352            return;
8353        }
8354
8355        // Determine if the process(es) for this task should be killed.
8356        final String pkg = component.getPackageName();
8357        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8358        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8359        for (int i = 0; i < pmap.size(); i++) {
8360
8361            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8362            for (int j = 0; j < uids.size(); j++) {
8363                ProcessRecord proc = uids.valueAt(j);
8364                if (proc.userId != tr.userId) {
8365                    // Don't kill process for a different user.
8366                    continue;
8367                }
8368                if (proc == mHomeProcess) {
8369                    // Don't kill the home process along with tasks from the same package.
8370                    continue;
8371                }
8372                if (!proc.pkgList.containsKey(pkg)) {
8373                    // Don't kill process that is not associated with this task.
8374                    continue;
8375                }
8376
8377                for (int k = 0; k < proc.activities.size(); k++) {
8378                    TaskRecord otherTask = proc.activities.get(k).task;
8379                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8380                        // Don't kill process(es) that has an activity in a different task that is
8381                        // also in recents.
8382                        return;
8383                    }
8384                }
8385
8386                // Add process to kill list.
8387                procsToKill.add(proc);
8388            }
8389        }
8390
8391        // Find any running services associated with this app and stop if needed.
8392        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8393
8394        // Kill the running processes.
8395        for (int i = 0; i < procsToKill.size(); i++) {
8396            ProcessRecord pr = procsToKill.get(i);
8397            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8398                pr.kill("remove task", true);
8399            } else {
8400                pr.waitingToKill = "remove task";
8401            }
8402        }
8403    }
8404
8405    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8406        // Remove all tasks with activities in the specified package from the list of recent tasks
8407        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8408            TaskRecord tr = mRecentTasks.get(i);
8409            if (tr.userId != userId) continue;
8410
8411            ComponentName cn = tr.intent.getComponent();
8412            if (cn != null && cn.getPackageName().equals(packageName)) {
8413                // If the package name matches, remove the task.
8414                removeTaskByIdLocked(tr.taskId, true);
8415            }
8416        }
8417    }
8418
8419    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8420        final IPackageManager pm = AppGlobals.getPackageManager();
8421        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8422
8423        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8424            TaskRecord tr = mRecentTasks.get(i);
8425            if (tr.userId != userId) continue;
8426
8427            ComponentName cn = tr.intent.getComponent();
8428            if (cn != null && cn.getPackageName().equals(packageName)) {
8429                // Skip if component still exists in the package.
8430                if (componentsKnownToExist.contains(cn)) continue;
8431
8432                try {
8433                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8434                    if (info != null) {
8435                        componentsKnownToExist.add(cn);
8436                    } else {
8437                        removeTaskByIdLocked(tr.taskId, false);
8438                    }
8439                } catch (RemoteException e) {
8440                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8441                }
8442            }
8443        }
8444    }
8445
8446    /**
8447     * Removes the task with the specified task id.
8448     *
8449     * @param taskId Identifier of the task to be removed.
8450     * @param killProcess Kill any process associated with the task if possible.
8451     * @return Returns true if the given task was found and removed.
8452     */
8453    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8454        TaskRecord tr = taskForIdLocked(taskId);
8455        if (tr != null) {
8456            tr.removeTaskActivitiesLocked();
8457            cleanUpRemovedTaskLocked(tr, killProcess);
8458            if (tr.isPersistable) {
8459                notifyTaskPersisterLocked(null, true);
8460            }
8461            return true;
8462        }
8463        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8464        return false;
8465    }
8466
8467    @Override
8468    public boolean removeTask(int taskId) {
8469        synchronized (this) {
8470            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8471                    "removeTask()");
8472            long ident = Binder.clearCallingIdentity();
8473            try {
8474                return removeTaskByIdLocked(taskId, true);
8475            } finally {
8476                Binder.restoreCallingIdentity(ident);
8477            }
8478        }
8479    }
8480
8481    /**
8482     * TODO: Add mController hook
8483     */
8484    @Override
8485    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8486        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8487                "moveTaskToFront()");
8488
8489        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8490        synchronized(this) {
8491            moveTaskToFrontLocked(taskId, flags, options);
8492        }
8493    }
8494
8495    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8496        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8497                Binder.getCallingUid(), -1, -1, "Task to front")) {
8498            ActivityOptions.abort(options);
8499            return;
8500        }
8501        final long origId = Binder.clearCallingIdentity();
8502        try {
8503            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8504            if (task == null) {
8505                Slog.d(TAG, "Could not find task for id: "+ taskId);
8506                return;
8507            }
8508            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8509                mStackSupervisor.showLockTaskToast();
8510                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8511                return;
8512            }
8513            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8514            if (prev != null && prev.isRecentsActivity()) {
8515                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8516            }
8517            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8518        } finally {
8519            Binder.restoreCallingIdentity(origId);
8520        }
8521        ActivityOptions.abort(options);
8522    }
8523
8524    @Override
8525    public void moveTaskToBack(int taskId) {
8526        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8527                "moveTaskToBack()");
8528
8529        synchronized(this) {
8530            TaskRecord tr = taskForIdLocked(taskId);
8531            if (tr != null) {
8532                if (tr == mStackSupervisor.mLockTaskModeTask) {
8533                    mStackSupervisor.showLockTaskToast();
8534                    return;
8535                }
8536                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8537                ActivityStack stack = tr.stack;
8538                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8539                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8540                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8541                        return;
8542                    }
8543                }
8544                final long origId = Binder.clearCallingIdentity();
8545                try {
8546                    stack.moveTaskToBackLocked(taskId, null);
8547                } finally {
8548                    Binder.restoreCallingIdentity(origId);
8549                }
8550            }
8551        }
8552    }
8553
8554    /**
8555     * Moves an activity, and all of the other activities within the same task, to the bottom
8556     * of the history stack.  The activity's order within the task is unchanged.
8557     *
8558     * @param token A reference to the activity we wish to move
8559     * @param nonRoot If false then this only works if the activity is the root
8560     *                of a task; if true it will work for any activity in a task.
8561     * @return Returns true if the move completed, false if not.
8562     */
8563    @Override
8564    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8565        enforceNotIsolatedCaller("moveActivityTaskToBack");
8566        synchronized(this) {
8567            final long origId = Binder.clearCallingIdentity();
8568            try {
8569                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8570                if (taskId >= 0) {
8571                    if ((mStackSupervisor.mLockTaskModeTask != null)
8572                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8573                        mStackSupervisor.showLockTaskToast();
8574                        return false;
8575                    }
8576                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8577                }
8578            } finally {
8579                Binder.restoreCallingIdentity(origId);
8580            }
8581        }
8582        return false;
8583    }
8584
8585    @Override
8586    public void moveTaskBackwards(int task) {
8587        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8588                "moveTaskBackwards()");
8589
8590        synchronized(this) {
8591            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8592                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8593                return;
8594            }
8595            final long origId = Binder.clearCallingIdentity();
8596            moveTaskBackwardsLocked(task);
8597            Binder.restoreCallingIdentity(origId);
8598        }
8599    }
8600
8601    private final void moveTaskBackwardsLocked(int task) {
8602        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8603    }
8604
8605    @Override
8606    public IBinder getHomeActivityToken() throws RemoteException {
8607        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8608                "getHomeActivityToken()");
8609        synchronized (this) {
8610            return mStackSupervisor.getHomeActivityToken();
8611        }
8612    }
8613
8614    @Override
8615    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8616            IActivityContainerCallback callback) throws RemoteException {
8617        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8618                "createActivityContainer()");
8619        synchronized (this) {
8620            if (parentActivityToken == null) {
8621                throw new IllegalArgumentException("parent token must not be null");
8622            }
8623            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8624            if (r == null) {
8625                return null;
8626            }
8627            if (callback == null) {
8628                throw new IllegalArgumentException("callback must not be null");
8629            }
8630            return mStackSupervisor.createActivityContainer(r, callback);
8631        }
8632    }
8633
8634    @Override
8635    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8636        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8637                "deleteActivityContainer()");
8638        synchronized (this) {
8639            mStackSupervisor.deleteActivityContainer(container);
8640        }
8641    }
8642
8643    @Override
8644    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8645            throws RemoteException {
8646        synchronized (this) {
8647            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8648            if (stack != null) {
8649                return stack.mActivityContainer;
8650            }
8651            return null;
8652        }
8653    }
8654
8655    @Override
8656    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8657        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8658                "moveTaskToStack()");
8659        if (stackId == HOME_STACK_ID) {
8660            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8661                    new RuntimeException("here").fillInStackTrace());
8662        }
8663        synchronized (this) {
8664            long ident = Binder.clearCallingIdentity();
8665            try {
8666                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8667                        + stackId + " toTop=" + toTop);
8668                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8669            } finally {
8670                Binder.restoreCallingIdentity(ident);
8671            }
8672        }
8673    }
8674
8675    @Override
8676    public void resizeStack(int stackBoxId, Rect bounds) {
8677        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8678                "resizeStackBox()");
8679        long ident = Binder.clearCallingIdentity();
8680        try {
8681            mWindowManager.resizeStack(stackBoxId, bounds);
8682        } finally {
8683            Binder.restoreCallingIdentity(ident);
8684        }
8685    }
8686
8687    @Override
8688    public List<StackInfo> getAllStackInfos() {
8689        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8690                "getAllStackInfos()");
8691        long ident = Binder.clearCallingIdentity();
8692        try {
8693            synchronized (this) {
8694                return mStackSupervisor.getAllStackInfosLocked();
8695            }
8696        } finally {
8697            Binder.restoreCallingIdentity(ident);
8698        }
8699    }
8700
8701    @Override
8702    public StackInfo getStackInfo(int stackId) {
8703        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8704                "getStackInfo()");
8705        long ident = Binder.clearCallingIdentity();
8706        try {
8707            synchronized (this) {
8708                return mStackSupervisor.getStackInfoLocked(stackId);
8709            }
8710        } finally {
8711            Binder.restoreCallingIdentity(ident);
8712        }
8713    }
8714
8715    @Override
8716    public boolean isInHomeStack(int taskId) {
8717        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8718                "getStackInfo()");
8719        long ident = Binder.clearCallingIdentity();
8720        try {
8721            synchronized (this) {
8722                TaskRecord tr = taskForIdLocked(taskId);
8723                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8724            }
8725        } finally {
8726            Binder.restoreCallingIdentity(ident);
8727        }
8728    }
8729
8730    @Override
8731    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8732        synchronized(this) {
8733            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8734        }
8735    }
8736
8737    private boolean isLockTaskAuthorized(String pkg) {
8738        final DevicePolicyManager dpm = (DevicePolicyManager)
8739                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8740        try {
8741            int uid = mContext.getPackageManager().getPackageUid(pkg,
8742                    Binder.getCallingUserHandle().getIdentifier());
8743            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8744        } catch (NameNotFoundException e) {
8745            return false;
8746        }
8747    }
8748
8749    void startLockTaskMode(TaskRecord task) {
8750        final String pkg;
8751        synchronized (this) {
8752            pkg = task.intent.getComponent().getPackageName();
8753        }
8754        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8755        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8756            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8757                    StatusBarManagerInternal.class);
8758            if (statusBarManager != null) {
8759                statusBarManager.showScreenPinningRequest();
8760            }
8761            return;
8762        }
8763        long ident = Binder.clearCallingIdentity();
8764        try {
8765            synchronized (this) {
8766                // Since we lost lock on task, make sure it is still there.
8767                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8768                if (task != null) {
8769                    if (!isSystemInitiated
8770                            && ((mStackSupervisor.getFocusedStack() == null)
8771                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8772                        throw new IllegalArgumentException("Invalid task, not in foreground");
8773                    }
8774                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8775                }
8776            }
8777        } finally {
8778            Binder.restoreCallingIdentity(ident);
8779        }
8780    }
8781
8782    @Override
8783    public void startLockTaskMode(int taskId) {
8784        final TaskRecord task;
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8789            }
8790        } finally {
8791            Binder.restoreCallingIdentity(ident);
8792        }
8793        if (task != null) {
8794            startLockTaskMode(task);
8795        }
8796    }
8797
8798    @Override
8799    public void startLockTaskMode(IBinder token) {
8800        final TaskRecord task;
8801        long ident = Binder.clearCallingIdentity();
8802        try {
8803            synchronized (this) {
8804                final ActivityRecord r = ActivityRecord.forToken(token);
8805                if (r == null) {
8806                    return;
8807                }
8808                task = r.task;
8809            }
8810        } finally {
8811            Binder.restoreCallingIdentity(ident);
8812        }
8813        if (task != null) {
8814            startLockTaskMode(task);
8815        }
8816    }
8817
8818    @Override
8819    public void startLockTaskModeOnCurrent() throws RemoteException {
8820        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8821                "startLockTaskModeOnCurrent");
8822        long ident = Binder.clearCallingIdentity();
8823        try {
8824            ActivityRecord r = null;
8825            synchronized (this) {
8826                r = mStackSupervisor.topRunningActivityLocked();
8827            }
8828            startLockTaskMode(r.task);
8829        } finally {
8830            Binder.restoreCallingIdentity(ident);
8831        }
8832    }
8833
8834    @Override
8835    public void stopLockTaskMode() {
8836        // Verify that the user matches the package of the intent for the TaskRecord
8837        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8838        // and stopLockTaskMode.
8839        final int callingUid = Binder.getCallingUid();
8840        if (callingUid != Process.SYSTEM_UID) {
8841            try {
8842                String pkg =
8843                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8844                int uid = mContext.getPackageManager().getPackageUid(pkg,
8845                        Binder.getCallingUserHandle().getIdentifier());
8846                if (uid != callingUid) {
8847                    throw new SecurityException("Invalid uid, expected " + uid);
8848                }
8849            } catch (NameNotFoundException e) {
8850                Log.d(TAG, "stopLockTaskMode " + e);
8851                return;
8852            }
8853        }
8854        long ident = Binder.clearCallingIdentity();
8855        try {
8856            Log.d(TAG, "stopLockTaskMode");
8857            // Stop lock task
8858            synchronized (this) {
8859                mStackSupervisor.setLockTaskModeLocked(null, false);
8860            }
8861        } finally {
8862            Binder.restoreCallingIdentity(ident);
8863        }
8864    }
8865
8866    @Override
8867    public void stopLockTaskModeOnCurrent() throws RemoteException {
8868        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8869                "stopLockTaskModeOnCurrent");
8870        long ident = Binder.clearCallingIdentity();
8871        try {
8872            stopLockTaskMode();
8873        } finally {
8874            Binder.restoreCallingIdentity(ident);
8875        }
8876    }
8877
8878    @Override
8879    public boolean isInLockTaskMode() {
8880        synchronized (this) {
8881            return mStackSupervisor.isInLockTaskMode();
8882        }
8883    }
8884
8885    // =========================================================
8886    // CONTENT PROVIDERS
8887    // =========================================================
8888
8889    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8890        List<ProviderInfo> providers = null;
8891        try {
8892            providers = AppGlobals.getPackageManager().
8893                queryContentProviders(app.processName, app.uid,
8894                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8895        } catch (RemoteException ex) {
8896        }
8897        if (DEBUG_MU)
8898            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8899        int userId = app.userId;
8900        if (providers != null) {
8901            int N = providers.size();
8902            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8903            for (int i=0; i<N; i++) {
8904                ProviderInfo cpi =
8905                    (ProviderInfo)providers.get(i);
8906                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8907                        cpi.name, cpi.flags);
8908                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8909                    // This is a singleton provider, but a user besides the
8910                    // default user is asking to initialize a process it runs
8911                    // in...  well, no, it doesn't actually run in this process,
8912                    // it runs in the process of the default user.  Get rid of it.
8913                    providers.remove(i);
8914                    N--;
8915                    i--;
8916                    continue;
8917                }
8918
8919                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8920                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8921                if (cpr == null) {
8922                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8923                    mProviderMap.putProviderByClass(comp, cpr);
8924                }
8925                if (DEBUG_MU)
8926                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8927                app.pubProviders.put(cpi.name, cpr);
8928                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8929                    // Don't add this if it is a platform component that is marked
8930                    // to run in multiple processes, because this is actually
8931                    // part of the framework so doesn't make sense to track as a
8932                    // separate apk in the process.
8933                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8934                            mProcessStats);
8935                }
8936                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8937            }
8938        }
8939        return providers;
8940    }
8941
8942    /**
8943     * Check if {@link ProcessRecord} has a possible chance at accessing the
8944     * given {@link ProviderInfo}. Final permission checking is always done
8945     * in {@link ContentProvider}.
8946     */
8947    private final String checkContentProviderPermissionLocked(
8948            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8949        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8950        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8951        boolean checkedGrants = false;
8952        if (checkUser) {
8953            // Looking for cross-user grants before enforcing the typical cross-users permissions
8954            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8955            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8956                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8957                    return null;
8958                }
8959                checkedGrants = true;
8960            }
8961            userId = handleIncomingUser(callingPid, callingUid, userId,
8962                    false, ALLOW_NON_FULL,
8963                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8964            if (userId != tmpTargetUserId) {
8965                // When we actually went to determine the final targer user ID, this ended
8966                // up different than our initial check for the authority.  This is because
8967                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8968                // SELF.  So we need to re-check the grants again.
8969                checkedGrants = false;
8970            }
8971        }
8972        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8973                cpi.applicationInfo.uid, cpi.exported)
8974                == PackageManager.PERMISSION_GRANTED) {
8975            return null;
8976        }
8977        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8978                cpi.applicationInfo.uid, cpi.exported)
8979                == PackageManager.PERMISSION_GRANTED) {
8980            return null;
8981        }
8982
8983        PathPermission[] pps = cpi.pathPermissions;
8984        if (pps != null) {
8985            int i = pps.length;
8986            while (i > 0) {
8987                i--;
8988                PathPermission pp = pps[i];
8989                String pprperm = pp.getReadPermission();
8990                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8991                        cpi.applicationInfo.uid, cpi.exported)
8992                        == PackageManager.PERMISSION_GRANTED) {
8993                    return null;
8994                }
8995                String ppwperm = pp.getWritePermission();
8996                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8997                        cpi.applicationInfo.uid, cpi.exported)
8998                        == PackageManager.PERMISSION_GRANTED) {
8999                    return null;
9000                }
9001            }
9002        }
9003        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9004            return null;
9005        }
9006
9007        String msg;
9008        if (!cpi.exported) {
9009            msg = "Permission Denial: opening provider " + cpi.name
9010                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9011                    + ", uid=" + callingUid + ") that is not exported from uid "
9012                    + cpi.applicationInfo.uid;
9013        } else {
9014            msg = "Permission Denial: opening provider " + cpi.name
9015                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9016                    + ", uid=" + callingUid + ") requires "
9017                    + cpi.readPermission + " or " + cpi.writePermission;
9018        }
9019        Slog.w(TAG, msg);
9020        return msg;
9021    }
9022
9023    /**
9024     * Returns if the ContentProvider has granted a uri to callingUid
9025     */
9026    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9027        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9028        if (perms != null) {
9029            for (int i=perms.size()-1; i>=0; i--) {
9030                GrantUri grantUri = perms.keyAt(i);
9031                if (grantUri.sourceUserId == userId || !checkUser) {
9032                    if (matchesProvider(grantUri.uri, cpi)) {
9033                        return true;
9034                    }
9035                }
9036            }
9037        }
9038        return false;
9039    }
9040
9041    /**
9042     * Returns true if the uri authority is one of the authorities specified in the provider.
9043     */
9044    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9045        String uriAuth = uri.getAuthority();
9046        String cpiAuth = cpi.authority;
9047        if (cpiAuth.indexOf(';') == -1) {
9048            return cpiAuth.equals(uriAuth);
9049        }
9050        String[] cpiAuths = cpiAuth.split(";");
9051        int length = cpiAuths.length;
9052        for (int i = 0; i < length; i++) {
9053            if (cpiAuths[i].equals(uriAuth)) return true;
9054        }
9055        return false;
9056    }
9057
9058    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9059            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9060        if (r != null) {
9061            for (int i=0; i<r.conProviders.size(); i++) {
9062                ContentProviderConnection conn = r.conProviders.get(i);
9063                if (conn.provider == cpr) {
9064                    if (DEBUG_PROVIDER) Slog.v(TAG,
9065                            "Adding provider requested by "
9066                            + r.processName + " from process "
9067                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9068                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9069                    if (stable) {
9070                        conn.stableCount++;
9071                        conn.numStableIncs++;
9072                    } else {
9073                        conn.unstableCount++;
9074                        conn.numUnstableIncs++;
9075                    }
9076                    return conn;
9077                }
9078            }
9079            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9080            if (stable) {
9081                conn.stableCount = 1;
9082                conn.numStableIncs = 1;
9083            } else {
9084                conn.unstableCount = 1;
9085                conn.numUnstableIncs = 1;
9086            }
9087            cpr.connections.add(conn);
9088            r.conProviders.add(conn);
9089            return conn;
9090        }
9091        cpr.addExternalProcessHandleLocked(externalProcessToken);
9092        return null;
9093    }
9094
9095    boolean decProviderCountLocked(ContentProviderConnection conn,
9096            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9097        if (conn != null) {
9098            cpr = conn.provider;
9099            if (DEBUG_PROVIDER) Slog.v(TAG,
9100                    "Removing provider requested by "
9101                    + conn.client.processName + " from process "
9102                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9103                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9104            if (stable) {
9105                conn.stableCount--;
9106            } else {
9107                conn.unstableCount--;
9108            }
9109            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9110                cpr.connections.remove(conn);
9111                conn.client.conProviders.remove(conn);
9112                return true;
9113            }
9114            return false;
9115        }
9116        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9117        return false;
9118    }
9119
9120    private void checkTime(long startTime, String where) {
9121        long now = SystemClock.elapsedRealtime();
9122        if ((now-startTime) > 1000) {
9123            // If we are taking more than a second, log about it.
9124            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9125        }
9126    }
9127
9128    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9129            String name, IBinder token, boolean stable, int userId) {
9130        ContentProviderRecord cpr;
9131        ContentProviderConnection conn = null;
9132        ProviderInfo cpi = null;
9133
9134        synchronized(this) {
9135            long startTime = SystemClock.elapsedRealtime();
9136
9137            ProcessRecord r = null;
9138            if (caller != null) {
9139                r = getRecordForAppLocked(caller);
9140                if (r == null) {
9141                    throw new SecurityException(
9142                            "Unable to find app for caller " + caller
9143                          + " (pid=" + Binder.getCallingPid()
9144                          + ") when getting content provider " + name);
9145                }
9146            }
9147
9148            boolean checkCrossUser = true;
9149
9150            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9151
9152            // First check if this content provider has been published...
9153            cpr = mProviderMap.getProviderByName(name, userId);
9154            // If that didn't work, check if it exists for user 0 and then
9155            // verify that it's a singleton provider before using it.
9156            if (cpr == null && userId != UserHandle.USER_OWNER) {
9157                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9158                if (cpr != null) {
9159                    cpi = cpr.info;
9160                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9161                            cpi.name, cpi.flags)
9162                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9163                        userId = UserHandle.USER_OWNER;
9164                        checkCrossUser = false;
9165                    } else {
9166                        cpr = null;
9167                        cpi = null;
9168                    }
9169                }
9170            }
9171
9172            boolean providerRunning = cpr != null;
9173            if (providerRunning) {
9174                cpi = cpr.info;
9175                String msg;
9176                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9177                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9178                        != null) {
9179                    throw new SecurityException(msg);
9180                }
9181                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9182
9183                if (r != null && cpr.canRunHere(r)) {
9184                    // This provider has been published or is in the process
9185                    // of being published...  but it is also allowed to run
9186                    // in the caller's process, so don't make a connection
9187                    // and just let the caller instantiate its own instance.
9188                    ContentProviderHolder holder = cpr.newHolder(null);
9189                    // don't give caller the provider object, it needs
9190                    // to make its own.
9191                    holder.provider = null;
9192                    return holder;
9193                }
9194
9195                final long origId = Binder.clearCallingIdentity();
9196
9197                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9198
9199                // In this case the provider instance already exists, so we can
9200                // return it right away.
9201                conn = incProviderCountLocked(r, cpr, token, stable);
9202                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9203                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9204                        // If this is a perceptible app accessing the provider,
9205                        // make sure to count it as being accessed and thus
9206                        // back up on the LRU list.  This is good because
9207                        // content providers are often expensive to start.
9208                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9209                        updateLruProcessLocked(cpr.proc, false, null);
9210                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9211                    }
9212                }
9213
9214                if (cpr.proc != null) {
9215                    if (false) {
9216                        if (cpr.name.flattenToShortString().equals(
9217                                "com.android.providers.calendar/.CalendarProvider2")) {
9218                            Slog.v(TAG, "****************** KILLING "
9219                                + cpr.name.flattenToShortString());
9220                            Process.killProcess(cpr.proc.pid);
9221                        }
9222                    }
9223                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9224                    boolean success = updateOomAdjLocked(cpr.proc);
9225                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9226                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9227                    // NOTE: there is still a race here where a signal could be
9228                    // pending on the process even though we managed to update its
9229                    // adj level.  Not sure what to do about this, but at least
9230                    // the race is now smaller.
9231                    if (!success) {
9232                        // Uh oh...  it looks like the provider's process
9233                        // has been killed on us.  We need to wait for a new
9234                        // process to be started, and make sure its death
9235                        // doesn't kill our process.
9236                        Slog.i(TAG,
9237                                "Existing provider " + cpr.name.flattenToShortString()
9238                                + " is crashing; detaching " + r);
9239                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9240                        checkTime(startTime, "getContentProviderImpl: before appDied");
9241                        appDiedLocked(cpr.proc);
9242                        checkTime(startTime, "getContentProviderImpl: after appDied");
9243                        if (!lastRef) {
9244                            // This wasn't the last ref our process had on
9245                            // the provider...  we have now been killed, bail.
9246                            return null;
9247                        }
9248                        providerRunning = false;
9249                        conn = null;
9250                    }
9251                }
9252
9253                Binder.restoreCallingIdentity(origId);
9254            }
9255
9256            boolean singleton;
9257            if (!providerRunning) {
9258                try {
9259                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9260                    cpi = AppGlobals.getPackageManager().
9261                        resolveContentProvider(name,
9262                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9263                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9264                } catch (RemoteException ex) {
9265                }
9266                if (cpi == null) {
9267                    return null;
9268                }
9269                // If the provider is a singleton AND
9270                // (it's a call within the same user || the provider is a
9271                // privileged app)
9272                // Then allow connecting to the singleton provider
9273                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9274                        cpi.name, cpi.flags)
9275                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9276                if (singleton) {
9277                    userId = UserHandle.USER_OWNER;
9278                }
9279                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9280                checkTime(startTime, "getContentProviderImpl: got app info for user");
9281
9282                String msg;
9283                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9284                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9285                        != null) {
9286                    throw new SecurityException(msg);
9287                }
9288                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9289
9290                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9291                        && !cpi.processName.equals("system")) {
9292                    // If this content provider does not run in the system
9293                    // process, and the system is not yet ready to run other
9294                    // processes, then fail fast instead of hanging.
9295                    throw new IllegalArgumentException(
9296                            "Attempt to launch content provider before system ready");
9297                }
9298
9299                // Make sure that the user who owns this provider is running.  If not,
9300                // we don't want to allow it to run.
9301                if (!isUserRunningLocked(userId, false)) {
9302                    Slog.w(TAG, "Unable to launch app "
9303                            + cpi.applicationInfo.packageName + "/"
9304                            + cpi.applicationInfo.uid + " for provider "
9305                            + name + ": user " + userId + " is stopped");
9306                    return null;
9307                }
9308
9309                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9310                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9311                cpr = mProviderMap.getProviderByClass(comp, userId);
9312                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9313                final boolean firstClass = cpr == null;
9314                if (firstClass) {
9315                    final long ident = Binder.clearCallingIdentity();
9316                    try {
9317                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9318                        ApplicationInfo ai =
9319                            AppGlobals.getPackageManager().
9320                                getApplicationInfo(
9321                                        cpi.applicationInfo.packageName,
9322                                        STOCK_PM_FLAGS, userId);
9323                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9324                        if (ai == null) {
9325                            Slog.w(TAG, "No package info for content provider "
9326                                    + cpi.name);
9327                            return null;
9328                        }
9329                        ai = getAppInfoForUser(ai, userId);
9330                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9331                    } catch (RemoteException ex) {
9332                        // pm is in same process, this will never happen.
9333                    } finally {
9334                        Binder.restoreCallingIdentity(ident);
9335                    }
9336                }
9337
9338                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9339
9340                if (r != null && cpr.canRunHere(r)) {
9341                    // If this is a multiprocess provider, then just return its
9342                    // info and allow the caller to instantiate it.  Only do
9343                    // this if the provider is the same user as the caller's
9344                    // process, or can run as root (so can be in any process).
9345                    return cpr.newHolder(null);
9346                }
9347
9348                if (DEBUG_PROVIDER) {
9349                    RuntimeException e = new RuntimeException("here");
9350                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9351                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9352                }
9353
9354                // This is single process, and our app is now connecting to it.
9355                // See if we are already in the process of launching this
9356                // provider.
9357                final int N = mLaunchingProviders.size();
9358                int i;
9359                for (i=0; i<N; i++) {
9360                    if (mLaunchingProviders.get(i) == cpr) {
9361                        break;
9362                    }
9363                }
9364
9365                // If the provider is not already being launched, then get it
9366                // started.
9367                if (i >= N) {
9368                    final long origId = Binder.clearCallingIdentity();
9369
9370                    try {
9371                        // Content provider is now in use, its package can't be stopped.
9372                        try {
9373                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9374                            AppGlobals.getPackageManager().setPackageStoppedState(
9375                                    cpr.appInfo.packageName, false, userId);
9376                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9377                        } catch (RemoteException e) {
9378                        } catch (IllegalArgumentException e) {
9379                            Slog.w(TAG, "Failed trying to unstop package "
9380                                    + cpr.appInfo.packageName + ": " + e);
9381                        }
9382
9383                        // Use existing process if already started
9384                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9385                        ProcessRecord proc = getProcessRecordLocked(
9386                                cpi.processName, cpr.appInfo.uid, false);
9387                        if (proc != null && proc.thread != null) {
9388                            if (DEBUG_PROVIDER) {
9389                                Slog.d(TAG, "Installing in existing process " + proc);
9390                            }
9391                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9392                            proc.pubProviders.put(cpi.name, cpr);
9393                            try {
9394                                proc.thread.scheduleInstallProvider(cpi);
9395                            } catch (RemoteException e) {
9396                            }
9397                        } else {
9398                            checkTime(startTime, "getContentProviderImpl: before start process");
9399                            proc = startProcessLocked(cpi.processName,
9400                                    cpr.appInfo, false, 0, "content provider",
9401                                    new ComponentName(cpi.applicationInfo.packageName,
9402                                            cpi.name), false, false, false);
9403                            checkTime(startTime, "getContentProviderImpl: after start process");
9404                            if (proc == null) {
9405                                Slog.w(TAG, "Unable to launch app "
9406                                        + cpi.applicationInfo.packageName + "/"
9407                                        + cpi.applicationInfo.uid + " for provider "
9408                                        + name + ": process is bad");
9409                                return null;
9410                            }
9411                        }
9412                        cpr.launchingApp = proc;
9413                        mLaunchingProviders.add(cpr);
9414                    } finally {
9415                        Binder.restoreCallingIdentity(origId);
9416                    }
9417                }
9418
9419                checkTime(startTime, "getContentProviderImpl: updating data structures");
9420
9421                // Make sure the provider is published (the same provider class
9422                // may be published under multiple names).
9423                if (firstClass) {
9424                    mProviderMap.putProviderByClass(comp, cpr);
9425                }
9426
9427                mProviderMap.putProviderByName(name, cpr);
9428                conn = incProviderCountLocked(r, cpr, token, stable);
9429                if (conn != null) {
9430                    conn.waiting = true;
9431                }
9432            }
9433            checkTime(startTime, "getContentProviderImpl: done!");
9434        }
9435
9436        // Wait for the provider to be published...
9437        synchronized (cpr) {
9438            while (cpr.provider == null) {
9439                if (cpr.launchingApp == null) {
9440                    Slog.w(TAG, "Unable to launch app "
9441                            + cpi.applicationInfo.packageName + "/"
9442                            + cpi.applicationInfo.uid + " for provider "
9443                            + name + ": launching app became null");
9444                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9445                            UserHandle.getUserId(cpi.applicationInfo.uid),
9446                            cpi.applicationInfo.packageName,
9447                            cpi.applicationInfo.uid, name);
9448                    return null;
9449                }
9450                try {
9451                    if (DEBUG_MU) {
9452                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9453                                + cpr.launchingApp);
9454                    }
9455                    if (conn != null) {
9456                        conn.waiting = true;
9457                    }
9458                    cpr.wait();
9459                } catch (InterruptedException ex) {
9460                } finally {
9461                    if (conn != null) {
9462                        conn.waiting = false;
9463                    }
9464                }
9465            }
9466        }
9467        return cpr != null ? cpr.newHolder(conn) : null;
9468    }
9469
9470    @Override
9471    public final ContentProviderHolder getContentProvider(
9472            IApplicationThread caller, String name, int userId, boolean stable) {
9473        enforceNotIsolatedCaller("getContentProvider");
9474        if (caller == null) {
9475            String msg = "null IApplicationThread when getting content provider "
9476                    + name;
9477            Slog.w(TAG, msg);
9478            throw new SecurityException(msg);
9479        }
9480        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9481        // with cross-user grant.
9482        return getContentProviderImpl(caller, name, null, stable, userId);
9483    }
9484
9485    public ContentProviderHolder getContentProviderExternal(
9486            String name, int userId, IBinder token) {
9487        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9488            "Do not have permission in call getContentProviderExternal()");
9489        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9490                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9491        return getContentProviderExternalUnchecked(name, token, userId);
9492    }
9493
9494    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9495            IBinder token, int userId) {
9496        return getContentProviderImpl(null, name, token, true, userId);
9497    }
9498
9499    /**
9500     * Drop a content provider from a ProcessRecord's bookkeeping
9501     */
9502    public void removeContentProvider(IBinder connection, boolean stable) {
9503        enforceNotIsolatedCaller("removeContentProvider");
9504        long ident = Binder.clearCallingIdentity();
9505        try {
9506            synchronized (this) {
9507                ContentProviderConnection conn;
9508                try {
9509                    conn = (ContentProviderConnection)connection;
9510                } catch (ClassCastException e) {
9511                    String msg ="removeContentProvider: " + connection
9512                            + " not a ContentProviderConnection";
9513                    Slog.w(TAG, msg);
9514                    throw new IllegalArgumentException(msg);
9515                }
9516                if (conn == null) {
9517                    throw new NullPointerException("connection is null");
9518                }
9519                if (decProviderCountLocked(conn, null, null, stable)) {
9520                    updateOomAdjLocked();
9521                }
9522            }
9523        } finally {
9524            Binder.restoreCallingIdentity(ident);
9525        }
9526    }
9527
9528    public void removeContentProviderExternal(String name, IBinder token) {
9529        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9530            "Do not have permission in call removeContentProviderExternal()");
9531        int userId = UserHandle.getCallingUserId();
9532        long ident = Binder.clearCallingIdentity();
9533        try {
9534            removeContentProviderExternalUnchecked(name, token, userId);
9535        } finally {
9536            Binder.restoreCallingIdentity(ident);
9537        }
9538    }
9539
9540    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9541        synchronized (this) {
9542            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9543            if(cpr == null) {
9544                //remove from mProvidersByClass
9545                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9546                return;
9547            }
9548
9549            //update content provider record entry info
9550            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9551            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9552            if (localCpr.hasExternalProcessHandles()) {
9553                if (localCpr.removeExternalProcessHandleLocked(token)) {
9554                    updateOomAdjLocked();
9555                } else {
9556                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9557                            + " with no external reference for token: "
9558                            + token + ".");
9559                }
9560            } else {
9561                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9562                        + " with no external references.");
9563            }
9564        }
9565    }
9566
9567    public final void publishContentProviders(IApplicationThread caller,
9568            List<ContentProviderHolder> providers) {
9569        if (providers == null) {
9570            return;
9571        }
9572
9573        enforceNotIsolatedCaller("publishContentProviders");
9574        synchronized (this) {
9575            final ProcessRecord r = getRecordForAppLocked(caller);
9576            if (DEBUG_MU)
9577                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9578            if (r == null) {
9579                throw new SecurityException(
9580                        "Unable to find app for caller " + caller
9581                      + " (pid=" + Binder.getCallingPid()
9582                      + ") when publishing content providers");
9583            }
9584
9585            final long origId = Binder.clearCallingIdentity();
9586
9587            final int N = providers.size();
9588            for (int i=0; i<N; i++) {
9589                ContentProviderHolder src = providers.get(i);
9590                if (src == null || src.info == null || src.provider == null) {
9591                    continue;
9592                }
9593                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9594                if (DEBUG_MU)
9595                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9596                if (dst != null) {
9597                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9598                    mProviderMap.putProviderByClass(comp, dst);
9599                    String names[] = dst.info.authority.split(";");
9600                    for (int j = 0; j < names.length; j++) {
9601                        mProviderMap.putProviderByName(names[j], dst);
9602                    }
9603
9604                    int NL = mLaunchingProviders.size();
9605                    int j;
9606                    for (j=0; j<NL; j++) {
9607                        if (mLaunchingProviders.get(j) == dst) {
9608                            mLaunchingProviders.remove(j);
9609                            j--;
9610                            NL--;
9611                        }
9612                    }
9613                    synchronized (dst) {
9614                        dst.provider = src.provider;
9615                        dst.proc = r;
9616                        dst.notifyAll();
9617                    }
9618                    updateOomAdjLocked(r);
9619                }
9620            }
9621
9622            Binder.restoreCallingIdentity(origId);
9623        }
9624    }
9625
9626    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9627        ContentProviderConnection conn;
9628        try {
9629            conn = (ContentProviderConnection)connection;
9630        } catch (ClassCastException e) {
9631            String msg ="refContentProvider: " + connection
9632                    + " not a ContentProviderConnection";
9633            Slog.w(TAG, msg);
9634            throw new IllegalArgumentException(msg);
9635        }
9636        if (conn == null) {
9637            throw new NullPointerException("connection is null");
9638        }
9639
9640        synchronized (this) {
9641            if (stable > 0) {
9642                conn.numStableIncs += stable;
9643            }
9644            stable = conn.stableCount + stable;
9645            if (stable < 0) {
9646                throw new IllegalStateException("stableCount < 0: " + stable);
9647            }
9648
9649            if (unstable > 0) {
9650                conn.numUnstableIncs += unstable;
9651            }
9652            unstable = conn.unstableCount + unstable;
9653            if (unstable < 0) {
9654                throw new IllegalStateException("unstableCount < 0: " + unstable);
9655            }
9656
9657            if ((stable+unstable) <= 0) {
9658                throw new IllegalStateException("ref counts can't go to zero here: stable="
9659                        + stable + " unstable=" + unstable);
9660            }
9661            conn.stableCount = stable;
9662            conn.unstableCount = unstable;
9663            return !conn.dead;
9664        }
9665    }
9666
9667    public void unstableProviderDied(IBinder connection) {
9668        ContentProviderConnection conn;
9669        try {
9670            conn = (ContentProviderConnection)connection;
9671        } catch (ClassCastException e) {
9672            String msg ="refContentProvider: " + connection
9673                    + " not a ContentProviderConnection";
9674            Slog.w(TAG, msg);
9675            throw new IllegalArgumentException(msg);
9676        }
9677        if (conn == null) {
9678            throw new NullPointerException("connection is null");
9679        }
9680
9681        // Safely retrieve the content provider associated with the connection.
9682        IContentProvider provider;
9683        synchronized (this) {
9684            provider = conn.provider.provider;
9685        }
9686
9687        if (provider == null) {
9688            // Um, yeah, we're way ahead of you.
9689            return;
9690        }
9691
9692        // Make sure the caller is being honest with us.
9693        if (provider.asBinder().pingBinder()) {
9694            // Er, no, still looks good to us.
9695            synchronized (this) {
9696                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9697                        + " says " + conn + " died, but we don't agree");
9698                return;
9699            }
9700        }
9701
9702        // Well look at that!  It's dead!
9703        synchronized (this) {
9704            if (conn.provider.provider != provider) {
9705                // But something changed...  good enough.
9706                return;
9707            }
9708
9709            ProcessRecord proc = conn.provider.proc;
9710            if (proc == null || proc.thread == null) {
9711                // Seems like the process is already cleaned up.
9712                return;
9713            }
9714
9715            // As far as we're concerned, this is just like receiving a
9716            // death notification...  just a bit prematurely.
9717            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9718                    + ") early provider death");
9719            final long ident = Binder.clearCallingIdentity();
9720            try {
9721                appDiedLocked(proc);
9722            } finally {
9723                Binder.restoreCallingIdentity(ident);
9724            }
9725        }
9726    }
9727
9728    @Override
9729    public void appNotRespondingViaProvider(IBinder connection) {
9730        enforceCallingPermission(
9731                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9732
9733        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9734        if (conn == null) {
9735            Slog.w(TAG, "ContentProviderConnection is null");
9736            return;
9737        }
9738
9739        final ProcessRecord host = conn.provider.proc;
9740        if (host == null) {
9741            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9742            return;
9743        }
9744
9745        final long token = Binder.clearCallingIdentity();
9746        try {
9747            appNotResponding(host, null, null, false, "ContentProvider not responding");
9748        } finally {
9749            Binder.restoreCallingIdentity(token);
9750        }
9751    }
9752
9753    public final void installSystemProviders() {
9754        List<ProviderInfo> providers;
9755        synchronized (this) {
9756            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9757            providers = generateApplicationProvidersLocked(app);
9758            if (providers != null) {
9759                for (int i=providers.size()-1; i>=0; i--) {
9760                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9761                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9762                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9763                                + ": not system .apk");
9764                        providers.remove(i);
9765                    }
9766                }
9767            }
9768        }
9769        if (providers != null) {
9770            mSystemThread.installSystemProviders(providers);
9771        }
9772
9773        mCoreSettingsObserver = new CoreSettingsObserver(this);
9774
9775        //mUsageStatsService.monitorPackages();
9776    }
9777
9778    /**
9779     * Allows apps to retrieve the MIME type of a URI.
9780     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9781     * users, then it does not need permission to access the ContentProvider.
9782     * Either, it needs cross-user uri grants.
9783     *
9784     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9785     *
9786     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9787     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9788     */
9789    public String getProviderMimeType(Uri uri, int userId) {
9790        enforceNotIsolatedCaller("getProviderMimeType");
9791        final String name = uri.getAuthority();
9792        int callingUid = Binder.getCallingUid();
9793        int callingPid = Binder.getCallingPid();
9794        long ident = 0;
9795        boolean clearedIdentity = false;
9796        userId = unsafeConvertIncomingUser(userId);
9797        if (canClearIdentity(callingPid, callingUid, userId)) {
9798            clearedIdentity = true;
9799            ident = Binder.clearCallingIdentity();
9800        }
9801        ContentProviderHolder holder = null;
9802        try {
9803            holder = getContentProviderExternalUnchecked(name, null, userId);
9804            if (holder != null) {
9805                return holder.provider.getType(uri);
9806            }
9807        } catch (RemoteException e) {
9808            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9809            return null;
9810        } finally {
9811            // We need to clear the identity to call removeContentProviderExternalUnchecked
9812            if (!clearedIdentity) {
9813                ident = Binder.clearCallingIdentity();
9814            }
9815            try {
9816                if (holder != null) {
9817                    removeContentProviderExternalUnchecked(name, null, userId);
9818                }
9819            } finally {
9820                Binder.restoreCallingIdentity(ident);
9821            }
9822        }
9823
9824        return null;
9825    }
9826
9827    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9828        if (UserHandle.getUserId(callingUid) == userId) {
9829            return true;
9830        }
9831        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9832                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9833                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9834                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9835                return true;
9836        }
9837        return false;
9838    }
9839
9840    // =========================================================
9841    // GLOBAL MANAGEMENT
9842    // =========================================================
9843
9844    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9845            boolean isolated, int isolatedUid) {
9846        String proc = customProcess != null ? customProcess : info.processName;
9847        BatteryStatsImpl.Uid.Proc ps = null;
9848        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9849        int uid = info.uid;
9850        if (isolated) {
9851            if (isolatedUid == 0) {
9852                int userId = UserHandle.getUserId(uid);
9853                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9854                while (true) {
9855                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9856                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9857                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9858                    }
9859                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9860                    mNextIsolatedProcessUid++;
9861                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9862                        // No process for this uid, use it.
9863                        break;
9864                    }
9865                    stepsLeft--;
9866                    if (stepsLeft <= 0) {
9867                        return null;
9868                    }
9869                }
9870            } else {
9871                // Special case for startIsolatedProcess (internal only), where
9872                // the uid of the isolated process is specified by the caller.
9873                uid = isolatedUid;
9874            }
9875        }
9876        return new ProcessRecord(stats, info, proc, uid);
9877    }
9878
9879    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9880            String abiOverride) {
9881        ProcessRecord app;
9882        if (!isolated) {
9883            app = getProcessRecordLocked(info.processName, info.uid, true);
9884        } else {
9885            app = null;
9886        }
9887
9888        if (app == null) {
9889            app = newProcessRecordLocked(info, null, isolated, 0);
9890            mProcessNames.put(info.processName, app.uid, app);
9891            if (isolated) {
9892                mIsolatedProcesses.put(app.uid, app);
9893            }
9894            updateLruProcessLocked(app, false, null);
9895            updateOomAdjLocked();
9896        }
9897
9898        // This package really, really can not be stopped.
9899        try {
9900            AppGlobals.getPackageManager().setPackageStoppedState(
9901                    info.packageName, false, UserHandle.getUserId(app.uid));
9902        } catch (RemoteException e) {
9903        } catch (IllegalArgumentException e) {
9904            Slog.w(TAG, "Failed trying to unstop package "
9905                    + info.packageName + ": " + e);
9906        }
9907
9908        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9909                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9910            app.persistent = true;
9911            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9912        }
9913        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9914            mPersistentStartingProcesses.add(app);
9915            startProcessLocked(app, "added application", app.processName, abiOverride,
9916                    null /* entryPoint */, null /* entryPointArgs */);
9917        }
9918
9919        return app;
9920    }
9921
9922    public void unhandledBack() {
9923        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9924                "unhandledBack()");
9925
9926        synchronized(this) {
9927            final long origId = Binder.clearCallingIdentity();
9928            try {
9929                getFocusedStack().unhandledBackLocked();
9930            } finally {
9931                Binder.restoreCallingIdentity(origId);
9932            }
9933        }
9934    }
9935
9936    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9937        enforceNotIsolatedCaller("openContentUri");
9938        final int userId = UserHandle.getCallingUserId();
9939        String name = uri.getAuthority();
9940        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9941        ParcelFileDescriptor pfd = null;
9942        if (cph != null) {
9943            // We record the binder invoker's uid in thread-local storage before
9944            // going to the content provider to open the file.  Later, in the code
9945            // that handles all permissions checks, we look for this uid and use
9946            // that rather than the Activity Manager's own uid.  The effect is that
9947            // we do the check against the caller's permissions even though it looks
9948            // to the content provider like the Activity Manager itself is making
9949            // the request.
9950            Binder token = new Binder();
9951            sCallerIdentity.set(new Identity(
9952                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9953            try {
9954                pfd = cph.provider.openFile(null, uri, "r", null, token);
9955            } catch (FileNotFoundException e) {
9956                // do nothing; pfd will be returned null
9957            } finally {
9958                // Ensure that whatever happens, we clean up the identity state
9959                sCallerIdentity.remove();
9960            }
9961
9962            // We've got the fd now, so we're done with the provider.
9963            removeContentProviderExternalUnchecked(name, null, userId);
9964        } else {
9965            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9966        }
9967        return pfd;
9968    }
9969
9970    // Actually is sleeping or shutting down or whatever else in the future
9971    // is an inactive state.
9972    public boolean isSleepingOrShuttingDown() {
9973        return isSleeping() || mShuttingDown;
9974    }
9975
9976    public boolean isSleeping() {
9977        return mSleeping;
9978    }
9979
9980    void onWakefulnessChanged(int wakefulness) {
9981        synchronized(this) {
9982            mWakefulness = wakefulness;
9983            updateSleepIfNeededLocked();
9984        }
9985    }
9986
9987    void finishRunningVoiceLocked() {
9988        if (mRunningVoice) {
9989            mRunningVoice = false;
9990            updateSleepIfNeededLocked();
9991        }
9992    }
9993
9994    void updateSleepIfNeededLocked() {
9995        if (mSleeping && !shouldSleepLocked()) {
9996            mSleeping = false;
9997            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9998        } else if (!mSleeping && shouldSleepLocked()) {
9999            mSleeping = true;
10000            mStackSupervisor.goingToSleepLocked();
10001
10002            // Initialize the wake times of all processes.
10003            checkExcessivePowerUsageLocked(false);
10004            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10005            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10006            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10007        }
10008    }
10009
10010    private boolean shouldSleepLocked() {
10011        // Resume applications while running a voice interactor.
10012        if (mRunningVoice) {
10013            return false;
10014        }
10015
10016        switch (mWakefulness) {
10017            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10018            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10019                // If we're interactive but applications are already paused then defer
10020                // resuming them until the lock screen is hidden.
10021                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10022            case PowerManagerInternal.WAKEFULNESS_DOZING:
10023                // If we're dozing then pause applications whenever the lock screen is shown.
10024                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10025            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10026            default:
10027                // If we're asleep then pause applications unconditionally.
10028                return true;
10029        }
10030    }
10031
10032    /** Pokes the task persister. */
10033    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10034        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10035            // Never persist the home stack.
10036            return;
10037        }
10038        mTaskPersister.wakeup(task, flush);
10039    }
10040
10041    /** Notifies all listeners when the task stack has changed. */
10042    void notifyTaskStackChangedLocked() {
10043        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10044        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10045        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10046    }
10047
10048    @Override
10049    public boolean shutdown(int timeout) {
10050        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10051                != PackageManager.PERMISSION_GRANTED) {
10052            throw new SecurityException("Requires permission "
10053                    + android.Manifest.permission.SHUTDOWN);
10054        }
10055
10056        boolean timedout = false;
10057
10058        synchronized(this) {
10059            mShuttingDown = true;
10060            updateEventDispatchingLocked();
10061            timedout = mStackSupervisor.shutdownLocked(timeout);
10062        }
10063
10064        mAppOpsService.shutdown();
10065        if (mUsageStatsService != null) {
10066            mUsageStatsService.prepareShutdown();
10067        }
10068        mBatteryStatsService.shutdown();
10069        synchronized (this) {
10070            mProcessStats.shutdownLocked();
10071            notifyTaskPersisterLocked(null, true);
10072        }
10073
10074        return timedout;
10075    }
10076
10077    public final void activitySlept(IBinder token) {
10078        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10079
10080        final long origId = Binder.clearCallingIdentity();
10081
10082        synchronized (this) {
10083            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10084            if (r != null) {
10085                mStackSupervisor.activitySleptLocked(r);
10086            }
10087        }
10088
10089        Binder.restoreCallingIdentity(origId);
10090    }
10091
10092    private String lockScreenShownToString() {
10093        switch (mLockScreenShown) {
10094            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10095            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10096            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10097            default: return "Unknown=" + mLockScreenShown;
10098        }
10099    }
10100
10101    void logLockScreen(String msg) {
10102        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10103                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10104                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10105                + " mSleeping=" + mSleeping);
10106    }
10107
10108    void startRunningVoiceLocked() {
10109        if (!mRunningVoice) {
10110            mRunningVoice = true;
10111            updateSleepIfNeededLocked();
10112        }
10113    }
10114
10115    private void updateEventDispatchingLocked() {
10116        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10117    }
10118
10119    public void setLockScreenShown(boolean shown) {
10120        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10121                != PackageManager.PERMISSION_GRANTED) {
10122            throw new SecurityException("Requires permission "
10123                    + android.Manifest.permission.DEVICE_POWER);
10124        }
10125
10126        synchronized(this) {
10127            long ident = Binder.clearCallingIdentity();
10128            try {
10129                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10130                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10131                updateSleepIfNeededLocked();
10132            } finally {
10133                Binder.restoreCallingIdentity(ident);
10134            }
10135        }
10136    }
10137
10138    @Override
10139    public void stopAppSwitches() {
10140        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10141                != PackageManager.PERMISSION_GRANTED) {
10142            throw new SecurityException("Requires permission "
10143                    + android.Manifest.permission.STOP_APP_SWITCHES);
10144        }
10145
10146        synchronized(this) {
10147            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10148                    + APP_SWITCH_DELAY_TIME;
10149            mDidAppSwitch = false;
10150            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10151            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10152            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10153        }
10154    }
10155
10156    public void resumeAppSwitches() {
10157        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10158                != PackageManager.PERMISSION_GRANTED) {
10159            throw new SecurityException("Requires permission "
10160                    + android.Manifest.permission.STOP_APP_SWITCHES);
10161        }
10162
10163        synchronized(this) {
10164            // Note that we don't execute any pending app switches... we will
10165            // let those wait until either the timeout, or the next start
10166            // activity request.
10167            mAppSwitchesAllowedTime = 0;
10168        }
10169    }
10170
10171    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10172            int callingPid, int callingUid, String name) {
10173        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10174            return true;
10175        }
10176
10177        int perm = checkComponentPermission(
10178                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10179                sourceUid, -1, true);
10180        if (perm == PackageManager.PERMISSION_GRANTED) {
10181            return true;
10182        }
10183
10184        // If the actual IPC caller is different from the logical source, then
10185        // also see if they are allowed to control app switches.
10186        if (callingUid != -1 && callingUid != sourceUid) {
10187            perm = checkComponentPermission(
10188                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10189                    callingUid, -1, true);
10190            if (perm == PackageManager.PERMISSION_GRANTED) {
10191                return true;
10192            }
10193        }
10194
10195        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10196        return false;
10197    }
10198
10199    public void setDebugApp(String packageName, boolean waitForDebugger,
10200            boolean persistent) {
10201        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10202                "setDebugApp()");
10203
10204        long ident = Binder.clearCallingIdentity();
10205        try {
10206            // Note that this is not really thread safe if there are multiple
10207            // callers into it at the same time, but that's not a situation we
10208            // care about.
10209            if (persistent) {
10210                final ContentResolver resolver = mContext.getContentResolver();
10211                Settings.Global.putString(
10212                    resolver, Settings.Global.DEBUG_APP,
10213                    packageName);
10214                Settings.Global.putInt(
10215                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10216                    waitForDebugger ? 1 : 0);
10217            }
10218
10219            synchronized (this) {
10220                if (!persistent) {
10221                    mOrigDebugApp = mDebugApp;
10222                    mOrigWaitForDebugger = mWaitForDebugger;
10223                }
10224                mDebugApp = packageName;
10225                mWaitForDebugger = waitForDebugger;
10226                mDebugTransient = !persistent;
10227                if (packageName != null) {
10228                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10229                            false, UserHandle.USER_ALL, "set debug app");
10230                }
10231            }
10232        } finally {
10233            Binder.restoreCallingIdentity(ident);
10234        }
10235    }
10236
10237    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10238        synchronized (this) {
10239            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10240            if (!isDebuggable) {
10241                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10242                    throw new SecurityException("Process not debuggable: " + app.packageName);
10243                }
10244            }
10245
10246            mOpenGlTraceApp = processName;
10247        }
10248    }
10249
10250    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10251        synchronized (this) {
10252            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10253            if (!isDebuggable) {
10254                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10255                    throw new SecurityException("Process not debuggable: " + app.packageName);
10256                }
10257            }
10258            mProfileApp = processName;
10259            mProfileFile = profilerInfo.profileFile;
10260            if (mProfileFd != null) {
10261                try {
10262                    mProfileFd.close();
10263                } catch (IOException e) {
10264                }
10265                mProfileFd = null;
10266            }
10267            mProfileFd = profilerInfo.profileFd;
10268            mSamplingInterval = profilerInfo.samplingInterval;
10269            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10270            mProfileType = 0;
10271        }
10272    }
10273
10274    @Override
10275    public void setAlwaysFinish(boolean enabled) {
10276        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10277                "setAlwaysFinish()");
10278
10279        Settings.Global.putInt(
10280                mContext.getContentResolver(),
10281                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10282
10283        synchronized (this) {
10284            mAlwaysFinishActivities = enabled;
10285        }
10286    }
10287
10288    @Override
10289    public void setActivityController(IActivityController controller) {
10290        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10291                "setActivityController()");
10292        synchronized (this) {
10293            mController = controller;
10294            Watchdog.getInstance().setActivityController(controller);
10295        }
10296    }
10297
10298    @Override
10299    public void setUserIsMonkey(boolean userIsMonkey) {
10300        synchronized (this) {
10301            synchronized (mPidsSelfLocked) {
10302                final int callingPid = Binder.getCallingPid();
10303                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10304                if (precessRecord == null) {
10305                    throw new SecurityException("Unknown process: " + callingPid);
10306                }
10307                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10308                    throw new SecurityException("Only an instrumentation process "
10309                            + "with a UiAutomation can call setUserIsMonkey");
10310                }
10311            }
10312            mUserIsMonkey = userIsMonkey;
10313        }
10314    }
10315
10316    @Override
10317    public boolean isUserAMonkey() {
10318        synchronized (this) {
10319            // If there is a controller also implies the user is a monkey.
10320            return (mUserIsMonkey || mController != null);
10321        }
10322    }
10323
10324    public void requestBugReport() {
10325        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10326        SystemProperties.set("ctl.start", "bugreport");
10327    }
10328
10329    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10330        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10331    }
10332
10333    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10334        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10335            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10336        }
10337        return KEY_DISPATCHING_TIMEOUT;
10338    }
10339
10340    @Override
10341    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10342        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10343                != PackageManager.PERMISSION_GRANTED) {
10344            throw new SecurityException("Requires permission "
10345                    + android.Manifest.permission.FILTER_EVENTS);
10346        }
10347        ProcessRecord proc;
10348        long timeout;
10349        synchronized (this) {
10350            synchronized (mPidsSelfLocked) {
10351                proc = mPidsSelfLocked.get(pid);
10352            }
10353            timeout = getInputDispatchingTimeoutLocked(proc);
10354        }
10355
10356        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10357            return -1;
10358        }
10359
10360        return timeout;
10361    }
10362
10363    /**
10364     * Handle input dispatching timeouts.
10365     * Returns whether input dispatching should be aborted or not.
10366     */
10367    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10368            final ActivityRecord activity, final ActivityRecord parent,
10369            final boolean aboveSystem, String reason) {
10370        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10371                != PackageManager.PERMISSION_GRANTED) {
10372            throw new SecurityException("Requires permission "
10373                    + android.Manifest.permission.FILTER_EVENTS);
10374        }
10375
10376        final String annotation;
10377        if (reason == null) {
10378            annotation = "Input dispatching timed out";
10379        } else {
10380            annotation = "Input dispatching timed out (" + reason + ")";
10381        }
10382
10383        if (proc != null) {
10384            synchronized (this) {
10385                if (proc.debugging) {
10386                    return false;
10387                }
10388
10389                if (mDidDexOpt) {
10390                    // Give more time since we were dexopting.
10391                    mDidDexOpt = false;
10392                    return false;
10393                }
10394
10395                if (proc.instrumentationClass != null) {
10396                    Bundle info = new Bundle();
10397                    info.putString("shortMsg", "keyDispatchingTimedOut");
10398                    info.putString("longMsg", annotation);
10399                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10400                    return true;
10401                }
10402            }
10403            mHandler.post(new Runnable() {
10404                @Override
10405                public void run() {
10406                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10407                }
10408            });
10409        }
10410
10411        return true;
10412    }
10413
10414    public Bundle getAssistContextExtras(int requestType) {
10415        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10416                UserHandle.getCallingUserId());
10417        if (pae == null) {
10418            return null;
10419        }
10420        synchronized (pae) {
10421            while (!pae.haveResult) {
10422                try {
10423                    pae.wait();
10424                } catch (InterruptedException e) {
10425                }
10426            }
10427            if (pae.result != null) {
10428                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10429            }
10430        }
10431        synchronized (this) {
10432            mPendingAssistExtras.remove(pae);
10433            mHandler.removeCallbacks(pae);
10434        }
10435        return pae.extras;
10436    }
10437
10438    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10439            int userHandle) {
10440        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10441                "getAssistContextExtras()");
10442        PendingAssistExtras pae;
10443        Bundle extras = new Bundle();
10444        synchronized (this) {
10445            ActivityRecord activity = getFocusedStack().mResumedActivity;
10446            if (activity == null) {
10447                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10448                return null;
10449            }
10450            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10451            if (activity.app == null || activity.app.thread == null) {
10452                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10453                return null;
10454            }
10455            if (activity.app.pid == Binder.getCallingPid()) {
10456                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10457                return null;
10458            }
10459            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10460            try {
10461                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10462                        requestType);
10463                mPendingAssistExtras.add(pae);
10464                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10465            } catch (RemoteException e) {
10466                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10467                return null;
10468            }
10469            return pae;
10470        }
10471    }
10472
10473    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10474        PendingAssistExtras pae = (PendingAssistExtras)token;
10475        synchronized (pae) {
10476            pae.result = extras;
10477            pae.haveResult = true;
10478            pae.notifyAll();
10479            if (pae.intent == null) {
10480                // Caller is just waiting for the result.
10481                return;
10482            }
10483        }
10484
10485        // We are now ready to launch the assist activity.
10486        synchronized (this) {
10487            boolean exists = mPendingAssistExtras.remove(pae);
10488            mHandler.removeCallbacks(pae);
10489            if (!exists) {
10490                // Timed out.
10491                return;
10492            }
10493        }
10494        pae.intent.replaceExtras(extras);
10495        if (pae.hint != null) {
10496            pae.intent.putExtra(pae.hint, true);
10497        }
10498        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10499                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10500                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10501        closeSystemDialogs("assist");
10502        try {
10503            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10504        } catch (ActivityNotFoundException e) {
10505            Slog.w(TAG, "No activity to handle assist action.", e);
10506        }
10507    }
10508
10509    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10510        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10511    }
10512
10513    public void registerProcessObserver(IProcessObserver observer) {
10514        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10515                "registerProcessObserver()");
10516        synchronized (this) {
10517            mProcessObservers.register(observer);
10518        }
10519    }
10520
10521    @Override
10522    public void unregisterProcessObserver(IProcessObserver observer) {
10523        synchronized (this) {
10524            mProcessObservers.unregister(observer);
10525        }
10526    }
10527
10528    @Override
10529    public boolean convertFromTranslucent(IBinder token) {
10530        final long origId = Binder.clearCallingIdentity();
10531        try {
10532            synchronized (this) {
10533                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10534                if (r == null) {
10535                    return false;
10536                }
10537                final boolean translucentChanged = r.changeWindowTranslucency(true);
10538                if (translucentChanged) {
10539                    r.task.stack.releaseBackgroundResources();
10540                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10541                }
10542                mWindowManager.setAppFullscreen(token, true);
10543                return translucentChanged;
10544            }
10545        } finally {
10546            Binder.restoreCallingIdentity(origId);
10547        }
10548    }
10549
10550    @Override
10551    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10552        final long origId = Binder.clearCallingIdentity();
10553        try {
10554            synchronized (this) {
10555                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10556                if (r == null) {
10557                    return false;
10558                }
10559                int index = r.task.mActivities.lastIndexOf(r);
10560                if (index > 0) {
10561                    ActivityRecord under = r.task.mActivities.get(index - 1);
10562                    under.returningOptions = options;
10563                }
10564                final boolean translucentChanged = r.changeWindowTranslucency(false);
10565                if (translucentChanged) {
10566                    r.task.stack.convertToTranslucent(r);
10567                }
10568                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10569                mWindowManager.setAppFullscreen(token, false);
10570                return translucentChanged;
10571            }
10572        } finally {
10573            Binder.restoreCallingIdentity(origId);
10574        }
10575    }
10576
10577    @Override
10578    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10579        final long origId = Binder.clearCallingIdentity();
10580        try {
10581            synchronized (this) {
10582                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10583                if (r != null) {
10584                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10585                }
10586            }
10587            return false;
10588        } finally {
10589            Binder.restoreCallingIdentity(origId);
10590        }
10591    }
10592
10593    @Override
10594    public boolean isBackgroundVisibleBehind(IBinder token) {
10595        final long origId = Binder.clearCallingIdentity();
10596        try {
10597            synchronized (this) {
10598                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10599                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10600                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10601                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10602                return visible;
10603            }
10604        } finally {
10605            Binder.restoreCallingIdentity(origId);
10606        }
10607    }
10608
10609    @Override
10610    public ActivityOptions getActivityOptions(IBinder token) {
10611        final long origId = Binder.clearCallingIdentity();
10612        try {
10613            synchronized (this) {
10614                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10615                if (r != null) {
10616                    final ActivityOptions activityOptions = r.pendingOptions;
10617                    r.pendingOptions = null;
10618                    return activityOptions;
10619                }
10620                return null;
10621            }
10622        } finally {
10623            Binder.restoreCallingIdentity(origId);
10624        }
10625    }
10626
10627    @Override
10628    public void setImmersive(IBinder token, boolean immersive) {
10629        synchronized(this) {
10630            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10631            if (r == null) {
10632                throw new IllegalArgumentException();
10633            }
10634            r.immersive = immersive;
10635
10636            // update associated state if we're frontmost
10637            if (r == mFocusedActivity) {
10638                if (DEBUG_IMMERSIVE) {
10639                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10640                }
10641                applyUpdateLockStateLocked(r);
10642            }
10643        }
10644    }
10645
10646    @Override
10647    public boolean isImmersive(IBinder token) {
10648        synchronized (this) {
10649            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10650            if (r == null) {
10651                throw new IllegalArgumentException();
10652            }
10653            return r.immersive;
10654        }
10655    }
10656
10657    public boolean isTopActivityImmersive() {
10658        enforceNotIsolatedCaller("startActivity");
10659        synchronized (this) {
10660            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10661            return (r != null) ? r.immersive : false;
10662        }
10663    }
10664
10665    @Override
10666    public boolean isTopOfTask(IBinder token) {
10667        synchronized (this) {
10668            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10669            if (r == null) {
10670                throw new IllegalArgumentException();
10671            }
10672            return r.task.getTopActivity() == r;
10673        }
10674    }
10675
10676    public final void enterSafeMode() {
10677        synchronized(this) {
10678            // It only makes sense to do this before the system is ready
10679            // and started launching other packages.
10680            if (!mSystemReady) {
10681                try {
10682                    AppGlobals.getPackageManager().enterSafeMode();
10683                } catch (RemoteException e) {
10684                }
10685            }
10686
10687            mSafeMode = true;
10688        }
10689    }
10690
10691    public final void showSafeModeOverlay() {
10692        View v = LayoutInflater.from(mContext).inflate(
10693                com.android.internal.R.layout.safe_mode, null);
10694        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10695        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10696        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10697        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10698        lp.gravity = Gravity.BOTTOM | Gravity.START;
10699        lp.format = v.getBackground().getOpacity();
10700        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10701                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10702        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10703        ((WindowManager)mContext.getSystemService(
10704                Context.WINDOW_SERVICE)).addView(v, lp);
10705    }
10706
10707    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10708        if (!(sender instanceof PendingIntentRecord)) {
10709            return;
10710        }
10711        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10712        synchronized (stats) {
10713            if (mBatteryStatsService.isOnBattery()) {
10714                mBatteryStatsService.enforceCallingPermission();
10715                PendingIntentRecord rec = (PendingIntentRecord)sender;
10716                int MY_UID = Binder.getCallingUid();
10717                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10718                BatteryStatsImpl.Uid.Pkg pkg =
10719                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10720                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10721                pkg.incWakeupsLocked();
10722            }
10723        }
10724    }
10725
10726    public boolean killPids(int[] pids, String pReason, boolean secure) {
10727        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10728            throw new SecurityException("killPids only available to the system");
10729        }
10730        String reason = (pReason == null) ? "Unknown" : pReason;
10731        // XXX Note: don't acquire main activity lock here, because the window
10732        // manager calls in with its locks held.
10733
10734        boolean killed = false;
10735        synchronized (mPidsSelfLocked) {
10736            int[] types = new int[pids.length];
10737            int worstType = 0;
10738            for (int i=0; i<pids.length; i++) {
10739                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10740                if (proc != null) {
10741                    int type = proc.setAdj;
10742                    types[i] = type;
10743                    if (type > worstType) {
10744                        worstType = type;
10745                    }
10746                }
10747            }
10748
10749            // If the worst oom_adj is somewhere in the cached proc LRU range,
10750            // then constrain it so we will kill all cached procs.
10751            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10752                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10753                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10754            }
10755
10756            // If this is not a secure call, don't let it kill processes that
10757            // are important.
10758            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10759                worstType = ProcessList.SERVICE_ADJ;
10760            }
10761
10762            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10763            for (int i=0; i<pids.length; i++) {
10764                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10765                if (proc == null) {
10766                    continue;
10767                }
10768                int adj = proc.setAdj;
10769                if (adj >= worstType && !proc.killedByAm) {
10770                    proc.kill(reason, true);
10771                    killed = true;
10772                }
10773            }
10774        }
10775        return killed;
10776    }
10777
10778    @Override
10779    public void killUid(int uid, String reason) {
10780        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10781            throw new SecurityException("killUid only available to the system");
10782        }
10783        synchronized (this) {
10784            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10785                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10786                    reason != null ? reason : "kill uid");
10787        }
10788    }
10789
10790    @Override
10791    public boolean killProcessesBelowForeground(String reason) {
10792        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10793            throw new SecurityException("killProcessesBelowForeground() only available to system");
10794        }
10795
10796        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10797    }
10798
10799    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10800        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10801            throw new SecurityException("killProcessesBelowAdj() only available to system");
10802        }
10803
10804        boolean killed = false;
10805        synchronized (mPidsSelfLocked) {
10806            final int size = mPidsSelfLocked.size();
10807            for (int i = 0; i < size; i++) {
10808                final int pid = mPidsSelfLocked.keyAt(i);
10809                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10810                if (proc == null) continue;
10811
10812                final int adj = proc.setAdj;
10813                if (adj > belowAdj && !proc.killedByAm) {
10814                    proc.kill(reason, true);
10815                    killed = true;
10816                }
10817            }
10818        }
10819        return killed;
10820    }
10821
10822    @Override
10823    public void hang(final IBinder who, boolean allowRestart) {
10824        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10825                != PackageManager.PERMISSION_GRANTED) {
10826            throw new SecurityException("Requires permission "
10827                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10828        }
10829
10830        final IBinder.DeathRecipient death = new DeathRecipient() {
10831            @Override
10832            public void binderDied() {
10833                synchronized (this) {
10834                    notifyAll();
10835                }
10836            }
10837        };
10838
10839        try {
10840            who.linkToDeath(death, 0);
10841        } catch (RemoteException e) {
10842            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10843            return;
10844        }
10845
10846        synchronized (this) {
10847            Watchdog.getInstance().setAllowRestart(allowRestart);
10848            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10849            synchronized (death) {
10850                while (who.isBinderAlive()) {
10851                    try {
10852                        death.wait();
10853                    } catch (InterruptedException e) {
10854                    }
10855                }
10856            }
10857            Watchdog.getInstance().setAllowRestart(true);
10858        }
10859    }
10860
10861    @Override
10862    public void restart() {
10863        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10864                != PackageManager.PERMISSION_GRANTED) {
10865            throw new SecurityException("Requires permission "
10866                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10867        }
10868
10869        Log.i(TAG, "Sending shutdown broadcast...");
10870
10871        BroadcastReceiver br = new BroadcastReceiver() {
10872            @Override public void onReceive(Context context, Intent intent) {
10873                // Now the broadcast is done, finish up the low-level shutdown.
10874                Log.i(TAG, "Shutting down activity manager...");
10875                shutdown(10000);
10876                Log.i(TAG, "Shutdown complete, restarting!");
10877                Process.killProcess(Process.myPid());
10878                System.exit(10);
10879            }
10880        };
10881
10882        // First send the high-level shut down broadcast.
10883        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10884        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10885        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10886        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10887        mContext.sendOrderedBroadcastAsUser(intent,
10888                UserHandle.ALL, null, br, mHandler, 0, null, null);
10889        */
10890        br.onReceive(mContext, intent);
10891    }
10892
10893    private long getLowRamTimeSinceIdle(long now) {
10894        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10895    }
10896
10897    @Override
10898    public void performIdleMaintenance() {
10899        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10900                != PackageManager.PERMISSION_GRANTED) {
10901            throw new SecurityException("Requires permission "
10902                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10903        }
10904
10905        synchronized (this) {
10906            final long now = SystemClock.uptimeMillis();
10907            final long timeSinceLastIdle = now - mLastIdleTime;
10908            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10909            mLastIdleTime = now;
10910            mLowRamTimeSinceLastIdle = 0;
10911            if (mLowRamStartTime != 0) {
10912                mLowRamStartTime = now;
10913            }
10914
10915            StringBuilder sb = new StringBuilder(128);
10916            sb.append("Idle maintenance over ");
10917            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10918            sb.append(" low RAM for ");
10919            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10920            Slog.i(TAG, sb.toString());
10921
10922            // If at least 1/3 of our time since the last idle period has been spent
10923            // with RAM low, then we want to kill processes.
10924            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10925
10926            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10927                ProcessRecord proc = mLruProcesses.get(i);
10928                if (proc.notCachedSinceIdle) {
10929                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10930                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10931                        if (doKilling && proc.initialIdlePss != 0
10932                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10933                            sb = new StringBuilder(128);
10934                            sb.append("Kill");
10935                            sb.append(proc.processName);
10936                            sb.append(" in idle maint: pss=");
10937                            sb.append(proc.lastPss);
10938                            sb.append(", initialPss=");
10939                            sb.append(proc.initialIdlePss);
10940                            sb.append(", period=");
10941                            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10942                            sb.append(", lowRamPeriod=");
10943                            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10944                            Slog.wtfQuiet(TAG, sb.toString());
10945                            proc.kill("idle maint (pss " + proc.lastPss
10946                                    + " from " + proc.initialIdlePss + ")", true);
10947                        }
10948                    }
10949                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10950                    proc.notCachedSinceIdle = true;
10951                    proc.initialIdlePss = 0;
10952                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10953                            mTestPssMode, isSleeping(), now);
10954                }
10955            }
10956
10957            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10958            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10959        }
10960    }
10961
10962    private void retrieveSettings() {
10963        final ContentResolver resolver = mContext.getContentResolver();
10964        String debugApp = Settings.Global.getString(
10965            resolver, Settings.Global.DEBUG_APP);
10966        boolean waitForDebugger = Settings.Global.getInt(
10967            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10968        boolean alwaysFinishActivities = Settings.Global.getInt(
10969            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10970        boolean forceRtl = Settings.Global.getInt(
10971                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10972        // Transfer any global setting for forcing RTL layout, into a System Property
10973        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10974
10975        Configuration configuration = new Configuration();
10976        Settings.System.getConfiguration(resolver, configuration);
10977        if (forceRtl) {
10978            // This will take care of setting the correct layout direction flags
10979            configuration.setLayoutDirection(configuration.locale);
10980        }
10981
10982        synchronized (this) {
10983            mDebugApp = mOrigDebugApp = debugApp;
10984            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10985            mAlwaysFinishActivities = alwaysFinishActivities;
10986            // This happens before any activities are started, so we can
10987            // change mConfiguration in-place.
10988            updateConfigurationLocked(configuration, null, false, true);
10989            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10990        }
10991    }
10992
10993    /** Loads resources after the current configuration has been set. */
10994    private void loadResourcesOnSystemReady() {
10995        final Resources res = mContext.getResources();
10996        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10997        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10998        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10999    }
11000
11001    public boolean testIsSystemReady() {
11002        // no need to synchronize(this) just to read & return the value
11003        return mSystemReady;
11004    }
11005
11006    private static File getCalledPreBootReceiversFile() {
11007        File dataDir = Environment.getDataDirectory();
11008        File systemDir = new File(dataDir, "system");
11009        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11010        return fname;
11011    }
11012
11013    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11014        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11015        File file = getCalledPreBootReceiversFile();
11016        FileInputStream fis = null;
11017        try {
11018            fis = new FileInputStream(file);
11019            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11020            int fvers = dis.readInt();
11021            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11022                String vers = dis.readUTF();
11023                String codename = dis.readUTF();
11024                String build = dis.readUTF();
11025                if (android.os.Build.VERSION.RELEASE.equals(vers)
11026                        && android.os.Build.VERSION.CODENAME.equals(codename)
11027                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11028                    int num = dis.readInt();
11029                    while (num > 0) {
11030                        num--;
11031                        String pkg = dis.readUTF();
11032                        String cls = dis.readUTF();
11033                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11034                    }
11035                }
11036            }
11037        } catch (FileNotFoundException e) {
11038        } catch (IOException e) {
11039            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11040        } finally {
11041            if (fis != null) {
11042                try {
11043                    fis.close();
11044                } catch (IOException e) {
11045                }
11046            }
11047        }
11048        return lastDoneReceivers;
11049    }
11050
11051    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11052        File file = getCalledPreBootReceiversFile();
11053        FileOutputStream fos = null;
11054        DataOutputStream dos = null;
11055        try {
11056            fos = new FileOutputStream(file);
11057            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11058            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11059            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11060            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11061            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11062            dos.writeInt(list.size());
11063            for (int i=0; i<list.size(); i++) {
11064                dos.writeUTF(list.get(i).getPackageName());
11065                dos.writeUTF(list.get(i).getClassName());
11066            }
11067        } catch (IOException e) {
11068            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11069            file.delete();
11070        } finally {
11071            FileUtils.sync(fos);
11072            if (dos != null) {
11073                try {
11074                    dos.close();
11075                } catch (IOException e) {
11076                    // TODO Auto-generated catch block
11077                    e.printStackTrace();
11078                }
11079            }
11080        }
11081    }
11082
11083    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11084            ArrayList<ComponentName> doneReceivers, int userId) {
11085        boolean waitingUpdate = false;
11086        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11087        List<ResolveInfo> ris = null;
11088        try {
11089            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11090                    intent, null, 0, userId);
11091        } catch (RemoteException e) {
11092        }
11093        if (ris != null) {
11094            for (int i=ris.size()-1; i>=0; i--) {
11095                if ((ris.get(i).activityInfo.applicationInfo.flags
11096                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11097                    ris.remove(i);
11098                }
11099            }
11100            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11101
11102            // For User 0, load the version number. When delivering to a new user, deliver
11103            // to all receivers.
11104            if (userId == UserHandle.USER_OWNER) {
11105                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11106                for (int i=0; i<ris.size(); i++) {
11107                    ActivityInfo ai = ris.get(i).activityInfo;
11108                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11109                    if (lastDoneReceivers.contains(comp)) {
11110                        // We already did the pre boot receiver for this app with the current
11111                        // platform version, so don't do it again...
11112                        ris.remove(i);
11113                        i--;
11114                        // ...however, do keep it as one that has been done, so we don't
11115                        // forget about it when rewriting the file of last done receivers.
11116                        doneReceivers.add(comp);
11117                    }
11118                }
11119            }
11120
11121            // If primary user, send broadcast to all available users, else just to userId
11122            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11123                    : new int[] { userId };
11124            for (int i = 0; i < ris.size(); i++) {
11125                ActivityInfo ai = ris.get(i).activityInfo;
11126                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11127                doneReceivers.add(comp);
11128                intent.setComponent(comp);
11129                for (int j=0; j<users.length; j++) {
11130                    IIntentReceiver finisher = null;
11131                    // On last receiver and user, set up a completion callback
11132                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11133                        finisher = new IIntentReceiver.Stub() {
11134                            public void performReceive(Intent intent, int resultCode,
11135                                    String data, Bundle extras, boolean ordered,
11136                                    boolean sticky, int sendingUser) {
11137                                // The raw IIntentReceiver interface is called
11138                                // with the AM lock held, so redispatch to
11139                                // execute our code without the lock.
11140                                mHandler.post(onFinishCallback);
11141                            }
11142                        };
11143                    }
11144                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11145                            + " for user " + users[j]);
11146                    broadcastIntentLocked(null, null, intent, null, finisher,
11147                            0, null, null, null, AppOpsManager.OP_NONE,
11148                            true, false, MY_PID, Process.SYSTEM_UID,
11149                            users[j]);
11150                    if (finisher != null) {
11151                        waitingUpdate = true;
11152                    }
11153                }
11154            }
11155        }
11156
11157        return waitingUpdate;
11158    }
11159
11160    public void systemReady(final Runnable goingCallback) {
11161        synchronized(this) {
11162            if (mSystemReady) {
11163                // If we're done calling all the receivers, run the next "boot phase" passed in
11164                // by the SystemServer
11165                if (goingCallback != null) {
11166                    goingCallback.run();
11167                }
11168                return;
11169            }
11170
11171            // Make sure we have the current profile info, since it is needed for
11172            // security checks.
11173            updateCurrentProfileIdsLocked();
11174
11175            if (mRecentTasks == null) {
11176                mRecentTasks = mTaskPersister.restoreTasksLocked();
11177                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11178                if (!mRecentTasks.isEmpty()) {
11179                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11180                }
11181                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11182                mTaskPersister.startPersisting();
11183            }
11184
11185            // Check to see if there are any update receivers to run.
11186            if (!mDidUpdate) {
11187                if (mWaitingUpdate) {
11188                    return;
11189                }
11190                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11191                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11192                    public void run() {
11193                        synchronized (ActivityManagerService.this) {
11194                            mDidUpdate = true;
11195                        }
11196                        writeLastDonePreBootReceivers(doneReceivers);
11197                        showBootMessage(mContext.getText(
11198                                R.string.android_upgrading_complete),
11199                                false);
11200                        systemReady(goingCallback);
11201                    }
11202                }, doneReceivers, UserHandle.USER_OWNER);
11203
11204                if (mWaitingUpdate) {
11205                    return;
11206                }
11207                mDidUpdate = true;
11208            }
11209
11210            mAppOpsService.systemReady();
11211            mSystemReady = true;
11212        }
11213
11214        ArrayList<ProcessRecord> procsToKill = null;
11215        synchronized(mPidsSelfLocked) {
11216            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11217                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11218                if (!isAllowedWhileBooting(proc.info)){
11219                    if (procsToKill == null) {
11220                        procsToKill = new ArrayList<ProcessRecord>();
11221                    }
11222                    procsToKill.add(proc);
11223                }
11224            }
11225        }
11226
11227        synchronized(this) {
11228            if (procsToKill != null) {
11229                for (int i=procsToKill.size()-1; i>=0; i--) {
11230                    ProcessRecord proc = procsToKill.get(i);
11231                    Slog.i(TAG, "Removing system update proc: " + proc);
11232                    removeProcessLocked(proc, true, false, "system update done");
11233                }
11234            }
11235
11236            // Now that we have cleaned up any update processes, we
11237            // are ready to start launching real processes and know that
11238            // we won't trample on them any more.
11239            mProcessesReady = true;
11240        }
11241
11242        Slog.i(TAG, "System now ready");
11243        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11244            SystemClock.uptimeMillis());
11245
11246        synchronized(this) {
11247            // Make sure we have no pre-ready processes sitting around.
11248
11249            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11250                ResolveInfo ri = mContext.getPackageManager()
11251                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11252                                STOCK_PM_FLAGS);
11253                CharSequence errorMsg = null;
11254                if (ri != null) {
11255                    ActivityInfo ai = ri.activityInfo;
11256                    ApplicationInfo app = ai.applicationInfo;
11257                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11258                        mTopAction = Intent.ACTION_FACTORY_TEST;
11259                        mTopData = null;
11260                        mTopComponent = new ComponentName(app.packageName,
11261                                ai.name);
11262                    } else {
11263                        errorMsg = mContext.getResources().getText(
11264                                com.android.internal.R.string.factorytest_not_system);
11265                    }
11266                } else {
11267                    errorMsg = mContext.getResources().getText(
11268                            com.android.internal.R.string.factorytest_no_action);
11269                }
11270                if (errorMsg != null) {
11271                    mTopAction = null;
11272                    mTopData = null;
11273                    mTopComponent = null;
11274                    Message msg = Message.obtain();
11275                    msg.what = SHOW_FACTORY_ERROR_MSG;
11276                    msg.getData().putCharSequence("msg", errorMsg);
11277                    mHandler.sendMessage(msg);
11278                }
11279            }
11280        }
11281
11282        retrieveSettings();
11283        loadResourcesOnSystemReady();
11284
11285        synchronized (this) {
11286            readGrantedUriPermissionsLocked();
11287        }
11288
11289        if (goingCallback != null) goingCallback.run();
11290
11291        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11292                Integer.toString(mCurrentUserId), mCurrentUserId);
11293        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11294                Integer.toString(mCurrentUserId), mCurrentUserId);
11295        mSystemServiceManager.startUser(mCurrentUserId);
11296
11297        synchronized (this) {
11298            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11299                try {
11300                    List apps = AppGlobals.getPackageManager().
11301                        getPersistentApplications(STOCK_PM_FLAGS);
11302                    if (apps != null) {
11303                        int N = apps.size();
11304                        int i;
11305                        for (i=0; i<N; i++) {
11306                            ApplicationInfo info
11307                                = (ApplicationInfo)apps.get(i);
11308                            if (info != null &&
11309                                    !info.packageName.equals("android")) {
11310                                addAppLocked(info, false, null /* ABI override */);
11311                            }
11312                        }
11313                    }
11314                } catch (RemoteException ex) {
11315                    // pm is in same process, this will never happen.
11316                }
11317            }
11318
11319            // Start up initial activity.
11320            mBooting = true;
11321            startHomeActivityLocked(mCurrentUserId);
11322
11323            try {
11324                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11325                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11326                            + " data partition or your device will be unstable.");
11327                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11328                }
11329            } catch (RemoteException e) {
11330            }
11331
11332            if (!Build.isFingerprintConsistent()) {
11333                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11334                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11335            }
11336
11337            long ident = Binder.clearCallingIdentity();
11338            try {
11339                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11340                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11341                        | Intent.FLAG_RECEIVER_FOREGROUND);
11342                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11343                broadcastIntentLocked(null, null, intent,
11344                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11345                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11346                intent = new Intent(Intent.ACTION_USER_STARTING);
11347                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11348                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11349                broadcastIntentLocked(null, null, intent,
11350                        null, new IIntentReceiver.Stub() {
11351                            @Override
11352                            public void performReceive(Intent intent, int resultCode, String data,
11353                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11354                                    throws RemoteException {
11355                            }
11356                        }, 0, null, null,
11357                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11358                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11359            } catch (Throwable t) {
11360                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11361            } finally {
11362                Binder.restoreCallingIdentity(ident);
11363            }
11364            mStackSupervisor.resumeTopActivitiesLocked();
11365            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11366        }
11367    }
11368
11369    private boolean makeAppCrashingLocked(ProcessRecord app,
11370            String shortMsg, String longMsg, String stackTrace) {
11371        app.crashing = true;
11372        app.crashingReport = generateProcessError(app,
11373                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11374        startAppProblemLocked(app);
11375        app.stopFreezingAllLocked();
11376        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11377    }
11378
11379    private void makeAppNotRespondingLocked(ProcessRecord app,
11380            String activity, String shortMsg, String longMsg) {
11381        app.notResponding = true;
11382        app.notRespondingReport = generateProcessError(app,
11383                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11384                activity, shortMsg, longMsg, null);
11385        startAppProblemLocked(app);
11386        app.stopFreezingAllLocked();
11387    }
11388
11389    /**
11390     * Generate a process error record, suitable for attachment to a ProcessRecord.
11391     *
11392     * @param app The ProcessRecord in which the error occurred.
11393     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11394     *                      ActivityManager.AppErrorStateInfo
11395     * @param activity The activity associated with the crash, if known.
11396     * @param shortMsg Short message describing the crash.
11397     * @param longMsg Long message describing the crash.
11398     * @param stackTrace Full crash stack trace, may be null.
11399     *
11400     * @return Returns a fully-formed AppErrorStateInfo record.
11401     */
11402    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11403            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11404        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11405
11406        report.condition = condition;
11407        report.processName = app.processName;
11408        report.pid = app.pid;
11409        report.uid = app.info.uid;
11410        report.tag = activity;
11411        report.shortMsg = shortMsg;
11412        report.longMsg = longMsg;
11413        report.stackTrace = stackTrace;
11414
11415        return report;
11416    }
11417
11418    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11419        synchronized (this) {
11420            app.crashing = false;
11421            app.crashingReport = null;
11422            app.notResponding = false;
11423            app.notRespondingReport = null;
11424            if (app.anrDialog == fromDialog) {
11425                app.anrDialog = null;
11426            }
11427            if (app.waitDialog == fromDialog) {
11428                app.waitDialog = null;
11429            }
11430            if (app.pid > 0 && app.pid != MY_PID) {
11431                handleAppCrashLocked(app, null, null, null);
11432                app.kill("user request after error", true);
11433            }
11434        }
11435    }
11436
11437    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11438            String stackTrace) {
11439        long now = SystemClock.uptimeMillis();
11440
11441        Long crashTime;
11442        if (!app.isolated) {
11443            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11444        } else {
11445            crashTime = null;
11446        }
11447        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11448            // This process loses!
11449            Slog.w(TAG, "Process " + app.info.processName
11450                    + " has crashed too many times: killing!");
11451            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11452                    app.userId, app.info.processName, app.uid);
11453            mStackSupervisor.handleAppCrashLocked(app);
11454            if (!app.persistent) {
11455                // We don't want to start this process again until the user
11456                // explicitly does so...  but for persistent process, we really
11457                // need to keep it running.  If a persistent process is actually
11458                // repeatedly crashing, then badness for everyone.
11459                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11460                        app.info.processName);
11461                if (!app.isolated) {
11462                    // XXX We don't have a way to mark isolated processes
11463                    // as bad, since they don't have a peristent identity.
11464                    mBadProcesses.put(app.info.processName, app.uid,
11465                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11466                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11467                }
11468                app.bad = true;
11469                app.removed = true;
11470                // Don't let services in this process be restarted and potentially
11471                // annoy the user repeatedly.  Unless it is persistent, since those
11472                // processes run critical code.
11473                removeProcessLocked(app, false, false, "crash");
11474                mStackSupervisor.resumeTopActivitiesLocked();
11475                return false;
11476            }
11477            mStackSupervisor.resumeTopActivitiesLocked();
11478        } else {
11479            mStackSupervisor.finishTopRunningActivityLocked(app);
11480        }
11481
11482        // Bump up the crash count of any services currently running in the proc.
11483        for (int i=app.services.size()-1; i>=0; i--) {
11484            // Any services running in the application need to be placed
11485            // back in the pending list.
11486            ServiceRecord sr = app.services.valueAt(i);
11487            sr.crashCount++;
11488        }
11489
11490        // If the crashing process is what we consider to be the "home process" and it has been
11491        // replaced by a third-party app, clear the package preferred activities from packages
11492        // with a home activity running in the process to prevent a repeatedly crashing app
11493        // from blocking the user to manually clear the list.
11494        final ArrayList<ActivityRecord> activities = app.activities;
11495        if (app == mHomeProcess && activities.size() > 0
11496                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11497            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11498                final ActivityRecord r = activities.get(activityNdx);
11499                if (r.isHomeActivity()) {
11500                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11501                    try {
11502                        ActivityThread.getPackageManager()
11503                                .clearPackagePreferredActivities(r.packageName);
11504                    } catch (RemoteException c) {
11505                        // pm is in same process, this will never happen.
11506                    }
11507                }
11508            }
11509        }
11510
11511        if (!app.isolated) {
11512            // XXX Can't keep track of crash times for isolated processes,
11513            // because they don't have a perisistent identity.
11514            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11515        }
11516
11517        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11518        return true;
11519    }
11520
11521    void startAppProblemLocked(ProcessRecord app) {
11522        // If this app is not running under the current user, then we
11523        // can't give it a report button because that would require
11524        // launching the report UI under a different user.
11525        app.errorReportReceiver = null;
11526
11527        for (int userId : mCurrentProfileIds) {
11528            if (app.userId == userId) {
11529                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11530                        mContext, app.info.packageName, app.info.flags);
11531            }
11532        }
11533        skipCurrentReceiverLocked(app);
11534    }
11535
11536    void skipCurrentReceiverLocked(ProcessRecord app) {
11537        for (BroadcastQueue queue : mBroadcastQueues) {
11538            queue.skipCurrentReceiverLocked(app);
11539        }
11540    }
11541
11542    /**
11543     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11544     * The application process will exit immediately after this call returns.
11545     * @param app object of the crashing app, null for the system server
11546     * @param crashInfo describing the exception
11547     */
11548    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11549        ProcessRecord r = findAppProcess(app, "Crash");
11550        final String processName = app == null ? "system_server"
11551                : (r == null ? "unknown" : r.processName);
11552
11553        handleApplicationCrashInner("crash", r, processName, crashInfo);
11554    }
11555
11556    /* Native crash reporting uses this inner version because it needs to be somewhat
11557     * decoupled from the AM-managed cleanup lifecycle
11558     */
11559    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11560            ApplicationErrorReport.CrashInfo crashInfo) {
11561        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11562                UserHandle.getUserId(Binder.getCallingUid()), processName,
11563                r == null ? -1 : r.info.flags,
11564                crashInfo.exceptionClassName,
11565                crashInfo.exceptionMessage,
11566                crashInfo.throwFileName,
11567                crashInfo.throwLineNumber);
11568
11569        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11570
11571        crashApplication(r, crashInfo);
11572    }
11573
11574    public void handleApplicationStrictModeViolation(
11575            IBinder app,
11576            int violationMask,
11577            StrictMode.ViolationInfo info) {
11578        ProcessRecord r = findAppProcess(app, "StrictMode");
11579        if (r == null) {
11580            return;
11581        }
11582
11583        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11584            Integer stackFingerprint = info.hashCode();
11585            boolean logIt = true;
11586            synchronized (mAlreadyLoggedViolatedStacks) {
11587                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11588                    logIt = false;
11589                    // TODO: sub-sample into EventLog for these, with
11590                    // the info.durationMillis?  Then we'd get
11591                    // the relative pain numbers, without logging all
11592                    // the stack traces repeatedly.  We'd want to do
11593                    // likewise in the client code, which also does
11594                    // dup suppression, before the Binder call.
11595                } else {
11596                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11597                        mAlreadyLoggedViolatedStacks.clear();
11598                    }
11599                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11600                }
11601            }
11602            if (logIt) {
11603                logStrictModeViolationToDropBox(r, info);
11604            }
11605        }
11606
11607        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11608            AppErrorResult result = new AppErrorResult();
11609            synchronized (this) {
11610                final long origId = Binder.clearCallingIdentity();
11611
11612                Message msg = Message.obtain();
11613                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11614                HashMap<String, Object> data = new HashMap<String, Object>();
11615                data.put("result", result);
11616                data.put("app", r);
11617                data.put("violationMask", violationMask);
11618                data.put("info", info);
11619                msg.obj = data;
11620                mHandler.sendMessage(msg);
11621
11622                Binder.restoreCallingIdentity(origId);
11623            }
11624            int res = result.get();
11625            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11626        }
11627    }
11628
11629    // Depending on the policy in effect, there could be a bunch of
11630    // these in quick succession so we try to batch these together to
11631    // minimize disk writes, number of dropbox entries, and maximize
11632    // compression, by having more fewer, larger records.
11633    private void logStrictModeViolationToDropBox(
11634            ProcessRecord process,
11635            StrictMode.ViolationInfo info) {
11636        if (info == null) {
11637            return;
11638        }
11639        final boolean isSystemApp = process == null ||
11640                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11641                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11642        final String processName = process == null ? "unknown" : process.processName;
11643        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11644        final DropBoxManager dbox = (DropBoxManager)
11645                mContext.getSystemService(Context.DROPBOX_SERVICE);
11646
11647        // Exit early if the dropbox isn't configured to accept this report type.
11648        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11649
11650        boolean bufferWasEmpty;
11651        boolean needsFlush;
11652        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11653        synchronized (sb) {
11654            bufferWasEmpty = sb.length() == 0;
11655            appendDropBoxProcessHeaders(process, processName, sb);
11656            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11657            sb.append("System-App: ").append(isSystemApp).append("\n");
11658            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11659            if (info.violationNumThisLoop != 0) {
11660                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11661            }
11662            if (info.numAnimationsRunning != 0) {
11663                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11664            }
11665            if (info.broadcastIntentAction != null) {
11666                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11667            }
11668            if (info.durationMillis != -1) {
11669                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11670            }
11671            if (info.numInstances != -1) {
11672                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11673            }
11674            if (info.tags != null) {
11675                for (String tag : info.tags) {
11676                    sb.append("Span-Tag: ").append(tag).append("\n");
11677                }
11678            }
11679            sb.append("\n");
11680            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11681                sb.append(info.crashInfo.stackTrace);
11682            }
11683            sb.append("\n");
11684
11685            // Only buffer up to ~64k.  Various logging bits truncate
11686            // things at 128k.
11687            needsFlush = (sb.length() > 64 * 1024);
11688        }
11689
11690        // Flush immediately if the buffer's grown too large, or this
11691        // is a non-system app.  Non-system apps are isolated with a
11692        // different tag & policy and not batched.
11693        //
11694        // Batching is useful during internal testing with
11695        // StrictMode settings turned up high.  Without batching,
11696        // thousands of separate files could be created on boot.
11697        if (!isSystemApp || needsFlush) {
11698            new Thread("Error dump: " + dropboxTag) {
11699                @Override
11700                public void run() {
11701                    String report;
11702                    synchronized (sb) {
11703                        report = sb.toString();
11704                        sb.delete(0, sb.length());
11705                        sb.trimToSize();
11706                    }
11707                    if (report.length() != 0) {
11708                        dbox.addText(dropboxTag, report);
11709                    }
11710                }
11711            }.start();
11712            return;
11713        }
11714
11715        // System app batching:
11716        if (!bufferWasEmpty) {
11717            // An existing dropbox-writing thread is outstanding, so
11718            // we don't need to start it up.  The existing thread will
11719            // catch the buffer appends we just did.
11720            return;
11721        }
11722
11723        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11724        // (After this point, we shouldn't access AMS internal data structures.)
11725        new Thread("Error dump: " + dropboxTag) {
11726            @Override
11727            public void run() {
11728                // 5 second sleep to let stacks arrive and be batched together
11729                try {
11730                    Thread.sleep(5000);  // 5 seconds
11731                } catch (InterruptedException e) {}
11732
11733                String errorReport;
11734                synchronized (mStrictModeBuffer) {
11735                    errorReport = mStrictModeBuffer.toString();
11736                    if (errorReport.length() == 0) {
11737                        return;
11738                    }
11739                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11740                    mStrictModeBuffer.trimToSize();
11741                }
11742                dbox.addText(dropboxTag, errorReport);
11743            }
11744        }.start();
11745    }
11746
11747    /**
11748     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11749     * @param app object of the crashing app, null for the system server
11750     * @param tag reported by the caller
11751     * @param system whether this wtf is coming from the system
11752     * @param crashInfo describing the context of the error
11753     * @return true if the process should exit immediately (WTF is fatal)
11754     */
11755    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11756            final ApplicationErrorReport.CrashInfo crashInfo) {
11757        final int callingUid = Binder.getCallingUid();
11758        final int callingPid = Binder.getCallingPid();
11759
11760        if (system) {
11761            // If this is coming from the system, we could very well have low-level
11762            // system locks held, so we want to do this all asynchronously.  And we
11763            // never want this to become fatal, so there is that too.
11764            mHandler.post(new Runnable() {
11765                @Override public void run() {
11766                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11767                }
11768            });
11769            return false;
11770        }
11771
11772        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11773                crashInfo);
11774
11775        if (r != null && r.pid != Process.myPid() &&
11776                Settings.Global.getInt(mContext.getContentResolver(),
11777                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11778            crashApplication(r, crashInfo);
11779            return true;
11780        } else {
11781            return false;
11782        }
11783    }
11784
11785    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11786            final ApplicationErrorReport.CrashInfo crashInfo) {
11787        final ProcessRecord r = findAppProcess(app, "WTF");
11788        final String processName = app == null ? "system_server"
11789                : (r == null ? "unknown" : r.processName);
11790
11791        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11792                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11793
11794        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11795
11796        return r;
11797    }
11798
11799    /**
11800     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11801     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11802     */
11803    private ProcessRecord findAppProcess(IBinder app, String reason) {
11804        if (app == null) {
11805            return null;
11806        }
11807
11808        synchronized (this) {
11809            final int NP = mProcessNames.getMap().size();
11810            for (int ip=0; ip<NP; ip++) {
11811                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11812                final int NA = apps.size();
11813                for (int ia=0; ia<NA; ia++) {
11814                    ProcessRecord p = apps.valueAt(ia);
11815                    if (p.thread != null && p.thread.asBinder() == app) {
11816                        return p;
11817                    }
11818                }
11819            }
11820
11821            Slog.w(TAG, "Can't find mystery application for " + reason
11822                    + " from pid=" + Binder.getCallingPid()
11823                    + " uid=" + Binder.getCallingUid() + ": " + app);
11824            return null;
11825        }
11826    }
11827
11828    /**
11829     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11830     * to append various headers to the dropbox log text.
11831     */
11832    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11833            StringBuilder sb) {
11834        // Watchdog thread ends up invoking this function (with
11835        // a null ProcessRecord) to add the stack file to dropbox.
11836        // Do not acquire a lock on this (am) in such cases, as it
11837        // could cause a potential deadlock, if and when watchdog
11838        // is invoked due to unavailability of lock on am and it
11839        // would prevent watchdog from killing system_server.
11840        if (process == null) {
11841            sb.append("Process: ").append(processName).append("\n");
11842            return;
11843        }
11844        // Note: ProcessRecord 'process' is guarded by the service
11845        // instance.  (notably process.pkgList, which could otherwise change
11846        // concurrently during execution of this method)
11847        synchronized (this) {
11848            sb.append("Process: ").append(processName).append("\n");
11849            int flags = process.info.flags;
11850            IPackageManager pm = AppGlobals.getPackageManager();
11851            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11852            for (int ip=0; ip<process.pkgList.size(); ip++) {
11853                String pkg = process.pkgList.keyAt(ip);
11854                sb.append("Package: ").append(pkg);
11855                try {
11856                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11857                    if (pi != null) {
11858                        sb.append(" v").append(pi.versionCode);
11859                        if (pi.versionName != null) {
11860                            sb.append(" (").append(pi.versionName).append(")");
11861                        }
11862                    }
11863                } catch (RemoteException e) {
11864                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11865                }
11866                sb.append("\n");
11867            }
11868        }
11869    }
11870
11871    private static String processClass(ProcessRecord process) {
11872        if (process == null || process.pid == MY_PID) {
11873            return "system_server";
11874        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11875            return "system_app";
11876        } else {
11877            return "data_app";
11878        }
11879    }
11880
11881    /**
11882     * Write a description of an error (crash, WTF, ANR) to the drop box.
11883     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11884     * @param process which caused the error, null means the system server
11885     * @param activity which triggered the error, null if unknown
11886     * @param parent activity related to the error, null if unknown
11887     * @param subject line related to the error, null if absent
11888     * @param report in long form describing the error, null if absent
11889     * @param logFile to include in the report, null if none
11890     * @param crashInfo giving an application stack trace, null if absent
11891     */
11892    public void addErrorToDropBox(String eventType,
11893            ProcessRecord process, String processName, ActivityRecord activity,
11894            ActivityRecord parent, String subject,
11895            final String report, final File logFile,
11896            final ApplicationErrorReport.CrashInfo crashInfo) {
11897        // NOTE -- this must never acquire the ActivityManagerService lock,
11898        // otherwise the watchdog may be prevented from resetting the system.
11899
11900        final String dropboxTag = processClass(process) + "_" + eventType;
11901        final DropBoxManager dbox = (DropBoxManager)
11902                mContext.getSystemService(Context.DROPBOX_SERVICE);
11903
11904        // Exit early if the dropbox isn't configured to accept this report type.
11905        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11906
11907        final StringBuilder sb = new StringBuilder(1024);
11908        appendDropBoxProcessHeaders(process, processName, sb);
11909        if (activity != null) {
11910            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11911        }
11912        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11913            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11914        }
11915        if (parent != null && parent != activity) {
11916            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11917        }
11918        if (subject != null) {
11919            sb.append("Subject: ").append(subject).append("\n");
11920        }
11921        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11922        if (Debug.isDebuggerConnected()) {
11923            sb.append("Debugger: Connected\n");
11924        }
11925        sb.append("\n");
11926
11927        // Do the rest in a worker thread to avoid blocking the caller on I/O
11928        // (After this point, we shouldn't access AMS internal data structures.)
11929        Thread worker = new Thread("Error dump: " + dropboxTag) {
11930            @Override
11931            public void run() {
11932                if (report != null) {
11933                    sb.append(report);
11934                }
11935                if (logFile != null) {
11936                    try {
11937                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11938                                    "\n\n[[TRUNCATED]]"));
11939                    } catch (IOException e) {
11940                        Slog.e(TAG, "Error reading " + logFile, e);
11941                    }
11942                }
11943                if (crashInfo != null && crashInfo.stackTrace != null) {
11944                    sb.append(crashInfo.stackTrace);
11945                }
11946
11947                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11948                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11949                if (lines > 0) {
11950                    sb.append("\n");
11951
11952                    // Merge several logcat streams, and take the last N lines
11953                    InputStreamReader input = null;
11954                    try {
11955                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11956                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11957                                "-b", "crash",
11958                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11959
11960                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11961                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11962                        input = new InputStreamReader(logcat.getInputStream());
11963
11964                        int num;
11965                        char[] buf = new char[8192];
11966                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11967                    } catch (IOException e) {
11968                        Slog.e(TAG, "Error running logcat", e);
11969                    } finally {
11970                        if (input != null) try { input.close(); } catch (IOException e) {}
11971                    }
11972                }
11973
11974                dbox.addText(dropboxTag, sb.toString());
11975            }
11976        };
11977
11978        if (process == null) {
11979            // If process is null, we are being called from some internal code
11980            // and may be about to die -- run this synchronously.
11981            worker.run();
11982        } else {
11983            worker.start();
11984        }
11985    }
11986
11987    /**
11988     * Bring up the "unexpected error" dialog box for a crashing app.
11989     * Deal with edge cases (intercepts from instrumented applications,
11990     * ActivityController, error intent receivers, that sort of thing).
11991     * @param r the application crashing
11992     * @param crashInfo describing the failure
11993     */
11994    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11995        long timeMillis = System.currentTimeMillis();
11996        String shortMsg = crashInfo.exceptionClassName;
11997        String longMsg = crashInfo.exceptionMessage;
11998        String stackTrace = crashInfo.stackTrace;
11999        if (shortMsg != null && longMsg != null) {
12000            longMsg = shortMsg + ": " + longMsg;
12001        } else if (shortMsg != null) {
12002            longMsg = shortMsg;
12003        }
12004
12005        AppErrorResult result = new AppErrorResult();
12006        synchronized (this) {
12007            if (mController != null) {
12008                try {
12009                    String name = r != null ? r.processName : null;
12010                    int pid = r != null ? r.pid : Binder.getCallingPid();
12011                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12012                    if (!mController.appCrashed(name, pid,
12013                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12014                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12015                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12016                            Slog.w(TAG, "Skip killing native crashed app " + name
12017                                    + "(" + pid + ") during testing");
12018                        } else {
12019                            Slog.w(TAG, "Force-killing crashed app " + name
12020                                    + " at watcher's request");
12021                            if (r != null) {
12022                                r.kill("crash", true);
12023                            } else {
12024                                // Huh.
12025                                Process.killProcess(pid);
12026                                Process.killProcessGroup(uid, pid);
12027                            }
12028                        }
12029                        return;
12030                    }
12031                } catch (RemoteException e) {
12032                    mController = null;
12033                    Watchdog.getInstance().setActivityController(null);
12034                }
12035            }
12036
12037            final long origId = Binder.clearCallingIdentity();
12038
12039            // If this process is running instrumentation, finish it.
12040            if (r != null && r.instrumentationClass != null) {
12041                Slog.w(TAG, "Error in app " + r.processName
12042                      + " running instrumentation " + r.instrumentationClass + ":");
12043                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12044                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12045                Bundle info = new Bundle();
12046                info.putString("shortMsg", shortMsg);
12047                info.putString("longMsg", longMsg);
12048                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12049                Binder.restoreCallingIdentity(origId);
12050                return;
12051            }
12052
12053            // Log crash in battery stats.
12054            if (r != null) {
12055                mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12056            }
12057
12058            // If we can't identify the process or it's already exceeded its crash quota,
12059            // quit right away without showing a crash dialog.
12060            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12061                Binder.restoreCallingIdentity(origId);
12062                return;
12063            }
12064
12065            Message msg = Message.obtain();
12066            msg.what = SHOW_ERROR_MSG;
12067            HashMap data = new HashMap();
12068            data.put("result", result);
12069            data.put("app", r);
12070            msg.obj = data;
12071            mHandler.sendMessage(msg);
12072
12073            Binder.restoreCallingIdentity(origId);
12074        }
12075
12076        int res = result.get();
12077
12078        Intent appErrorIntent = null;
12079        synchronized (this) {
12080            if (r != null && !r.isolated) {
12081                // XXX Can't keep track of crash time for isolated processes,
12082                // since they don't have a persistent identity.
12083                mProcessCrashTimes.put(r.info.processName, r.uid,
12084                        SystemClock.uptimeMillis());
12085            }
12086            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12087                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12088            }
12089        }
12090
12091        if (appErrorIntent != null) {
12092            try {
12093                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12094            } catch (ActivityNotFoundException e) {
12095                Slog.w(TAG, "bug report receiver dissappeared", e);
12096            }
12097        }
12098    }
12099
12100    Intent createAppErrorIntentLocked(ProcessRecord r,
12101            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12102        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12103        if (report == null) {
12104            return null;
12105        }
12106        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12107        result.setComponent(r.errorReportReceiver);
12108        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12109        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12110        return result;
12111    }
12112
12113    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12114            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12115        if (r.errorReportReceiver == null) {
12116            return null;
12117        }
12118
12119        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12120            return null;
12121        }
12122
12123        ApplicationErrorReport report = new ApplicationErrorReport();
12124        report.packageName = r.info.packageName;
12125        report.installerPackageName = r.errorReportReceiver.getPackageName();
12126        report.processName = r.processName;
12127        report.time = timeMillis;
12128        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12129
12130        if (r.crashing || r.forceCrashReport) {
12131            report.type = ApplicationErrorReport.TYPE_CRASH;
12132            report.crashInfo = crashInfo;
12133        } else if (r.notResponding) {
12134            report.type = ApplicationErrorReport.TYPE_ANR;
12135            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12136
12137            report.anrInfo.activity = r.notRespondingReport.tag;
12138            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12139            report.anrInfo.info = r.notRespondingReport.longMsg;
12140        }
12141
12142        return report;
12143    }
12144
12145    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12146        enforceNotIsolatedCaller("getProcessesInErrorState");
12147        // assume our apps are happy - lazy create the list
12148        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12149
12150        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12151                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12152        int userId = UserHandle.getUserId(Binder.getCallingUid());
12153
12154        synchronized (this) {
12155
12156            // iterate across all processes
12157            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12158                ProcessRecord app = mLruProcesses.get(i);
12159                if (!allUsers && app.userId != userId) {
12160                    continue;
12161                }
12162                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12163                    // This one's in trouble, so we'll generate a report for it
12164                    // crashes are higher priority (in case there's a crash *and* an anr)
12165                    ActivityManager.ProcessErrorStateInfo report = null;
12166                    if (app.crashing) {
12167                        report = app.crashingReport;
12168                    } else if (app.notResponding) {
12169                        report = app.notRespondingReport;
12170                    }
12171
12172                    if (report != null) {
12173                        if (errList == null) {
12174                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12175                        }
12176                        errList.add(report);
12177                    } else {
12178                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12179                                " crashing = " + app.crashing +
12180                                " notResponding = " + app.notResponding);
12181                    }
12182                }
12183            }
12184        }
12185
12186        return errList;
12187    }
12188
12189    static int procStateToImportance(int procState, int memAdj,
12190            ActivityManager.RunningAppProcessInfo currApp) {
12191        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12192        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12193            currApp.lru = memAdj;
12194        } else {
12195            currApp.lru = 0;
12196        }
12197        return imp;
12198    }
12199
12200    private void fillInProcMemInfo(ProcessRecord app,
12201            ActivityManager.RunningAppProcessInfo outInfo) {
12202        outInfo.pid = app.pid;
12203        outInfo.uid = app.info.uid;
12204        if (mHeavyWeightProcess == app) {
12205            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12206        }
12207        if (app.persistent) {
12208            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12209        }
12210        if (app.activities.size() > 0) {
12211            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12212        }
12213        outInfo.lastTrimLevel = app.trimMemoryLevel;
12214        int adj = app.curAdj;
12215        int procState = app.curProcState;
12216        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12217        outInfo.importanceReasonCode = app.adjTypeCode;
12218        outInfo.processState = app.curProcState;
12219    }
12220
12221    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12222        enforceNotIsolatedCaller("getRunningAppProcesses");
12223        // Lazy instantiation of list
12224        List<ActivityManager.RunningAppProcessInfo> runList = null;
12225        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12226                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12227        int userId = UserHandle.getUserId(Binder.getCallingUid());
12228        synchronized (this) {
12229            // Iterate across all processes
12230            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12231                ProcessRecord app = mLruProcesses.get(i);
12232                if (!allUsers && app.userId != userId) {
12233                    continue;
12234                }
12235                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12236                    // Generate process state info for running application
12237                    ActivityManager.RunningAppProcessInfo currApp =
12238                        new ActivityManager.RunningAppProcessInfo(app.processName,
12239                                app.pid, app.getPackageList());
12240                    fillInProcMemInfo(app, currApp);
12241                    if (app.adjSource instanceof ProcessRecord) {
12242                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12243                        currApp.importanceReasonImportance =
12244                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12245                                        app.adjSourceProcState);
12246                    } else if (app.adjSource instanceof ActivityRecord) {
12247                        ActivityRecord r = (ActivityRecord)app.adjSource;
12248                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12249                    }
12250                    if (app.adjTarget instanceof ComponentName) {
12251                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12252                    }
12253                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12254                    //        + " lru=" + currApp.lru);
12255                    if (runList == null) {
12256                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12257                    }
12258                    runList.add(currApp);
12259                }
12260            }
12261        }
12262        return runList;
12263    }
12264
12265    public List<ApplicationInfo> getRunningExternalApplications() {
12266        enforceNotIsolatedCaller("getRunningExternalApplications");
12267        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12268        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12269        if (runningApps != null && runningApps.size() > 0) {
12270            Set<String> extList = new HashSet<String>();
12271            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12272                if (app.pkgList != null) {
12273                    for (String pkg : app.pkgList) {
12274                        extList.add(pkg);
12275                    }
12276                }
12277            }
12278            IPackageManager pm = AppGlobals.getPackageManager();
12279            for (String pkg : extList) {
12280                try {
12281                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12282                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12283                        retList.add(info);
12284                    }
12285                } catch (RemoteException e) {
12286                }
12287            }
12288        }
12289        return retList;
12290    }
12291
12292    @Override
12293    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12294        enforceNotIsolatedCaller("getMyMemoryState");
12295        synchronized (this) {
12296            ProcessRecord proc;
12297            synchronized (mPidsSelfLocked) {
12298                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12299            }
12300            fillInProcMemInfo(proc, outInfo);
12301        }
12302    }
12303
12304    @Override
12305    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12306        if (checkCallingPermission(android.Manifest.permission.DUMP)
12307                != PackageManager.PERMISSION_GRANTED) {
12308            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12309                    + Binder.getCallingPid()
12310                    + ", uid=" + Binder.getCallingUid()
12311                    + " without permission "
12312                    + android.Manifest.permission.DUMP);
12313            return;
12314        }
12315
12316        boolean dumpAll = false;
12317        boolean dumpClient = false;
12318        String dumpPackage = null;
12319
12320        int opti = 0;
12321        while (opti < args.length) {
12322            String opt = args[opti];
12323            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12324                break;
12325            }
12326            opti++;
12327            if ("-a".equals(opt)) {
12328                dumpAll = true;
12329            } else if ("-c".equals(opt)) {
12330                dumpClient = true;
12331            } else if ("-h".equals(opt)) {
12332                pw.println("Activity manager dump options:");
12333                pw.println("  [-a] [-c] [-h] [cmd] ...");
12334                pw.println("  cmd may be one of:");
12335                pw.println("    a[ctivities]: activity stack state");
12336                pw.println("    r[recents]: recent activities state");
12337                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12338                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12339                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12340                pw.println("    o[om]: out of memory management");
12341                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12342                pw.println("    provider [COMP_SPEC]: provider client-side state");
12343                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12344                pw.println("    service [COMP_SPEC]: service client-side state");
12345                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12346                pw.println("    all: dump all activities");
12347                pw.println("    top: dump the top activity");
12348                pw.println("    write: write all pending state to storage");
12349                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12350                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12351                pw.println("    a partial substring in a component name, a");
12352                pw.println("    hex object identifier.");
12353                pw.println("  -a: include all available server state.");
12354                pw.println("  -c: include client state.");
12355                return;
12356            } else {
12357                pw.println("Unknown argument: " + opt + "; use -h for help");
12358            }
12359        }
12360
12361        long origId = Binder.clearCallingIdentity();
12362        boolean more = false;
12363        // Is the caller requesting to dump a particular piece of data?
12364        if (opti < args.length) {
12365            String cmd = args[opti];
12366            opti++;
12367            if ("activities".equals(cmd) || "a".equals(cmd)) {
12368                synchronized (this) {
12369                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12370                }
12371            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12372                synchronized (this) {
12373                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12374                }
12375            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12376                String[] newArgs;
12377                String name;
12378                if (opti >= args.length) {
12379                    name = null;
12380                    newArgs = EMPTY_STRING_ARRAY;
12381                } else {
12382                    name = args[opti];
12383                    opti++;
12384                    newArgs = new String[args.length - opti];
12385                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12386                            args.length - opti);
12387                }
12388                synchronized (this) {
12389                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12390                }
12391            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12392                String[] newArgs;
12393                String name;
12394                if (opti >= args.length) {
12395                    name = null;
12396                    newArgs = EMPTY_STRING_ARRAY;
12397                } else {
12398                    name = args[opti];
12399                    opti++;
12400                    newArgs = new String[args.length - opti];
12401                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12402                            args.length - opti);
12403                }
12404                synchronized (this) {
12405                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12406                }
12407            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12408                String[] newArgs;
12409                String name;
12410                if (opti >= args.length) {
12411                    name = null;
12412                    newArgs = EMPTY_STRING_ARRAY;
12413                } else {
12414                    name = args[opti];
12415                    opti++;
12416                    newArgs = new String[args.length - opti];
12417                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12418                            args.length - opti);
12419                }
12420                synchronized (this) {
12421                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12422                }
12423            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12424                synchronized (this) {
12425                    dumpOomLocked(fd, pw, args, opti, true);
12426                }
12427            } else if ("provider".equals(cmd)) {
12428                String[] newArgs;
12429                String name;
12430                if (opti >= args.length) {
12431                    name = null;
12432                    newArgs = EMPTY_STRING_ARRAY;
12433                } else {
12434                    name = args[opti];
12435                    opti++;
12436                    newArgs = new String[args.length - opti];
12437                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12438                }
12439                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12440                    pw.println("No providers match: " + name);
12441                    pw.println("Use -h for help.");
12442                }
12443            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12444                synchronized (this) {
12445                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12446                }
12447            } else if ("service".equals(cmd)) {
12448                String[] newArgs;
12449                String name;
12450                if (opti >= args.length) {
12451                    name = null;
12452                    newArgs = EMPTY_STRING_ARRAY;
12453                } else {
12454                    name = args[opti];
12455                    opti++;
12456                    newArgs = new String[args.length - opti];
12457                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12458                            args.length - opti);
12459                }
12460                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12461                    pw.println("No services match: " + name);
12462                    pw.println("Use -h for help.");
12463                }
12464            } else if ("package".equals(cmd)) {
12465                String[] newArgs;
12466                if (opti >= args.length) {
12467                    pw.println("package: no package name specified");
12468                    pw.println("Use -h for help.");
12469                } else {
12470                    dumpPackage = args[opti];
12471                    opti++;
12472                    newArgs = new String[args.length - opti];
12473                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12474                            args.length - opti);
12475                    args = newArgs;
12476                    opti = 0;
12477                    more = true;
12478                }
12479            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12480                synchronized (this) {
12481                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12482                }
12483            } else if ("write".equals(cmd)) {
12484                mTaskPersister.flush();
12485                pw.println("All tasks persisted.");
12486                return;
12487            } else {
12488                // Dumping a single activity?
12489                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12490                    pw.println("Bad activity command, or no activities match: " + cmd);
12491                    pw.println("Use -h for help.");
12492                }
12493            }
12494            if (!more) {
12495                Binder.restoreCallingIdentity(origId);
12496                return;
12497            }
12498        }
12499
12500        // No piece of data specified, dump everything.
12501        synchronized (this) {
12502            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12503            pw.println();
12504            if (dumpAll) {
12505                pw.println("-------------------------------------------------------------------------------");
12506            }
12507            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12508            pw.println();
12509            if (dumpAll) {
12510                pw.println("-------------------------------------------------------------------------------");
12511            }
12512            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12513            pw.println();
12514            if (dumpAll) {
12515                pw.println("-------------------------------------------------------------------------------");
12516            }
12517            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12518            pw.println();
12519            if (dumpAll) {
12520                pw.println("-------------------------------------------------------------------------------");
12521            }
12522            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12523            pw.println();
12524            if (dumpAll) {
12525                pw.println("-------------------------------------------------------------------------------");
12526            }
12527            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12528            pw.println();
12529            if (dumpAll) {
12530                pw.println("-------------------------------------------------------------------------------");
12531            }
12532            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12533        }
12534        Binder.restoreCallingIdentity(origId);
12535    }
12536
12537    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12538            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12539        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12540
12541        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12542                dumpPackage);
12543        boolean needSep = printedAnything;
12544
12545        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12546                dumpPackage, needSep, "  mFocusedActivity: ");
12547        if (printed) {
12548            printedAnything = true;
12549            needSep = false;
12550        }
12551
12552        if (dumpPackage == null) {
12553            if (needSep) {
12554                pw.println();
12555            }
12556            needSep = true;
12557            printedAnything = true;
12558            mStackSupervisor.dump(pw, "  ");
12559        }
12560
12561        if (!printedAnything) {
12562            pw.println("  (nothing)");
12563        }
12564    }
12565
12566    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12567            int opti, boolean dumpAll, String dumpPackage) {
12568        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12569
12570        boolean printedAnything = false;
12571
12572        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12573            boolean printedHeader = false;
12574
12575            final int N = mRecentTasks.size();
12576            for (int i=0; i<N; i++) {
12577                TaskRecord tr = mRecentTasks.get(i);
12578                if (dumpPackage != null) {
12579                    if (tr.realActivity == null ||
12580                            !dumpPackage.equals(tr.realActivity)) {
12581                        continue;
12582                    }
12583                }
12584                if (!printedHeader) {
12585                    pw.println("  Recent tasks:");
12586                    printedHeader = true;
12587                    printedAnything = true;
12588                }
12589                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12590                        pw.println(tr);
12591                if (dumpAll) {
12592                    mRecentTasks.get(i).dump(pw, "    ");
12593                }
12594            }
12595        }
12596
12597        if (!printedAnything) {
12598            pw.println("  (nothing)");
12599        }
12600    }
12601
12602    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12603            int opti, boolean dumpAll, String dumpPackage) {
12604        boolean needSep = false;
12605        boolean printedAnything = false;
12606        int numPers = 0;
12607
12608        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12609
12610        if (dumpAll) {
12611            final int NP = mProcessNames.getMap().size();
12612            for (int ip=0; ip<NP; ip++) {
12613                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12614                final int NA = procs.size();
12615                for (int ia=0; ia<NA; ia++) {
12616                    ProcessRecord r = procs.valueAt(ia);
12617                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12618                        continue;
12619                    }
12620                    if (!needSep) {
12621                        pw.println("  All known processes:");
12622                        needSep = true;
12623                        printedAnything = true;
12624                    }
12625                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12626                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12627                        pw.print(" "); pw.println(r);
12628                    r.dump(pw, "    ");
12629                    if (r.persistent) {
12630                        numPers++;
12631                    }
12632                }
12633            }
12634        }
12635
12636        if (mIsolatedProcesses.size() > 0) {
12637            boolean printed = false;
12638            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12639                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12640                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12641                    continue;
12642                }
12643                if (!printed) {
12644                    if (needSep) {
12645                        pw.println();
12646                    }
12647                    pw.println("  Isolated process list (sorted by uid):");
12648                    printedAnything = true;
12649                    printed = true;
12650                    needSep = true;
12651                }
12652                pw.println(String.format("%sIsolated #%2d: %s",
12653                        "    ", i, r.toString()));
12654            }
12655        }
12656
12657        if (mLruProcesses.size() > 0) {
12658            if (needSep) {
12659                pw.println();
12660            }
12661            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12662                    pw.print(" total, non-act at ");
12663                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12664                    pw.print(", non-svc at ");
12665                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12666                    pw.println("):");
12667            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12668            needSep = true;
12669            printedAnything = true;
12670        }
12671
12672        if (dumpAll || dumpPackage != null) {
12673            synchronized (mPidsSelfLocked) {
12674                boolean printed = false;
12675                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12676                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12677                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12678                        continue;
12679                    }
12680                    if (!printed) {
12681                        if (needSep) pw.println();
12682                        needSep = true;
12683                        pw.println("  PID mappings:");
12684                        printed = true;
12685                        printedAnything = true;
12686                    }
12687                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12688                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12689                }
12690            }
12691        }
12692
12693        if (mForegroundProcesses.size() > 0) {
12694            synchronized (mPidsSelfLocked) {
12695                boolean printed = false;
12696                for (int i=0; i<mForegroundProcesses.size(); i++) {
12697                    ProcessRecord r = mPidsSelfLocked.get(
12698                            mForegroundProcesses.valueAt(i).pid);
12699                    if (dumpPackage != null && (r == null
12700                            || !r.pkgList.containsKey(dumpPackage))) {
12701                        continue;
12702                    }
12703                    if (!printed) {
12704                        if (needSep) pw.println();
12705                        needSep = true;
12706                        pw.println("  Foreground Processes:");
12707                        printed = true;
12708                        printedAnything = true;
12709                    }
12710                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12711                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12712                }
12713            }
12714        }
12715
12716        if (mPersistentStartingProcesses.size() > 0) {
12717            if (needSep) pw.println();
12718            needSep = true;
12719            printedAnything = true;
12720            pw.println("  Persisent processes that are starting:");
12721            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12722                    "Starting Norm", "Restarting PERS", dumpPackage);
12723        }
12724
12725        if (mRemovedProcesses.size() > 0) {
12726            if (needSep) pw.println();
12727            needSep = true;
12728            printedAnything = true;
12729            pw.println("  Processes that are being removed:");
12730            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12731                    "Removed Norm", "Removed PERS", dumpPackage);
12732        }
12733
12734        if (mProcessesOnHold.size() > 0) {
12735            if (needSep) pw.println();
12736            needSep = true;
12737            printedAnything = true;
12738            pw.println("  Processes that are on old until the system is ready:");
12739            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12740                    "OnHold Norm", "OnHold PERS", dumpPackage);
12741        }
12742
12743        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12744
12745        if (mProcessCrashTimes.getMap().size() > 0) {
12746            boolean printed = false;
12747            long now = SystemClock.uptimeMillis();
12748            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12749            final int NP = pmap.size();
12750            for (int ip=0; ip<NP; ip++) {
12751                String pname = pmap.keyAt(ip);
12752                SparseArray<Long> uids = pmap.valueAt(ip);
12753                final int N = uids.size();
12754                for (int i=0; i<N; i++) {
12755                    int puid = uids.keyAt(i);
12756                    ProcessRecord r = mProcessNames.get(pname, puid);
12757                    if (dumpPackage != null && (r == null
12758                            || !r.pkgList.containsKey(dumpPackage))) {
12759                        continue;
12760                    }
12761                    if (!printed) {
12762                        if (needSep) pw.println();
12763                        needSep = true;
12764                        pw.println("  Time since processes crashed:");
12765                        printed = true;
12766                        printedAnything = true;
12767                    }
12768                    pw.print("    Process "); pw.print(pname);
12769                            pw.print(" uid "); pw.print(puid);
12770                            pw.print(": last crashed ");
12771                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12772                            pw.println(" ago");
12773                }
12774            }
12775        }
12776
12777        if (mBadProcesses.getMap().size() > 0) {
12778            boolean printed = false;
12779            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12780            final int NP = pmap.size();
12781            for (int ip=0; ip<NP; ip++) {
12782                String pname = pmap.keyAt(ip);
12783                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12784                final int N = uids.size();
12785                for (int i=0; i<N; i++) {
12786                    int puid = uids.keyAt(i);
12787                    ProcessRecord r = mProcessNames.get(pname, puid);
12788                    if (dumpPackage != null && (r == null
12789                            || !r.pkgList.containsKey(dumpPackage))) {
12790                        continue;
12791                    }
12792                    if (!printed) {
12793                        if (needSep) pw.println();
12794                        needSep = true;
12795                        pw.println("  Bad processes:");
12796                        printedAnything = true;
12797                    }
12798                    BadProcessInfo info = uids.valueAt(i);
12799                    pw.print("    Bad process "); pw.print(pname);
12800                            pw.print(" uid "); pw.print(puid);
12801                            pw.print(": crashed at time "); pw.println(info.time);
12802                    if (info.shortMsg != null) {
12803                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12804                    }
12805                    if (info.longMsg != null) {
12806                        pw.print("      Long msg: "); pw.println(info.longMsg);
12807                    }
12808                    if (info.stack != null) {
12809                        pw.println("      Stack:");
12810                        int lastPos = 0;
12811                        for (int pos=0; pos<info.stack.length(); pos++) {
12812                            if (info.stack.charAt(pos) == '\n') {
12813                                pw.print("        ");
12814                                pw.write(info.stack, lastPos, pos-lastPos);
12815                                pw.println();
12816                                lastPos = pos+1;
12817                            }
12818                        }
12819                        if (lastPos < info.stack.length()) {
12820                            pw.print("        ");
12821                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12822                            pw.println();
12823                        }
12824                    }
12825                }
12826            }
12827        }
12828
12829        if (dumpPackage == null) {
12830            pw.println();
12831            needSep = false;
12832            pw.println("  mStartedUsers:");
12833            for (int i=0; i<mStartedUsers.size(); i++) {
12834                UserStartedState uss = mStartedUsers.valueAt(i);
12835                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12836                        pw.print(": "); uss.dump("", pw);
12837            }
12838            pw.print("  mStartedUserArray: [");
12839            for (int i=0; i<mStartedUserArray.length; i++) {
12840                if (i > 0) pw.print(", ");
12841                pw.print(mStartedUserArray[i]);
12842            }
12843            pw.println("]");
12844            pw.print("  mUserLru: [");
12845            for (int i=0; i<mUserLru.size(); i++) {
12846                if (i > 0) pw.print(", ");
12847                pw.print(mUserLru.get(i));
12848            }
12849            pw.println("]");
12850            if (dumpAll) {
12851                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12852            }
12853            synchronized (mUserProfileGroupIdsSelfLocked) {
12854                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12855                    pw.println("  mUserProfileGroupIds:");
12856                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12857                        pw.print("    User #");
12858                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12859                        pw.print(" -> profile #");
12860                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12861                    }
12862                }
12863            }
12864        }
12865        if (mHomeProcess != null && (dumpPackage == null
12866                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12867            if (needSep) {
12868                pw.println();
12869                needSep = false;
12870            }
12871            pw.println("  mHomeProcess: " + mHomeProcess);
12872        }
12873        if (mPreviousProcess != null && (dumpPackage == null
12874                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12875            if (needSep) {
12876                pw.println();
12877                needSep = false;
12878            }
12879            pw.println("  mPreviousProcess: " + mPreviousProcess);
12880        }
12881        if (dumpAll) {
12882            StringBuilder sb = new StringBuilder(128);
12883            sb.append("  mPreviousProcessVisibleTime: ");
12884            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12885            pw.println(sb);
12886        }
12887        if (mHeavyWeightProcess != null && (dumpPackage == null
12888                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12889            if (needSep) {
12890                pw.println();
12891                needSep = false;
12892            }
12893            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12894        }
12895        if (dumpPackage == null) {
12896            pw.println("  mConfiguration: " + mConfiguration);
12897        }
12898        if (dumpAll) {
12899            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12900            if (mCompatModePackages.getPackages().size() > 0) {
12901                boolean printed = false;
12902                for (Map.Entry<String, Integer> entry
12903                        : mCompatModePackages.getPackages().entrySet()) {
12904                    String pkg = entry.getKey();
12905                    int mode = entry.getValue();
12906                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12907                        continue;
12908                    }
12909                    if (!printed) {
12910                        pw.println("  mScreenCompatPackages:");
12911                        printed = true;
12912                    }
12913                    pw.print("    "); pw.print(pkg); pw.print(": ");
12914                            pw.print(mode); pw.println();
12915                }
12916            }
12917        }
12918        if (dumpPackage == null) {
12919            pw.println("  mWakefulness="
12920                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12921            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12922                    + lockScreenShownToString());
12923            pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
12924                    + " mTestPssMode=" + mTestPssMode);
12925        }
12926        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12927                || mOrigWaitForDebugger) {
12928            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12929                    || dumpPackage.equals(mOrigDebugApp)) {
12930                if (needSep) {
12931                    pw.println();
12932                    needSep = false;
12933                }
12934                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12935                        + " mDebugTransient=" + mDebugTransient
12936                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12937            }
12938        }
12939        if (mOpenGlTraceApp != null) {
12940            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12941                if (needSep) {
12942                    pw.println();
12943                    needSep = false;
12944                }
12945                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12946            }
12947        }
12948        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12949                || mProfileFd != null) {
12950            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12951                if (needSep) {
12952                    pw.println();
12953                    needSep = false;
12954                }
12955                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12956                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12957                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12958                        + mAutoStopProfiler);
12959                pw.println("  mProfileType=" + mProfileType);
12960            }
12961        }
12962        if (dumpPackage == null) {
12963            if (mAlwaysFinishActivities || mController != null) {
12964                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12965                        + " mController=" + mController);
12966            }
12967            if (dumpAll) {
12968                pw.println("  Total persistent processes: " + numPers);
12969                pw.println("  mProcessesReady=" + mProcessesReady
12970                        + " mSystemReady=" + mSystemReady
12971                        + " mBooted=" + mBooted
12972                        + " mFactoryTest=" + mFactoryTest);
12973                pw.println("  mBooting=" + mBooting
12974                        + " mCallFinishBooting=" + mCallFinishBooting
12975                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12976                pw.print("  mLastPowerCheckRealtime=");
12977                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12978                        pw.println("");
12979                pw.print("  mLastPowerCheckUptime=");
12980                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12981                        pw.println("");
12982                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12983                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12984                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12985                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12986                        + " (" + mLruProcesses.size() + " total)"
12987                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12988                        + " mNumServiceProcs=" + mNumServiceProcs
12989                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12990                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12991                        + " mLastMemoryLevel" + mLastMemoryLevel
12992                        + " mLastNumProcesses" + mLastNumProcesses);
12993                long now = SystemClock.uptimeMillis();
12994                pw.print("  mLastIdleTime=");
12995                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12996                        pw.print(" mLowRamSinceLastIdle=");
12997                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12998                        pw.println();
12999            }
13000        }
13001
13002        if (!printedAnything) {
13003            pw.println("  (nothing)");
13004        }
13005    }
13006
13007    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13008            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13009        if (mProcessesToGc.size() > 0) {
13010            boolean printed = false;
13011            long now = SystemClock.uptimeMillis();
13012            for (int i=0; i<mProcessesToGc.size(); i++) {
13013                ProcessRecord proc = mProcessesToGc.get(i);
13014                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13015                    continue;
13016                }
13017                if (!printed) {
13018                    if (needSep) pw.println();
13019                    needSep = true;
13020                    pw.println("  Processes that are waiting to GC:");
13021                    printed = true;
13022                }
13023                pw.print("    Process "); pw.println(proc);
13024                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13025                        pw.print(", last gced=");
13026                        pw.print(now-proc.lastRequestedGc);
13027                        pw.print(" ms ago, last lowMem=");
13028                        pw.print(now-proc.lastLowMemory);
13029                        pw.println(" ms ago");
13030
13031            }
13032        }
13033        return needSep;
13034    }
13035
13036    void printOomLevel(PrintWriter pw, String name, int adj) {
13037        pw.print("    ");
13038        if (adj >= 0) {
13039            pw.print(' ');
13040            if (adj < 10) pw.print(' ');
13041        } else {
13042            if (adj > -10) pw.print(' ');
13043        }
13044        pw.print(adj);
13045        pw.print(": ");
13046        pw.print(name);
13047        pw.print(" (");
13048        pw.print(mProcessList.getMemLevel(adj)/1024);
13049        pw.println(" kB)");
13050    }
13051
13052    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13053            int opti, boolean dumpAll) {
13054        boolean needSep = false;
13055
13056        if (mLruProcesses.size() > 0) {
13057            if (needSep) pw.println();
13058            needSep = true;
13059            pw.println("  OOM levels:");
13060            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13061            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13062            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13063            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13064            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13065            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13066            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13067            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13068            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13069            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13070            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13071            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13072            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13073            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13074
13075            if (needSep) pw.println();
13076            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13077                    pw.print(" total, non-act at ");
13078                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13079                    pw.print(", non-svc at ");
13080                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13081                    pw.println("):");
13082            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13083            needSep = true;
13084        }
13085
13086        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13087
13088        pw.println();
13089        pw.println("  mHomeProcess: " + mHomeProcess);
13090        pw.println("  mPreviousProcess: " + mPreviousProcess);
13091        if (mHeavyWeightProcess != null) {
13092            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13093        }
13094
13095        return true;
13096    }
13097
13098    /**
13099     * There are three ways to call this:
13100     *  - no provider specified: dump all the providers
13101     *  - a flattened component name that matched an existing provider was specified as the
13102     *    first arg: dump that one provider
13103     *  - the first arg isn't the flattened component name of an existing provider:
13104     *    dump all providers whose component contains the first arg as a substring
13105     */
13106    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13107            int opti, boolean dumpAll) {
13108        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13109    }
13110
13111    static class ItemMatcher {
13112        ArrayList<ComponentName> components;
13113        ArrayList<String> strings;
13114        ArrayList<Integer> objects;
13115        boolean all;
13116
13117        ItemMatcher() {
13118            all = true;
13119        }
13120
13121        void build(String name) {
13122            ComponentName componentName = ComponentName.unflattenFromString(name);
13123            if (componentName != null) {
13124                if (components == null) {
13125                    components = new ArrayList<ComponentName>();
13126                }
13127                components.add(componentName);
13128                all = false;
13129            } else {
13130                int objectId = 0;
13131                // Not a '/' separated full component name; maybe an object ID?
13132                try {
13133                    objectId = Integer.parseInt(name, 16);
13134                    if (objects == null) {
13135                        objects = new ArrayList<Integer>();
13136                    }
13137                    objects.add(objectId);
13138                    all = false;
13139                } catch (RuntimeException e) {
13140                    // Not an integer; just do string match.
13141                    if (strings == null) {
13142                        strings = new ArrayList<String>();
13143                    }
13144                    strings.add(name);
13145                    all = false;
13146                }
13147            }
13148        }
13149
13150        int build(String[] args, int opti) {
13151            for (; opti<args.length; opti++) {
13152                String name = args[opti];
13153                if ("--".equals(name)) {
13154                    return opti+1;
13155                }
13156                build(name);
13157            }
13158            return opti;
13159        }
13160
13161        boolean match(Object object, ComponentName comp) {
13162            if (all) {
13163                return true;
13164            }
13165            if (components != null) {
13166                for (int i=0; i<components.size(); i++) {
13167                    if (components.get(i).equals(comp)) {
13168                        return true;
13169                    }
13170                }
13171            }
13172            if (objects != null) {
13173                for (int i=0; i<objects.size(); i++) {
13174                    if (System.identityHashCode(object) == objects.get(i)) {
13175                        return true;
13176                    }
13177                }
13178            }
13179            if (strings != null) {
13180                String flat = comp.flattenToString();
13181                for (int i=0; i<strings.size(); i++) {
13182                    if (flat.contains(strings.get(i))) {
13183                        return true;
13184                    }
13185                }
13186            }
13187            return false;
13188        }
13189    }
13190
13191    /**
13192     * There are three things that cmd can be:
13193     *  - a flattened component name that matches an existing activity
13194     *  - the cmd arg isn't the flattened component name of an existing activity:
13195     *    dump all activity whose component contains the cmd as a substring
13196     *  - A hex number of the ActivityRecord object instance.
13197     */
13198    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13199            int opti, boolean dumpAll) {
13200        ArrayList<ActivityRecord> activities;
13201
13202        synchronized (this) {
13203            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13204        }
13205
13206        if (activities.size() <= 0) {
13207            return false;
13208        }
13209
13210        String[] newArgs = new String[args.length - opti];
13211        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13212
13213        TaskRecord lastTask = null;
13214        boolean needSep = false;
13215        for (int i=activities.size()-1; i>=0; i--) {
13216            ActivityRecord r = activities.get(i);
13217            if (needSep) {
13218                pw.println();
13219            }
13220            needSep = true;
13221            synchronized (this) {
13222                if (lastTask != r.task) {
13223                    lastTask = r.task;
13224                    pw.print("TASK "); pw.print(lastTask.affinity);
13225                            pw.print(" id="); pw.println(lastTask.taskId);
13226                    if (dumpAll) {
13227                        lastTask.dump(pw, "  ");
13228                    }
13229                }
13230            }
13231            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13232        }
13233        return true;
13234    }
13235
13236    /**
13237     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13238     * there is a thread associated with the activity.
13239     */
13240    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13241            final ActivityRecord r, String[] args, boolean dumpAll) {
13242        String innerPrefix = prefix + "  ";
13243        synchronized (this) {
13244            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13245                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13246                    pw.print(" pid=");
13247                    if (r.app != null) pw.println(r.app.pid);
13248                    else pw.println("(not running)");
13249            if (dumpAll) {
13250                r.dump(pw, innerPrefix);
13251            }
13252        }
13253        if (r.app != null && r.app.thread != null) {
13254            // flush anything that is already in the PrintWriter since the thread is going
13255            // to write to the file descriptor directly
13256            pw.flush();
13257            try {
13258                TransferPipe tp = new TransferPipe();
13259                try {
13260                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13261                            r.appToken, innerPrefix, args);
13262                    tp.go(fd);
13263                } finally {
13264                    tp.kill();
13265                }
13266            } catch (IOException e) {
13267                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13268            } catch (RemoteException e) {
13269                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13270            }
13271        }
13272    }
13273
13274    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13275            int opti, boolean dumpAll, String dumpPackage) {
13276        boolean needSep = false;
13277        boolean onlyHistory = false;
13278        boolean printedAnything = false;
13279
13280        if ("history".equals(dumpPackage)) {
13281            if (opti < args.length && "-s".equals(args[opti])) {
13282                dumpAll = false;
13283            }
13284            onlyHistory = true;
13285            dumpPackage = null;
13286        }
13287
13288        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13289        if (!onlyHistory && dumpAll) {
13290            if (mRegisteredReceivers.size() > 0) {
13291                boolean printed = false;
13292                Iterator it = mRegisteredReceivers.values().iterator();
13293                while (it.hasNext()) {
13294                    ReceiverList r = (ReceiverList)it.next();
13295                    if (dumpPackage != null && (r.app == null ||
13296                            !dumpPackage.equals(r.app.info.packageName))) {
13297                        continue;
13298                    }
13299                    if (!printed) {
13300                        pw.println("  Registered Receivers:");
13301                        needSep = true;
13302                        printed = true;
13303                        printedAnything = true;
13304                    }
13305                    pw.print("  * "); pw.println(r);
13306                    r.dump(pw, "    ");
13307                }
13308            }
13309
13310            if (mReceiverResolver.dump(pw, needSep ?
13311                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13312                    "    ", dumpPackage, false, false)) {
13313                needSep = true;
13314                printedAnything = true;
13315            }
13316        }
13317
13318        for (BroadcastQueue q : mBroadcastQueues) {
13319            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13320            printedAnything |= needSep;
13321        }
13322
13323        needSep = true;
13324
13325        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13326            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13327                if (needSep) {
13328                    pw.println();
13329                }
13330                needSep = true;
13331                printedAnything = true;
13332                pw.print("  Sticky broadcasts for user ");
13333                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13334                StringBuilder sb = new StringBuilder(128);
13335                for (Map.Entry<String, ArrayList<Intent>> ent
13336                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13337                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13338                    if (dumpAll) {
13339                        pw.println(":");
13340                        ArrayList<Intent> intents = ent.getValue();
13341                        final int N = intents.size();
13342                        for (int i=0; i<N; i++) {
13343                            sb.setLength(0);
13344                            sb.append("    Intent: ");
13345                            intents.get(i).toShortString(sb, false, true, false, false);
13346                            pw.println(sb.toString());
13347                            Bundle bundle = intents.get(i).getExtras();
13348                            if (bundle != null) {
13349                                pw.print("      ");
13350                                pw.println(bundle.toString());
13351                            }
13352                        }
13353                    } else {
13354                        pw.println("");
13355                    }
13356                }
13357            }
13358        }
13359
13360        if (!onlyHistory && dumpAll) {
13361            pw.println();
13362            for (BroadcastQueue queue : mBroadcastQueues) {
13363                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13364                        + queue.mBroadcastsScheduled);
13365            }
13366            pw.println("  mHandler:");
13367            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13368            needSep = true;
13369            printedAnything = true;
13370        }
13371
13372        if (!printedAnything) {
13373            pw.println("  (nothing)");
13374        }
13375    }
13376
13377    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13378            int opti, boolean dumpAll, String dumpPackage) {
13379        boolean needSep;
13380        boolean printedAnything = false;
13381
13382        ItemMatcher matcher = new ItemMatcher();
13383        matcher.build(args, opti);
13384
13385        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13386
13387        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13388        printedAnything |= needSep;
13389
13390        if (mLaunchingProviders.size() > 0) {
13391            boolean printed = false;
13392            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13393                ContentProviderRecord r = mLaunchingProviders.get(i);
13394                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13395                    continue;
13396                }
13397                if (!printed) {
13398                    if (needSep) pw.println();
13399                    needSep = true;
13400                    pw.println("  Launching content providers:");
13401                    printed = true;
13402                    printedAnything = true;
13403                }
13404                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13405                        pw.println(r);
13406            }
13407        }
13408
13409        if (mGrantedUriPermissions.size() > 0) {
13410            boolean printed = false;
13411            int dumpUid = -2;
13412            if (dumpPackage != null) {
13413                try {
13414                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13415                } catch (NameNotFoundException e) {
13416                    dumpUid = -1;
13417                }
13418            }
13419            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13420                int uid = mGrantedUriPermissions.keyAt(i);
13421                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13422                    continue;
13423                }
13424                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13425                if (!printed) {
13426                    if (needSep) pw.println();
13427                    needSep = true;
13428                    pw.println("  Granted Uri Permissions:");
13429                    printed = true;
13430                    printedAnything = true;
13431                }
13432                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13433                for (UriPermission perm : perms.values()) {
13434                    pw.print("    "); pw.println(perm);
13435                    if (dumpAll) {
13436                        perm.dump(pw, "      ");
13437                    }
13438                }
13439            }
13440        }
13441
13442        if (!printedAnything) {
13443            pw.println("  (nothing)");
13444        }
13445    }
13446
13447    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13448            int opti, boolean dumpAll, String dumpPackage) {
13449        boolean printed = false;
13450
13451        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13452
13453        if (mIntentSenderRecords.size() > 0) {
13454            Iterator<WeakReference<PendingIntentRecord>> it
13455                    = mIntentSenderRecords.values().iterator();
13456            while (it.hasNext()) {
13457                WeakReference<PendingIntentRecord> ref = it.next();
13458                PendingIntentRecord rec = ref != null ? ref.get(): null;
13459                if (dumpPackage != null && (rec == null
13460                        || !dumpPackage.equals(rec.key.packageName))) {
13461                    continue;
13462                }
13463                printed = true;
13464                if (rec != null) {
13465                    pw.print("  * "); pw.println(rec);
13466                    if (dumpAll) {
13467                        rec.dump(pw, "    ");
13468                    }
13469                } else {
13470                    pw.print("  * "); pw.println(ref);
13471                }
13472            }
13473        }
13474
13475        if (!printed) {
13476            pw.println("  (nothing)");
13477        }
13478    }
13479
13480    private static final int dumpProcessList(PrintWriter pw,
13481            ActivityManagerService service, List list,
13482            String prefix, String normalLabel, String persistentLabel,
13483            String dumpPackage) {
13484        int numPers = 0;
13485        final int N = list.size()-1;
13486        for (int i=N; i>=0; i--) {
13487            ProcessRecord r = (ProcessRecord)list.get(i);
13488            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13489                continue;
13490            }
13491            pw.println(String.format("%s%s #%2d: %s",
13492                    prefix, (r.persistent ? persistentLabel : normalLabel),
13493                    i, r.toString()));
13494            if (r.persistent) {
13495                numPers++;
13496            }
13497        }
13498        return numPers;
13499    }
13500
13501    private static final boolean dumpProcessOomList(PrintWriter pw,
13502            ActivityManagerService service, List<ProcessRecord> origList,
13503            String prefix, String normalLabel, String persistentLabel,
13504            boolean inclDetails, String dumpPackage) {
13505
13506        ArrayList<Pair<ProcessRecord, Integer>> list
13507                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13508        for (int i=0; i<origList.size(); i++) {
13509            ProcessRecord r = origList.get(i);
13510            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13511                continue;
13512            }
13513            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13514        }
13515
13516        if (list.size() <= 0) {
13517            return false;
13518        }
13519
13520        Comparator<Pair<ProcessRecord, Integer>> comparator
13521                = new Comparator<Pair<ProcessRecord, Integer>>() {
13522            @Override
13523            public int compare(Pair<ProcessRecord, Integer> object1,
13524                    Pair<ProcessRecord, Integer> object2) {
13525                if (object1.first.setAdj != object2.first.setAdj) {
13526                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13527                }
13528                if (object1.second.intValue() != object2.second.intValue()) {
13529                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13530                }
13531                return 0;
13532            }
13533        };
13534
13535        Collections.sort(list, comparator);
13536
13537        final long curRealtime = SystemClock.elapsedRealtime();
13538        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13539        final long curUptime = SystemClock.uptimeMillis();
13540        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13541
13542        for (int i=list.size()-1; i>=0; i--) {
13543            ProcessRecord r = list.get(i).first;
13544            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13545            char schedGroup;
13546            switch (r.setSchedGroup) {
13547                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13548                    schedGroup = 'B';
13549                    break;
13550                case Process.THREAD_GROUP_DEFAULT:
13551                    schedGroup = 'F';
13552                    break;
13553                default:
13554                    schedGroup = '?';
13555                    break;
13556            }
13557            char foreground;
13558            if (r.foregroundActivities) {
13559                foreground = 'A';
13560            } else if (r.foregroundServices) {
13561                foreground = 'S';
13562            } else {
13563                foreground = ' ';
13564            }
13565            String procState = ProcessList.makeProcStateString(r.curProcState);
13566            pw.print(prefix);
13567            pw.print(r.persistent ? persistentLabel : normalLabel);
13568            pw.print(" #");
13569            int num = (origList.size()-1)-list.get(i).second;
13570            if (num < 10) pw.print(' ');
13571            pw.print(num);
13572            pw.print(": ");
13573            pw.print(oomAdj);
13574            pw.print(' ');
13575            pw.print(schedGroup);
13576            pw.print('/');
13577            pw.print(foreground);
13578            pw.print('/');
13579            pw.print(procState);
13580            pw.print(" trm:");
13581            if (r.trimMemoryLevel < 10) pw.print(' ');
13582            pw.print(r.trimMemoryLevel);
13583            pw.print(' ');
13584            pw.print(r.toShortString());
13585            pw.print(" (");
13586            pw.print(r.adjType);
13587            pw.println(')');
13588            if (r.adjSource != null || r.adjTarget != null) {
13589                pw.print(prefix);
13590                pw.print("    ");
13591                if (r.adjTarget instanceof ComponentName) {
13592                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13593                } else if (r.adjTarget != null) {
13594                    pw.print(r.adjTarget.toString());
13595                } else {
13596                    pw.print("{null}");
13597                }
13598                pw.print("<=");
13599                if (r.adjSource instanceof ProcessRecord) {
13600                    pw.print("Proc{");
13601                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13602                    pw.println("}");
13603                } else if (r.adjSource != null) {
13604                    pw.println(r.adjSource.toString());
13605                } else {
13606                    pw.println("{null}");
13607                }
13608            }
13609            if (inclDetails) {
13610                pw.print(prefix);
13611                pw.print("    ");
13612                pw.print("oom: max="); pw.print(r.maxAdj);
13613                pw.print(" curRaw="); pw.print(r.curRawAdj);
13614                pw.print(" setRaw="); pw.print(r.setRawAdj);
13615                pw.print(" cur="); pw.print(r.curAdj);
13616                pw.print(" set="); pw.println(r.setAdj);
13617                pw.print(prefix);
13618                pw.print("    ");
13619                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13620                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13621                pw.print(" lastPss="); pw.print(r.lastPss);
13622                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13623                pw.print(prefix);
13624                pw.print("    ");
13625                pw.print("cached="); pw.print(r.cached);
13626                pw.print(" empty="); pw.print(r.empty);
13627                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13628
13629                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13630                    if (r.lastWakeTime != 0) {
13631                        long wtime;
13632                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13633                        synchronized (stats) {
13634                            wtime = stats.getProcessWakeTime(r.info.uid,
13635                                    r.pid, curRealtime);
13636                        }
13637                        long timeUsed = wtime - r.lastWakeTime;
13638                        pw.print(prefix);
13639                        pw.print("    ");
13640                        pw.print("keep awake over ");
13641                        TimeUtils.formatDuration(realtimeSince, pw);
13642                        pw.print(" used ");
13643                        TimeUtils.formatDuration(timeUsed, pw);
13644                        pw.print(" (");
13645                        pw.print((timeUsed*100)/realtimeSince);
13646                        pw.println("%)");
13647                    }
13648                    if (r.lastCpuTime != 0) {
13649                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13650                        pw.print(prefix);
13651                        pw.print("    ");
13652                        pw.print("run cpu over ");
13653                        TimeUtils.formatDuration(uptimeSince, pw);
13654                        pw.print(" used ");
13655                        TimeUtils.formatDuration(timeUsed, pw);
13656                        pw.print(" (");
13657                        pw.print((timeUsed*100)/uptimeSince);
13658                        pw.println("%)");
13659                    }
13660                }
13661            }
13662        }
13663        return true;
13664    }
13665
13666    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13667            String[] args) {
13668        ArrayList<ProcessRecord> procs;
13669        synchronized (this) {
13670            if (args != null && args.length > start
13671                    && args[start].charAt(0) != '-') {
13672                procs = new ArrayList<ProcessRecord>();
13673                int pid = -1;
13674                try {
13675                    pid = Integer.parseInt(args[start]);
13676                } catch (NumberFormatException e) {
13677                }
13678                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13679                    ProcessRecord proc = mLruProcesses.get(i);
13680                    if (proc.pid == pid) {
13681                        procs.add(proc);
13682                    } else if (allPkgs && proc.pkgList != null
13683                            && proc.pkgList.containsKey(args[start])) {
13684                        procs.add(proc);
13685                    } else if (proc.processName.equals(args[start])) {
13686                        procs.add(proc);
13687                    }
13688                }
13689                if (procs.size() <= 0) {
13690                    return null;
13691                }
13692            } else {
13693                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13694            }
13695        }
13696        return procs;
13697    }
13698
13699    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13700            PrintWriter pw, String[] args) {
13701        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13702        if (procs == null) {
13703            pw.println("No process found for: " + args[0]);
13704            return;
13705        }
13706
13707        long uptime = SystemClock.uptimeMillis();
13708        long realtime = SystemClock.elapsedRealtime();
13709        pw.println("Applications Graphics Acceleration Info:");
13710        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13711
13712        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13713            ProcessRecord r = procs.get(i);
13714            if (r.thread != null) {
13715                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13716                pw.flush();
13717                try {
13718                    TransferPipe tp = new TransferPipe();
13719                    try {
13720                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13721                        tp.go(fd);
13722                    } finally {
13723                        tp.kill();
13724                    }
13725                } catch (IOException e) {
13726                    pw.println("Failure while dumping the app: " + r);
13727                    pw.flush();
13728                } catch (RemoteException e) {
13729                    pw.println("Got a RemoteException while dumping the app " + r);
13730                    pw.flush();
13731                }
13732            }
13733        }
13734    }
13735
13736    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13737        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13738        if (procs == null) {
13739            pw.println("No process found for: " + args[0]);
13740            return;
13741        }
13742
13743        pw.println("Applications Database Info:");
13744
13745        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13746            ProcessRecord r = procs.get(i);
13747            if (r.thread != null) {
13748                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13749                pw.flush();
13750                try {
13751                    TransferPipe tp = new TransferPipe();
13752                    try {
13753                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13754                        tp.go(fd);
13755                    } finally {
13756                        tp.kill();
13757                    }
13758                } catch (IOException e) {
13759                    pw.println("Failure while dumping the app: " + r);
13760                    pw.flush();
13761                } catch (RemoteException e) {
13762                    pw.println("Got a RemoteException while dumping the app " + r);
13763                    pw.flush();
13764                }
13765            }
13766        }
13767    }
13768
13769    final static class MemItem {
13770        final boolean isProc;
13771        final String label;
13772        final String shortLabel;
13773        final long pss;
13774        final int id;
13775        final boolean hasActivities;
13776        ArrayList<MemItem> subitems;
13777
13778        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13779                boolean _hasActivities) {
13780            isProc = true;
13781            label = _label;
13782            shortLabel = _shortLabel;
13783            pss = _pss;
13784            id = _id;
13785            hasActivities = _hasActivities;
13786        }
13787
13788        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13789            isProc = false;
13790            label = _label;
13791            shortLabel = _shortLabel;
13792            pss = _pss;
13793            id = _id;
13794            hasActivities = false;
13795        }
13796    }
13797
13798    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13799            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13800        if (sort && !isCompact) {
13801            Collections.sort(items, new Comparator<MemItem>() {
13802                @Override
13803                public int compare(MemItem lhs, MemItem rhs) {
13804                    if (lhs.pss < rhs.pss) {
13805                        return 1;
13806                    } else if (lhs.pss > rhs.pss) {
13807                        return -1;
13808                    }
13809                    return 0;
13810                }
13811            });
13812        }
13813
13814        for (int i=0; i<items.size(); i++) {
13815            MemItem mi = items.get(i);
13816            if (!isCompact) {
13817                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13818            } else if (mi.isProc) {
13819                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13820                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13821                pw.println(mi.hasActivities ? ",a" : ",e");
13822            } else {
13823                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13824                pw.println(mi.pss);
13825            }
13826            if (mi.subitems != null) {
13827                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13828                        true, isCompact);
13829            }
13830        }
13831    }
13832
13833    // These are in KB.
13834    static final long[] DUMP_MEM_BUCKETS = new long[] {
13835        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13836        120*1024, 160*1024, 200*1024,
13837        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13838        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13839    };
13840
13841    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13842            boolean stackLike) {
13843        int start = label.lastIndexOf('.');
13844        if (start >= 0) start++;
13845        else start = 0;
13846        int end = label.length();
13847        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13848            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13849                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13850                out.append(bucket);
13851                out.append(stackLike ? "MB." : "MB ");
13852                out.append(label, start, end);
13853                return;
13854            }
13855        }
13856        out.append(memKB/1024);
13857        out.append(stackLike ? "MB." : "MB ");
13858        out.append(label, start, end);
13859    }
13860
13861    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13862            ProcessList.NATIVE_ADJ,
13863            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13864            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13865            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13866            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13867            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13868            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13869    };
13870    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13871            "Native",
13872            "System", "Persistent", "Persistent Service", "Foreground",
13873            "Visible", "Perceptible",
13874            "Heavy Weight", "Backup",
13875            "A Services", "Home",
13876            "Previous", "B Services", "Cached"
13877    };
13878    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13879            "native",
13880            "sys", "pers", "persvc", "fore",
13881            "vis", "percept",
13882            "heavy", "backup",
13883            "servicea", "home",
13884            "prev", "serviceb", "cached"
13885    };
13886
13887    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13888            long realtime, boolean isCheckinRequest, boolean isCompact) {
13889        if (isCheckinRequest || isCompact) {
13890            // short checkin version
13891            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13892        } else {
13893            pw.println("Applications Memory Usage (kB):");
13894            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13895        }
13896    }
13897
13898    private static final int KSM_SHARED = 0;
13899    private static final int KSM_SHARING = 1;
13900    private static final int KSM_UNSHARED = 2;
13901    private static final int KSM_VOLATILE = 3;
13902
13903    private final long[] getKsmInfo() {
13904        long[] longOut = new long[4];
13905        final int[] SINGLE_LONG_FORMAT = new int[] {
13906            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13907        };
13908        long[] longTmp = new long[1];
13909        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13910                SINGLE_LONG_FORMAT, null, longTmp, null);
13911        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13912        longTmp[0] = 0;
13913        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13914                SINGLE_LONG_FORMAT, null, longTmp, null);
13915        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13916        longTmp[0] = 0;
13917        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13918                SINGLE_LONG_FORMAT, null, longTmp, null);
13919        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13920        longTmp[0] = 0;
13921        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13922                SINGLE_LONG_FORMAT, null, longTmp, null);
13923        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13924        return longOut;
13925    }
13926
13927    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13928            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13929        boolean dumpDetails = false;
13930        boolean dumpFullDetails = false;
13931        boolean dumpDalvik = false;
13932        boolean oomOnly = false;
13933        boolean isCompact = false;
13934        boolean localOnly = false;
13935        boolean packages = false;
13936
13937        int opti = 0;
13938        while (opti < args.length) {
13939            String opt = args[opti];
13940            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13941                break;
13942            }
13943            opti++;
13944            if ("-a".equals(opt)) {
13945                dumpDetails = true;
13946                dumpFullDetails = true;
13947                dumpDalvik = true;
13948            } else if ("-d".equals(opt)) {
13949                dumpDalvik = true;
13950            } else if ("-c".equals(opt)) {
13951                isCompact = true;
13952            } else if ("--oom".equals(opt)) {
13953                oomOnly = true;
13954            } else if ("--local".equals(opt)) {
13955                localOnly = true;
13956            } else if ("--package".equals(opt)) {
13957                packages = true;
13958            } else if ("-h".equals(opt)) {
13959                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13960                pw.println("  -a: include all available information for each process.");
13961                pw.println("  -d: include dalvik details when dumping process details.");
13962                pw.println("  -c: dump in a compact machine-parseable representation.");
13963                pw.println("  --oom: only show processes organized by oom adj.");
13964                pw.println("  --local: only collect details locally, don't call process.");
13965                pw.println("  --package: interpret process arg as package, dumping all");
13966                pw.println("             processes that have loaded that package.");
13967                pw.println("If [process] is specified it can be the name or ");
13968                pw.println("pid of a specific process to dump.");
13969                return;
13970            } else {
13971                pw.println("Unknown argument: " + opt + "; use -h for help");
13972            }
13973        }
13974
13975        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13976        long uptime = SystemClock.uptimeMillis();
13977        long realtime = SystemClock.elapsedRealtime();
13978        final long[] tmpLong = new long[1];
13979
13980        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13981        if (procs == null) {
13982            // No Java processes.  Maybe they want to print a native process.
13983            if (args != null && args.length > opti
13984                    && args[opti].charAt(0) != '-') {
13985                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13986                        = new ArrayList<ProcessCpuTracker.Stats>();
13987                updateCpuStatsNow();
13988                int findPid = -1;
13989                try {
13990                    findPid = Integer.parseInt(args[opti]);
13991                } catch (NumberFormatException e) {
13992                }
13993                synchronized (mProcessCpuTracker) {
13994                    final int N = mProcessCpuTracker.countStats();
13995                    for (int i=0; i<N; i++) {
13996                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13997                        if (st.pid == findPid || (st.baseName != null
13998                                && st.baseName.equals(args[opti]))) {
13999                            nativeProcs.add(st);
14000                        }
14001                    }
14002                }
14003                if (nativeProcs.size() > 0) {
14004                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14005                            isCompact);
14006                    Debug.MemoryInfo mi = null;
14007                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14008                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14009                        final int pid = r.pid;
14010                        if (!isCheckinRequest && dumpDetails) {
14011                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14012                        }
14013                        if (mi == null) {
14014                            mi = new Debug.MemoryInfo();
14015                        }
14016                        if (dumpDetails || (!brief && !oomOnly)) {
14017                            Debug.getMemoryInfo(pid, mi);
14018                        } else {
14019                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14020                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14021                        }
14022                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14023                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14024                        if (isCheckinRequest) {
14025                            pw.println();
14026                        }
14027                    }
14028                    return;
14029                }
14030            }
14031            pw.println("No process found for: " + args[opti]);
14032            return;
14033        }
14034
14035        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14036            dumpDetails = true;
14037        }
14038
14039        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14040
14041        String[] innerArgs = new String[args.length-opti];
14042        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14043
14044        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14045        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14046        long nativePss = 0;
14047        long dalvikPss = 0;
14048        long otherPss = 0;
14049        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14050
14051        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14052        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14053                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14054
14055        long totalPss = 0;
14056        long cachedPss = 0;
14057
14058        Debug.MemoryInfo mi = null;
14059        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14060            final ProcessRecord r = procs.get(i);
14061            final IApplicationThread thread;
14062            final int pid;
14063            final int oomAdj;
14064            final boolean hasActivities;
14065            synchronized (this) {
14066                thread = r.thread;
14067                pid = r.pid;
14068                oomAdj = r.getSetAdjWithServices();
14069                hasActivities = r.activities.size() > 0;
14070            }
14071            if (thread != null) {
14072                if (!isCheckinRequest && dumpDetails) {
14073                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14074                }
14075                if (mi == null) {
14076                    mi = new Debug.MemoryInfo();
14077                }
14078                if (dumpDetails || (!brief && !oomOnly)) {
14079                    Debug.getMemoryInfo(pid, mi);
14080                } else {
14081                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14082                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14083                }
14084                if (dumpDetails) {
14085                    if (localOnly) {
14086                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14087                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14088                        if (isCheckinRequest) {
14089                            pw.println();
14090                        }
14091                    } else {
14092                        try {
14093                            pw.flush();
14094                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14095                                    dumpDalvik, innerArgs);
14096                        } catch (RemoteException e) {
14097                            if (!isCheckinRequest) {
14098                                pw.println("Got RemoteException!");
14099                                pw.flush();
14100                            }
14101                        }
14102                    }
14103                }
14104
14105                final long myTotalPss = mi.getTotalPss();
14106                final long myTotalUss = mi.getTotalUss();
14107
14108                synchronized (this) {
14109                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14110                        // Record this for posterity if the process has been stable.
14111                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14112                    }
14113                }
14114
14115                if (!isCheckinRequest && mi != null) {
14116                    totalPss += myTotalPss;
14117                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14118                            (hasActivities ? " / activities)" : ")"),
14119                            r.processName, myTotalPss, pid, hasActivities);
14120                    procMems.add(pssItem);
14121                    procMemsMap.put(pid, pssItem);
14122
14123                    nativePss += mi.nativePss;
14124                    dalvikPss += mi.dalvikPss;
14125                    otherPss += mi.otherPss;
14126                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14127                        long mem = mi.getOtherPss(j);
14128                        miscPss[j] += mem;
14129                        otherPss -= mem;
14130                    }
14131
14132                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14133                        cachedPss += myTotalPss;
14134                    }
14135
14136                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14137                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14138                                || oomIndex == (oomPss.length-1)) {
14139                            oomPss[oomIndex] += myTotalPss;
14140                            if (oomProcs[oomIndex] == null) {
14141                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14142                            }
14143                            oomProcs[oomIndex].add(pssItem);
14144                            break;
14145                        }
14146                    }
14147                }
14148            }
14149        }
14150
14151        long nativeProcTotalPss = 0;
14152
14153        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14154            // If we are showing aggregations, also look for native processes to
14155            // include so that our aggregations are more accurate.
14156            updateCpuStatsNow();
14157            mi = null;
14158            synchronized (mProcessCpuTracker) {
14159                final int N = mProcessCpuTracker.countStats();
14160                for (int i=0; i<N; i++) {
14161                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14162                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14163                        if (mi == null) {
14164                            mi = new Debug.MemoryInfo();
14165                        }
14166                        if (!brief && !oomOnly) {
14167                            Debug.getMemoryInfo(st.pid, mi);
14168                        } else {
14169                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14170                            mi.nativePrivateDirty = (int)tmpLong[0];
14171                        }
14172
14173                        final long myTotalPss = mi.getTotalPss();
14174                        totalPss += myTotalPss;
14175                        nativeProcTotalPss += myTotalPss;
14176
14177                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14178                                st.name, myTotalPss, st.pid, false);
14179                        procMems.add(pssItem);
14180
14181                        nativePss += mi.nativePss;
14182                        dalvikPss += mi.dalvikPss;
14183                        otherPss += mi.otherPss;
14184                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14185                            long mem = mi.getOtherPss(j);
14186                            miscPss[j] += mem;
14187                            otherPss -= mem;
14188                        }
14189                        oomPss[0] += myTotalPss;
14190                        if (oomProcs[0] == null) {
14191                            oomProcs[0] = new ArrayList<MemItem>();
14192                        }
14193                        oomProcs[0].add(pssItem);
14194                    }
14195                }
14196            }
14197
14198            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14199
14200            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14201            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14202            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14203            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14204                String label = Debug.MemoryInfo.getOtherLabel(j);
14205                catMems.add(new MemItem(label, label, miscPss[j], j));
14206            }
14207
14208            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14209            for (int j=0; j<oomPss.length; j++) {
14210                if (oomPss[j] != 0) {
14211                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14212                            : DUMP_MEM_OOM_LABEL[j];
14213                    MemItem item = new MemItem(label, label, oomPss[j],
14214                            DUMP_MEM_OOM_ADJ[j]);
14215                    item.subitems = oomProcs[j];
14216                    oomMems.add(item);
14217                }
14218            }
14219
14220            if (!brief && !oomOnly && !isCompact) {
14221                pw.println();
14222                pw.println("Total PSS by process:");
14223                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14224                pw.println();
14225            }
14226            if (!isCompact) {
14227                pw.println("Total PSS by OOM adjustment:");
14228            }
14229            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14230            if (!brief && !oomOnly) {
14231                PrintWriter out = categoryPw != null ? categoryPw : pw;
14232                if (!isCompact) {
14233                    out.println();
14234                    out.println("Total PSS by category:");
14235                }
14236                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14237            }
14238            if (!isCompact) {
14239                pw.println();
14240            }
14241            MemInfoReader memInfo = new MemInfoReader();
14242            memInfo.readMemInfo();
14243            if (nativeProcTotalPss > 0) {
14244                synchronized (this) {
14245                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14246                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14247                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14248                }
14249            }
14250            if (!brief) {
14251                if (!isCompact) {
14252                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14253                    pw.print(" kB (status ");
14254                    switch (mLastMemoryLevel) {
14255                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14256                            pw.println("normal)");
14257                            break;
14258                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14259                            pw.println("moderate)");
14260                            break;
14261                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14262                            pw.println("low)");
14263                            break;
14264                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14265                            pw.println("critical)");
14266                            break;
14267                        default:
14268                            pw.print(mLastMemoryLevel);
14269                            pw.println(")");
14270                            break;
14271                    }
14272                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14273                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14274                            pw.print(cachedPss); pw.print(" cached pss + ");
14275                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14276                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14277                } else {
14278                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14279                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14280                            + memInfo.getFreeSizeKb()); pw.print(",");
14281                    pw.println(totalPss - cachedPss);
14282                }
14283            }
14284            if (!isCompact) {
14285                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14286                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14287                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14288                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14289                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14290                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14291                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14292            }
14293            if (!brief) {
14294                if (memInfo.getZramTotalSizeKb() != 0) {
14295                    if (!isCompact) {
14296                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14297                                pw.print(" kB physical used for ");
14298                                pw.print(memInfo.getSwapTotalSizeKb()
14299                                        - memInfo.getSwapFreeSizeKb());
14300                                pw.print(" kB in swap (");
14301                                pw.print(memInfo.getSwapTotalSizeKb());
14302                                pw.println(" kB total swap)");
14303                    } else {
14304                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14305                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14306                                pw.println(memInfo.getSwapFreeSizeKb());
14307                    }
14308                }
14309                final long[] ksm = getKsmInfo();
14310                if (!isCompact) {
14311                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14312                            || ksm[KSM_VOLATILE] != 0) {
14313                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14314                                pw.print(" kB saved from shared ");
14315                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14316                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14317                                pw.print(" kB unshared; ");
14318                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14319                    }
14320                    pw.print("   Tuning: ");
14321                    pw.print(ActivityManager.staticGetMemoryClass());
14322                    pw.print(" (large ");
14323                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14324                    pw.print("), oom ");
14325                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14326                    pw.print(" kB");
14327                    pw.print(", restore limit ");
14328                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14329                    pw.print(" kB");
14330                    if (ActivityManager.isLowRamDeviceStatic()) {
14331                        pw.print(" (low-ram)");
14332                    }
14333                    if (ActivityManager.isHighEndGfx()) {
14334                        pw.print(" (high-end-gfx)");
14335                    }
14336                    pw.println();
14337                } else {
14338                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14339                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14340                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14341                    pw.print("tuning,");
14342                    pw.print(ActivityManager.staticGetMemoryClass());
14343                    pw.print(',');
14344                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14345                    pw.print(',');
14346                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14347                    if (ActivityManager.isLowRamDeviceStatic()) {
14348                        pw.print(",low-ram");
14349                    }
14350                    if (ActivityManager.isHighEndGfx()) {
14351                        pw.print(",high-end-gfx");
14352                    }
14353                    pw.println();
14354                }
14355            }
14356        }
14357    }
14358
14359    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14360            long memtrack, String name) {
14361        sb.append("  ");
14362        sb.append(ProcessList.makeOomAdjString(oomAdj));
14363        sb.append(' ');
14364        sb.append(ProcessList.makeProcStateString(procState));
14365        sb.append(' ');
14366        ProcessList.appendRamKb(sb, pss);
14367        sb.append(" kB: ");
14368        sb.append(name);
14369        if (memtrack > 0) {
14370            sb.append(" (");
14371            sb.append(memtrack);
14372            sb.append(" kB memtrack)");
14373        }
14374    }
14375
14376    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14377        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14378        sb.append(" (pid ");
14379        sb.append(mi.pid);
14380        sb.append(") ");
14381        sb.append(mi.adjType);
14382        sb.append('\n');
14383        if (mi.adjReason != null) {
14384            sb.append("                      ");
14385            sb.append(mi.adjReason);
14386            sb.append('\n');
14387        }
14388    }
14389
14390    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14391        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14392        for (int i=0, N=memInfos.size(); i<N; i++) {
14393            ProcessMemInfo mi = memInfos.get(i);
14394            infoMap.put(mi.pid, mi);
14395        }
14396        updateCpuStatsNow();
14397        long[] memtrackTmp = new long[1];
14398        synchronized (mProcessCpuTracker) {
14399            final int N = mProcessCpuTracker.countStats();
14400            for (int i=0; i<N; i++) {
14401                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14402                if (st.vsize > 0) {
14403                    long pss = Debug.getPss(st.pid, null, memtrackTmp);
14404                    if (pss > 0) {
14405                        if (infoMap.indexOfKey(st.pid) < 0) {
14406                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14407                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14408                            mi.pss = pss;
14409                            mi.memtrack = memtrackTmp[0];
14410                            memInfos.add(mi);
14411                        }
14412                    }
14413                }
14414            }
14415        }
14416
14417        long totalPss = 0;
14418        long totalMemtrack = 0;
14419        for (int i=0, N=memInfos.size(); i<N; i++) {
14420            ProcessMemInfo mi = memInfos.get(i);
14421            if (mi.pss == 0) {
14422                mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14423                mi.memtrack = memtrackTmp[0];
14424            }
14425            totalPss += mi.pss;
14426            totalMemtrack += mi.memtrack;
14427        }
14428        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14429            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14430                if (lhs.oomAdj != rhs.oomAdj) {
14431                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14432                }
14433                if (lhs.pss != rhs.pss) {
14434                    return lhs.pss < rhs.pss ? 1 : -1;
14435                }
14436                return 0;
14437            }
14438        });
14439
14440        StringBuilder tag = new StringBuilder(128);
14441        StringBuilder stack = new StringBuilder(128);
14442        tag.append("Low on memory -- ");
14443        appendMemBucket(tag, totalPss, "total", false);
14444        appendMemBucket(stack, totalPss, "total", true);
14445
14446        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14447        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14448        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14449
14450        boolean firstLine = true;
14451        int lastOomAdj = Integer.MIN_VALUE;
14452        long extraNativeRam = 0;
14453        long extraNativeMemtrack = 0;
14454        long cachedPss = 0;
14455        for (int i=0, N=memInfos.size(); i<N; i++) {
14456            ProcessMemInfo mi = memInfos.get(i);
14457
14458            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14459                cachedPss += mi.pss;
14460            }
14461
14462            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14463                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14464                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14465                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14466                if (lastOomAdj != mi.oomAdj) {
14467                    lastOomAdj = mi.oomAdj;
14468                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14469                        tag.append(" / ");
14470                    }
14471                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14472                        if (firstLine) {
14473                            stack.append(":");
14474                            firstLine = false;
14475                        }
14476                        stack.append("\n\t at ");
14477                    } else {
14478                        stack.append("$");
14479                    }
14480                } else {
14481                    tag.append(" ");
14482                    stack.append("$");
14483                }
14484                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14485                    appendMemBucket(tag, mi.pss, mi.name, false);
14486                }
14487                appendMemBucket(stack, mi.pss, mi.name, true);
14488                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14489                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14490                    stack.append("(");
14491                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14492                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14493                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14494                            stack.append(":");
14495                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14496                        }
14497                    }
14498                    stack.append(")");
14499                }
14500            }
14501
14502            appendMemInfo(fullNativeBuilder, mi);
14503            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14504                // The short form only has native processes that are >= 512K.
14505                if (mi.pss >= 512) {
14506                    appendMemInfo(shortNativeBuilder, mi);
14507                } else {
14508                    extraNativeRam += mi.pss;
14509                    extraNativeMemtrack += mi.memtrack;
14510                }
14511            } else {
14512                // Short form has all other details, but if we have collected RAM
14513                // from smaller native processes let's dump a summary of that.
14514                if (extraNativeRam > 0) {
14515                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14516                            -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14517                    shortNativeBuilder.append('\n');
14518                    extraNativeRam = 0;
14519                }
14520                appendMemInfo(fullJavaBuilder, mi);
14521            }
14522        }
14523
14524        fullJavaBuilder.append("           ");
14525        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14526        fullJavaBuilder.append(" kB: TOTAL");
14527        if (totalMemtrack > 0) {
14528            fullJavaBuilder.append(" (");
14529            fullJavaBuilder.append(totalMemtrack);
14530            fullJavaBuilder.append(" kB memtrack)");
14531        } else {
14532        }
14533        fullJavaBuilder.append("\n");
14534
14535        MemInfoReader memInfo = new MemInfoReader();
14536        memInfo.readMemInfo();
14537        final long[] infos = memInfo.getRawInfo();
14538
14539        StringBuilder memInfoBuilder = new StringBuilder(1024);
14540        Debug.getMemInfo(infos);
14541        memInfoBuilder.append("  MemInfo: ");
14542        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14543        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14544        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14545        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14546        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14547        memInfoBuilder.append("           ");
14548        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14549        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14550        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14551        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14552        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14553            memInfoBuilder.append("  ZRAM: ");
14554            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14555            memInfoBuilder.append(" kB RAM, ");
14556            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14557            memInfoBuilder.append(" kB swap total, ");
14558            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14559            memInfoBuilder.append(" kB swap free\n");
14560        }
14561        final long[] ksm = getKsmInfo();
14562        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14563                || ksm[KSM_VOLATILE] != 0) {
14564            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14565            memInfoBuilder.append(" kB saved from shared ");
14566            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14567            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14568            memInfoBuilder.append(" kB unshared; ");
14569            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14570        }
14571        memInfoBuilder.append("  Free RAM: ");
14572        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14573                + memInfo.getFreeSizeKb());
14574        memInfoBuilder.append(" kB\n");
14575        memInfoBuilder.append("  Used RAM: ");
14576        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14577        memInfoBuilder.append(" kB\n");
14578        memInfoBuilder.append("  Lost RAM: ");
14579        memInfoBuilder.append(memInfo.getTotalSizeKb()
14580                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14581                - memInfo.getKernelUsedSizeKb());
14582        memInfoBuilder.append(" kB\n");
14583        Slog.i(TAG, "Low on memory:");
14584        Slog.i(TAG, shortNativeBuilder.toString());
14585        Slog.i(TAG, fullJavaBuilder.toString());
14586        Slog.i(TAG, memInfoBuilder.toString());
14587
14588        StringBuilder dropBuilder = new StringBuilder(1024);
14589        /*
14590        StringWriter oomSw = new StringWriter();
14591        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14592        StringWriter catSw = new StringWriter();
14593        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14594        String[] emptyArgs = new String[] { };
14595        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14596        oomPw.flush();
14597        String oomString = oomSw.toString();
14598        */
14599        dropBuilder.append("Low on memory:");
14600        dropBuilder.append(stack);
14601        dropBuilder.append('\n');
14602        dropBuilder.append(fullNativeBuilder);
14603        dropBuilder.append(fullJavaBuilder);
14604        dropBuilder.append('\n');
14605        dropBuilder.append(memInfoBuilder);
14606        dropBuilder.append('\n');
14607        /*
14608        dropBuilder.append(oomString);
14609        dropBuilder.append('\n');
14610        */
14611        StringWriter catSw = new StringWriter();
14612        synchronized (ActivityManagerService.this) {
14613            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14614            String[] emptyArgs = new String[] { };
14615            catPw.println();
14616            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14617            catPw.println();
14618            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14619                    false, false, null);
14620            catPw.println();
14621            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14622            catPw.flush();
14623        }
14624        dropBuilder.append(catSw.toString());
14625        addErrorToDropBox("lowmem", null, "system_server", null,
14626                null, tag.toString(), dropBuilder.toString(), null, null);
14627        //Slog.i(TAG, "Sent to dropbox:");
14628        //Slog.i(TAG, dropBuilder.toString());
14629        synchronized (ActivityManagerService.this) {
14630            long now = SystemClock.uptimeMillis();
14631            if (mLastMemUsageReportTime < now) {
14632                mLastMemUsageReportTime = now;
14633            }
14634        }
14635    }
14636
14637    /**
14638     * Searches array of arguments for the specified string
14639     * @param args array of argument strings
14640     * @param value value to search for
14641     * @return true if the value is contained in the array
14642     */
14643    private static boolean scanArgs(String[] args, String value) {
14644        if (args != null) {
14645            for (String arg : args) {
14646                if (value.equals(arg)) {
14647                    return true;
14648                }
14649            }
14650        }
14651        return false;
14652    }
14653
14654    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14655            ContentProviderRecord cpr, boolean always) {
14656        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14657
14658        if (!inLaunching || always) {
14659            synchronized (cpr) {
14660                cpr.launchingApp = null;
14661                cpr.notifyAll();
14662            }
14663            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14664            String names[] = cpr.info.authority.split(";");
14665            for (int j = 0; j < names.length; j++) {
14666                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14667            }
14668        }
14669
14670        for (int i=0; i<cpr.connections.size(); i++) {
14671            ContentProviderConnection conn = cpr.connections.get(i);
14672            if (conn.waiting) {
14673                // If this connection is waiting for the provider, then we don't
14674                // need to mess with its process unless we are always removing
14675                // or for some reason the provider is not currently launching.
14676                if (inLaunching && !always) {
14677                    continue;
14678                }
14679            }
14680            ProcessRecord capp = conn.client;
14681            conn.dead = true;
14682            if (conn.stableCount > 0) {
14683                if (!capp.persistent && capp.thread != null
14684                        && capp.pid != 0
14685                        && capp.pid != MY_PID) {
14686                    capp.kill("depends on provider "
14687                            + cpr.name.flattenToShortString()
14688                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14689                }
14690            } else if (capp.thread != null && conn.provider.provider != null) {
14691                try {
14692                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14693                } catch (RemoteException e) {
14694                }
14695                // In the protocol here, we don't expect the client to correctly
14696                // clean up this connection, we'll just remove it.
14697                cpr.connections.remove(i);
14698                conn.client.conProviders.remove(conn);
14699            }
14700        }
14701
14702        if (inLaunching && always) {
14703            mLaunchingProviders.remove(cpr);
14704        }
14705        return inLaunching;
14706    }
14707
14708    /**
14709     * Main code for cleaning up a process when it has gone away.  This is
14710     * called both as a result of the process dying, or directly when stopping
14711     * a process when running in single process mode.
14712     *
14713     * @return Returns true if the given process has been restarted, so the
14714     * app that was passed in must remain on the process lists.
14715     */
14716    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14717            boolean restarting, boolean allowRestart, int index) {
14718        if (index >= 0) {
14719            removeLruProcessLocked(app);
14720            ProcessList.remove(app.pid);
14721        }
14722
14723        mProcessesToGc.remove(app);
14724        mPendingPssProcesses.remove(app);
14725
14726        // Dismiss any open dialogs.
14727        if (app.crashDialog != null && !app.forceCrashReport) {
14728            app.crashDialog.dismiss();
14729            app.crashDialog = null;
14730        }
14731        if (app.anrDialog != null) {
14732            app.anrDialog.dismiss();
14733            app.anrDialog = null;
14734        }
14735        if (app.waitDialog != null) {
14736            app.waitDialog.dismiss();
14737            app.waitDialog = null;
14738        }
14739
14740        app.crashing = false;
14741        app.notResponding = false;
14742
14743        app.resetPackageList(mProcessStats);
14744        app.unlinkDeathRecipient();
14745        app.makeInactive(mProcessStats);
14746        app.waitingToKill = null;
14747        app.forcingToForeground = null;
14748        updateProcessForegroundLocked(app, false, false);
14749        app.foregroundActivities = false;
14750        app.hasShownUi = false;
14751        app.treatLikeActivity = false;
14752        app.hasAboveClient = false;
14753        app.hasClientActivities = false;
14754
14755        mServices.killServicesLocked(app, allowRestart);
14756
14757        boolean restart = false;
14758
14759        // Remove published content providers.
14760        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14761            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14762            final boolean always = app.bad || !allowRestart;
14763            if (removeDyingProviderLocked(app, cpr, always) || always) {
14764                // We left the provider in the launching list, need to
14765                // restart it.
14766                restart = true;
14767            }
14768
14769            cpr.provider = null;
14770            cpr.proc = null;
14771        }
14772        app.pubProviders.clear();
14773
14774        // Take care of any launching providers waiting for this process.
14775        if (checkAppInLaunchingProvidersLocked(app, false)) {
14776            restart = true;
14777        }
14778
14779        // Unregister from connected content providers.
14780        if (!app.conProviders.isEmpty()) {
14781            for (int i=0; i<app.conProviders.size(); i++) {
14782                ContentProviderConnection conn = app.conProviders.get(i);
14783                conn.provider.connections.remove(conn);
14784            }
14785            app.conProviders.clear();
14786        }
14787
14788        // At this point there may be remaining entries in mLaunchingProviders
14789        // where we were the only one waiting, so they are no longer of use.
14790        // Look for these and clean up if found.
14791        // XXX Commented out for now.  Trying to figure out a way to reproduce
14792        // the actual situation to identify what is actually going on.
14793        if (false) {
14794            for (int i=0; i<mLaunchingProviders.size(); i++) {
14795                ContentProviderRecord cpr = (ContentProviderRecord)
14796                        mLaunchingProviders.get(i);
14797                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14798                    synchronized (cpr) {
14799                        cpr.launchingApp = null;
14800                        cpr.notifyAll();
14801                    }
14802                }
14803            }
14804        }
14805
14806        skipCurrentReceiverLocked(app);
14807
14808        // Unregister any receivers.
14809        for (int i=app.receivers.size()-1; i>=0; i--) {
14810            removeReceiverLocked(app.receivers.valueAt(i));
14811        }
14812        app.receivers.clear();
14813
14814        // If the app is undergoing backup, tell the backup manager about it
14815        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14816            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14817                    + mBackupTarget.appInfo + " died during backup");
14818            try {
14819                IBackupManager bm = IBackupManager.Stub.asInterface(
14820                        ServiceManager.getService(Context.BACKUP_SERVICE));
14821                bm.agentDisconnected(app.info.packageName);
14822            } catch (RemoteException e) {
14823                // can't happen; backup manager is local
14824            }
14825        }
14826
14827        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14828            ProcessChangeItem item = mPendingProcessChanges.get(i);
14829            if (item.pid == app.pid) {
14830                mPendingProcessChanges.remove(i);
14831                mAvailProcessChanges.add(item);
14832            }
14833        }
14834        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14835
14836        // If the caller is restarting this app, then leave it in its
14837        // current lists and let the caller take care of it.
14838        if (restarting) {
14839            return false;
14840        }
14841
14842        if (!app.persistent || app.isolated) {
14843            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14844                    "Removing non-persistent process during cleanup: " + app);
14845            mProcessNames.remove(app.processName, app.uid);
14846            mIsolatedProcesses.remove(app.uid);
14847            if (mHeavyWeightProcess == app) {
14848                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14849                        mHeavyWeightProcess.userId, 0));
14850                mHeavyWeightProcess = null;
14851            }
14852        } else if (!app.removed) {
14853            // This app is persistent, so we need to keep its record around.
14854            // If it is not already on the pending app list, add it there
14855            // and start a new process for it.
14856            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14857                mPersistentStartingProcesses.add(app);
14858                restart = true;
14859            }
14860        }
14861        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14862                "Clean-up removing on hold: " + app);
14863        mProcessesOnHold.remove(app);
14864
14865        if (app == mHomeProcess) {
14866            mHomeProcess = null;
14867        }
14868        if (app == mPreviousProcess) {
14869            mPreviousProcess = null;
14870        }
14871
14872        if (restart && !app.isolated) {
14873            // We have components that still need to be running in the
14874            // process, so re-launch it.
14875            if (index < 0) {
14876                ProcessList.remove(app.pid);
14877            }
14878            mProcessNames.put(app.processName, app.uid, app);
14879            startProcessLocked(app, "restart", app.processName);
14880            return true;
14881        } else if (app.pid > 0 && app.pid != MY_PID) {
14882            // Goodbye!
14883            boolean removed;
14884            synchronized (mPidsSelfLocked) {
14885                mPidsSelfLocked.remove(app.pid);
14886                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14887            }
14888            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14889            if (app.isolated) {
14890                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14891            }
14892            app.setPid(0);
14893        }
14894        return false;
14895    }
14896
14897    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14898        // Look through the content providers we are waiting to have launched,
14899        // and if any run in this process then either schedule a restart of
14900        // the process or kill the client waiting for it if this process has
14901        // gone bad.
14902        int NL = mLaunchingProviders.size();
14903        boolean restart = false;
14904        for (int i=0; i<NL; i++) {
14905            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14906            if (cpr.launchingApp == app) {
14907                if (!alwaysBad && !app.bad) {
14908                    restart = true;
14909                } else {
14910                    removeDyingProviderLocked(app, cpr, true);
14911                    // cpr should have been removed from mLaunchingProviders
14912                    NL = mLaunchingProviders.size();
14913                    i--;
14914                }
14915            }
14916        }
14917        return restart;
14918    }
14919
14920    // =========================================================
14921    // SERVICES
14922    // =========================================================
14923
14924    @Override
14925    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14926            int flags) {
14927        enforceNotIsolatedCaller("getServices");
14928        synchronized (this) {
14929            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14930        }
14931    }
14932
14933    @Override
14934    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14935        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14936        synchronized (this) {
14937            return mServices.getRunningServiceControlPanelLocked(name);
14938        }
14939    }
14940
14941    @Override
14942    public ComponentName startService(IApplicationThread caller, Intent service,
14943            String resolvedType, int userId) {
14944        enforceNotIsolatedCaller("startService");
14945        // Refuse possible leaked file descriptors
14946        if (service != null && service.hasFileDescriptors() == true) {
14947            throw new IllegalArgumentException("File descriptors passed in Intent");
14948        }
14949
14950        if (DEBUG_SERVICE)
14951            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14952        synchronized(this) {
14953            final int callingPid = Binder.getCallingPid();
14954            final int callingUid = Binder.getCallingUid();
14955            final long origId = Binder.clearCallingIdentity();
14956            ComponentName res = mServices.startServiceLocked(caller, service,
14957                    resolvedType, callingPid, callingUid, userId);
14958            Binder.restoreCallingIdentity(origId);
14959            return res;
14960        }
14961    }
14962
14963    ComponentName startServiceInPackage(int uid,
14964            Intent service, String resolvedType, int userId) {
14965        synchronized(this) {
14966            if (DEBUG_SERVICE)
14967                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14968            final long origId = Binder.clearCallingIdentity();
14969            ComponentName res = mServices.startServiceLocked(null, service,
14970                    resolvedType, -1, uid, userId);
14971            Binder.restoreCallingIdentity(origId);
14972            return res;
14973        }
14974    }
14975
14976    @Override
14977    public int stopService(IApplicationThread caller, Intent service,
14978            String resolvedType, int userId) {
14979        enforceNotIsolatedCaller("stopService");
14980        // Refuse possible leaked file descriptors
14981        if (service != null && service.hasFileDescriptors() == true) {
14982            throw new IllegalArgumentException("File descriptors passed in Intent");
14983        }
14984
14985        synchronized(this) {
14986            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14987        }
14988    }
14989
14990    @Override
14991    public IBinder peekService(Intent service, String resolvedType) {
14992        enforceNotIsolatedCaller("peekService");
14993        // Refuse possible leaked file descriptors
14994        if (service != null && service.hasFileDescriptors() == true) {
14995            throw new IllegalArgumentException("File descriptors passed in Intent");
14996        }
14997        synchronized(this) {
14998            return mServices.peekServiceLocked(service, resolvedType);
14999        }
15000    }
15001
15002    @Override
15003    public boolean stopServiceToken(ComponentName className, IBinder token,
15004            int startId) {
15005        synchronized(this) {
15006            return mServices.stopServiceTokenLocked(className, token, startId);
15007        }
15008    }
15009
15010    @Override
15011    public void setServiceForeground(ComponentName className, IBinder token,
15012            int id, Notification notification, boolean removeNotification) {
15013        synchronized(this) {
15014            mServices.setServiceForegroundLocked(className, token, id, notification,
15015                    removeNotification);
15016        }
15017    }
15018
15019    @Override
15020    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15021            boolean requireFull, String name, String callerPackage) {
15022        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15023                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15024    }
15025
15026    int unsafeConvertIncomingUser(int userId) {
15027        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15028                ? mCurrentUserId : userId;
15029    }
15030
15031    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15032            int allowMode, String name, String callerPackage) {
15033        final int callingUserId = UserHandle.getUserId(callingUid);
15034        if (callingUserId == userId) {
15035            return userId;
15036        }
15037
15038        // Note that we may be accessing mCurrentUserId outside of a lock...
15039        // shouldn't be a big deal, if this is being called outside
15040        // of a locked context there is intrinsically a race with
15041        // the value the caller will receive and someone else changing it.
15042        // We assume that USER_CURRENT_OR_SELF will use the current user; later
15043        // we will switch to the calling user if access to the current user fails.
15044        int targetUserId = unsafeConvertIncomingUser(userId);
15045
15046        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15047            final boolean allow;
15048            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15049                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15050                // If the caller has this permission, they always pass go.  And collect $200.
15051                allow = true;
15052            } else if (allowMode == ALLOW_FULL_ONLY) {
15053                // We require full access, sucks to be you.
15054                allow = false;
15055            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15056                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15057                // If the caller does not have either permission, they are always doomed.
15058                allow = false;
15059            } else if (allowMode == ALLOW_NON_FULL) {
15060                // We are blanket allowing non-full access, you lucky caller!
15061                allow = true;
15062            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15063                // We may or may not allow this depending on whether the two users are
15064                // in the same profile.
15065                synchronized (mUserProfileGroupIdsSelfLocked) {
15066                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15067                            UserInfo.NO_PROFILE_GROUP_ID);
15068                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15069                            UserInfo.NO_PROFILE_GROUP_ID);
15070                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15071                            && callingProfile == targetProfile;
15072                }
15073            } else {
15074                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15075            }
15076            if (!allow) {
15077                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15078                    // In this case, they would like to just execute as their
15079                    // owner user instead of failing.
15080                    targetUserId = callingUserId;
15081                } else {
15082                    StringBuilder builder = new StringBuilder(128);
15083                    builder.append("Permission Denial: ");
15084                    builder.append(name);
15085                    if (callerPackage != null) {
15086                        builder.append(" from ");
15087                        builder.append(callerPackage);
15088                    }
15089                    builder.append(" asks to run as user ");
15090                    builder.append(userId);
15091                    builder.append(" but is calling from user ");
15092                    builder.append(UserHandle.getUserId(callingUid));
15093                    builder.append("; this requires ");
15094                    builder.append(INTERACT_ACROSS_USERS_FULL);
15095                    if (allowMode != ALLOW_FULL_ONLY) {
15096                        builder.append(" or ");
15097                        builder.append(INTERACT_ACROSS_USERS);
15098                    }
15099                    String msg = builder.toString();
15100                    Slog.w(TAG, msg);
15101                    throw new SecurityException(msg);
15102                }
15103            }
15104        }
15105        if (!allowAll && targetUserId < 0) {
15106            throw new IllegalArgumentException(
15107                    "Call does not support special user #" + targetUserId);
15108        }
15109        // Check shell permission
15110        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15111            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15112                    targetUserId)) {
15113                throw new SecurityException("Shell does not have permission to access user "
15114                        + targetUserId + "\n " + Debug.getCallers(3));
15115            }
15116        }
15117        return targetUserId;
15118    }
15119
15120    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15121            String className, int flags) {
15122        boolean result = false;
15123        // For apps that don't have pre-defined UIDs, check for permission
15124        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15125            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15126                if (ActivityManager.checkUidPermission(
15127                        INTERACT_ACROSS_USERS,
15128                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15129                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15130                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15131                            + " requests FLAG_SINGLE_USER, but app does not hold "
15132                            + INTERACT_ACROSS_USERS;
15133                    Slog.w(TAG, msg);
15134                    throw new SecurityException(msg);
15135                }
15136                // Permission passed
15137                result = true;
15138            }
15139        } else if ("system".equals(componentProcessName)) {
15140            result = true;
15141        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15142            // Phone app and persistent apps are allowed to export singleuser providers.
15143            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15144                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15145        }
15146        if (DEBUG_MU) {
15147            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15148                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15149        }
15150        return result;
15151    }
15152
15153    /**
15154     * Checks to see if the caller is in the same app as the singleton
15155     * component, or the component is in a special app. It allows special apps
15156     * to export singleton components but prevents exporting singleton
15157     * components for regular apps.
15158     */
15159    boolean isValidSingletonCall(int callingUid, int componentUid) {
15160        int componentAppId = UserHandle.getAppId(componentUid);
15161        return UserHandle.isSameApp(callingUid, componentUid)
15162                || componentAppId == Process.SYSTEM_UID
15163                || componentAppId == Process.PHONE_UID
15164                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15165                        == PackageManager.PERMISSION_GRANTED;
15166    }
15167
15168    public int bindService(IApplicationThread caller, IBinder token,
15169            Intent service, String resolvedType,
15170            IServiceConnection connection, int flags, int userId) {
15171        enforceNotIsolatedCaller("bindService");
15172
15173        // Refuse possible leaked file descriptors
15174        if (service != null && service.hasFileDescriptors() == true) {
15175            throw new IllegalArgumentException("File descriptors passed in Intent");
15176        }
15177
15178        synchronized(this) {
15179            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15180                    connection, flags, userId);
15181        }
15182    }
15183
15184    public boolean unbindService(IServiceConnection connection) {
15185        synchronized (this) {
15186            return mServices.unbindServiceLocked(connection);
15187        }
15188    }
15189
15190    public void publishService(IBinder token, Intent intent, IBinder service) {
15191        // Refuse possible leaked file descriptors
15192        if (intent != null && intent.hasFileDescriptors() == true) {
15193            throw new IllegalArgumentException("File descriptors passed in Intent");
15194        }
15195
15196        synchronized(this) {
15197            if (!(token instanceof ServiceRecord)) {
15198                throw new IllegalArgumentException("Invalid service token");
15199            }
15200            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15201        }
15202    }
15203
15204    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15205        // Refuse possible leaked file descriptors
15206        if (intent != null && intent.hasFileDescriptors() == true) {
15207            throw new IllegalArgumentException("File descriptors passed in Intent");
15208        }
15209
15210        synchronized(this) {
15211            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15212        }
15213    }
15214
15215    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15216        synchronized(this) {
15217            if (!(token instanceof ServiceRecord)) {
15218                throw new IllegalArgumentException("Invalid service token");
15219            }
15220            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15221        }
15222    }
15223
15224    // =========================================================
15225    // BACKUP AND RESTORE
15226    // =========================================================
15227
15228    // Cause the target app to be launched if necessary and its backup agent
15229    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15230    // activity manager to announce its creation.
15231    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15232        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15233        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15234
15235        synchronized(this) {
15236            // !!! TODO: currently no check here that we're already bound
15237            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15238            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15239            synchronized (stats) {
15240                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15241            }
15242
15243            // Backup agent is now in use, its package can't be stopped.
15244            try {
15245                AppGlobals.getPackageManager().setPackageStoppedState(
15246                        app.packageName, false, UserHandle.getUserId(app.uid));
15247            } catch (RemoteException e) {
15248            } catch (IllegalArgumentException e) {
15249                Slog.w(TAG, "Failed trying to unstop package "
15250                        + app.packageName + ": " + e);
15251            }
15252
15253            BackupRecord r = new BackupRecord(ss, app, backupMode);
15254            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15255                    ? new ComponentName(app.packageName, app.backupAgentName)
15256                    : new ComponentName("android", "FullBackupAgent");
15257            // startProcessLocked() returns existing proc's record if it's already running
15258            ProcessRecord proc = startProcessLocked(app.processName, app,
15259                    false, 0, "backup", hostingName, false, false, false);
15260            if (proc == null) {
15261                Slog.e(TAG, "Unable to start backup agent process " + r);
15262                return false;
15263            }
15264
15265            r.app = proc;
15266            mBackupTarget = r;
15267            mBackupAppName = app.packageName;
15268
15269            // Try not to kill the process during backup
15270            updateOomAdjLocked(proc);
15271
15272            // If the process is already attached, schedule the creation of the backup agent now.
15273            // If it is not yet live, this will be done when it attaches to the framework.
15274            if (proc.thread != null) {
15275                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15276                try {
15277                    proc.thread.scheduleCreateBackupAgent(app,
15278                            compatibilityInfoForPackageLocked(app), backupMode);
15279                } catch (RemoteException e) {
15280                    // Will time out on the backup manager side
15281                }
15282            } else {
15283                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15284            }
15285            // Invariants: at this point, the target app process exists and the application
15286            // is either already running or in the process of coming up.  mBackupTarget and
15287            // mBackupAppName describe the app, so that when it binds back to the AM we
15288            // know that it's scheduled for a backup-agent operation.
15289        }
15290
15291        return true;
15292    }
15293
15294    @Override
15295    public void clearPendingBackup() {
15296        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15297        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15298
15299        synchronized (this) {
15300            mBackupTarget = null;
15301            mBackupAppName = null;
15302        }
15303    }
15304
15305    // A backup agent has just come up
15306    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15307        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15308                + " = " + agent);
15309
15310        synchronized(this) {
15311            if (!agentPackageName.equals(mBackupAppName)) {
15312                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15313                return;
15314            }
15315        }
15316
15317        long oldIdent = Binder.clearCallingIdentity();
15318        try {
15319            IBackupManager bm = IBackupManager.Stub.asInterface(
15320                    ServiceManager.getService(Context.BACKUP_SERVICE));
15321            bm.agentConnected(agentPackageName, agent);
15322        } catch (RemoteException e) {
15323            // can't happen; the backup manager service is local
15324        } catch (Exception e) {
15325            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15326            e.printStackTrace();
15327        } finally {
15328            Binder.restoreCallingIdentity(oldIdent);
15329        }
15330    }
15331
15332    // done with this agent
15333    public void unbindBackupAgent(ApplicationInfo appInfo) {
15334        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15335        if (appInfo == null) {
15336            Slog.w(TAG, "unbind backup agent for null app");
15337            return;
15338        }
15339
15340        synchronized(this) {
15341            try {
15342                if (mBackupAppName == null) {
15343                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15344                    return;
15345                }
15346
15347                if (!mBackupAppName.equals(appInfo.packageName)) {
15348                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15349                    return;
15350                }
15351
15352                // Not backing this app up any more; reset its OOM adjustment
15353                final ProcessRecord proc = mBackupTarget.app;
15354                updateOomAdjLocked(proc);
15355
15356                // If the app crashed during backup, 'thread' will be null here
15357                if (proc.thread != null) {
15358                    try {
15359                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15360                                compatibilityInfoForPackageLocked(appInfo));
15361                    } catch (Exception e) {
15362                        Slog.e(TAG, "Exception when unbinding backup agent:");
15363                        e.printStackTrace();
15364                    }
15365                }
15366            } finally {
15367                mBackupTarget = null;
15368                mBackupAppName = null;
15369            }
15370        }
15371    }
15372    // =========================================================
15373    // BROADCASTS
15374    // =========================================================
15375
15376    private final List getStickiesLocked(String action, IntentFilter filter,
15377            List cur, int userId) {
15378        final ContentResolver resolver = mContext.getContentResolver();
15379        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15380        if (stickies == null) {
15381            return cur;
15382        }
15383        final ArrayList<Intent> list = stickies.get(action);
15384        if (list == null) {
15385            return cur;
15386        }
15387        int N = list.size();
15388        for (int i=0; i<N; i++) {
15389            Intent intent = list.get(i);
15390            if (filter.match(resolver, intent, true, TAG) >= 0) {
15391                if (cur == null) {
15392                    cur = new ArrayList<Intent>();
15393                }
15394                cur.add(intent);
15395            }
15396        }
15397        return cur;
15398    }
15399
15400    boolean isPendingBroadcastProcessLocked(int pid) {
15401        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15402                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15403    }
15404
15405    void skipPendingBroadcastLocked(int pid) {
15406            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15407            for (BroadcastQueue queue : mBroadcastQueues) {
15408                queue.skipPendingBroadcastLocked(pid);
15409            }
15410    }
15411
15412    // The app just attached; send any pending broadcasts that it should receive
15413    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15414        boolean didSomething = false;
15415        for (BroadcastQueue queue : mBroadcastQueues) {
15416            didSomething |= queue.sendPendingBroadcastsLocked(app);
15417        }
15418        return didSomething;
15419    }
15420
15421    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15422            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15423        enforceNotIsolatedCaller("registerReceiver");
15424        int callingUid;
15425        int callingPid;
15426        synchronized(this) {
15427            ProcessRecord callerApp = null;
15428            if (caller != null) {
15429                callerApp = getRecordForAppLocked(caller);
15430                if (callerApp == null) {
15431                    throw new SecurityException(
15432                            "Unable to find app for caller " + caller
15433                            + " (pid=" + Binder.getCallingPid()
15434                            + ") when registering receiver " + receiver);
15435                }
15436                if (callerApp.info.uid != Process.SYSTEM_UID &&
15437                        !callerApp.pkgList.containsKey(callerPackage) &&
15438                        !"android".equals(callerPackage)) {
15439                    throw new SecurityException("Given caller package " + callerPackage
15440                            + " is not running in process " + callerApp);
15441                }
15442                callingUid = callerApp.info.uid;
15443                callingPid = callerApp.pid;
15444            } else {
15445                callerPackage = null;
15446                callingUid = Binder.getCallingUid();
15447                callingPid = Binder.getCallingPid();
15448            }
15449
15450            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15451                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15452
15453            List allSticky = null;
15454
15455            // Look for any matching sticky broadcasts...
15456            Iterator actions = filter.actionsIterator();
15457            if (actions != null) {
15458                while (actions.hasNext()) {
15459                    String action = (String)actions.next();
15460                    allSticky = getStickiesLocked(action, filter, allSticky,
15461                            UserHandle.USER_ALL);
15462                    allSticky = getStickiesLocked(action, filter, allSticky,
15463                            UserHandle.getUserId(callingUid));
15464                }
15465            } else {
15466                allSticky = getStickiesLocked(null, filter, allSticky,
15467                        UserHandle.USER_ALL);
15468                allSticky = getStickiesLocked(null, filter, allSticky,
15469                        UserHandle.getUserId(callingUid));
15470            }
15471
15472            // The first sticky in the list is returned directly back to
15473            // the client.
15474            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15475
15476            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15477                    + ": " + sticky);
15478
15479            if (receiver == null) {
15480                return sticky;
15481            }
15482
15483            ReceiverList rl
15484                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15485            if (rl == null) {
15486                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15487                        userId, receiver);
15488                if (rl.app != null) {
15489                    rl.app.receivers.add(rl);
15490                } else {
15491                    try {
15492                        receiver.asBinder().linkToDeath(rl, 0);
15493                    } catch (RemoteException e) {
15494                        return sticky;
15495                    }
15496                    rl.linkedToDeath = true;
15497                }
15498                mRegisteredReceivers.put(receiver.asBinder(), rl);
15499            } else if (rl.uid != callingUid) {
15500                throw new IllegalArgumentException(
15501                        "Receiver requested to register for uid " + callingUid
15502                        + " was previously registered for uid " + rl.uid);
15503            } else if (rl.pid != callingPid) {
15504                throw new IllegalArgumentException(
15505                        "Receiver requested to register for pid " + callingPid
15506                        + " was previously registered for pid " + rl.pid);
15507            } else if (rl.userId != userId) {
15508                throw new IllegalArgumentException(
15509                        "Receiver requested to register for user " + userId
15510                        + " was previously registered for user " + rl.userId);
15511            }
15512            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15513                    permission, callingUid, userId);
15514            rl.add(bf);
15515            if (!bf.debugCheck()) {
15516                Slog.w(TAG, "==> For Dynamic broadast");
15517            }
15518            mReceiverResolver.addFilter(bf);
15519
15520            // Enqueue broadcasts for all existing stickies that match
15521            // this filter.
15522            if (allSticky != null) {
15523                ArrayList receivers = new ArrayList();
15524                receivers.add(bf);
15525
15526                int N = allSticky.size();
15527                for (int i=0; i<N; i++) {
15528                    Intent intent = (Intent)allSticky.get(i);
15529                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15530                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15531                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15532                            null, null, false, true, true, -1);
15533                    queue.enqueueParallelBroadcastLocked(r);
15534                    queue.scheduleBroadcastsLocked();
15535                }
15536            }
15537
15538            return sticky;
15539        }
15540    }
15541
15542    public void unregisterReceiver(IIntentReceiver receiver) {
15543        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15544
15545        final long origId = Binder.clearCallingIdentity();
15546        try {
15547            boolean doTrim = false;
15548
15549            synchronized(this) {
15550                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15551                if (rl != null) {
15552                    if (rl.curBroadcast != null) {
15553                        BroadcastRecord r = rl.curBroadcast;
15554                        final boolean doNext = finishReceiverLocked(
15555                                receiver.asBinder(), r.resultCode, r.resultData,
15556                                r.resultExtras, r.resultAbort);
15557                        if (doNext) {
15558                            doTrim = true;
15559                            r.queue.processNextBroadcast(false);
15560                        }
15561                    }
15562
15563                    if (rl.app != null) {
15564                        rl.app.receivers.remove(rl);
15565                    }
15566                    removeReceiverLocked(rl);
15567                    if (rl.linkedToDeath) {
15568                        rl.linkedToDeath = false;
15569                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15570                    }
15571                }
15572            }
15573
15574            // If we actually concluded any broadcasts, we might now be able
15575            // to trim the recipients' apps from our working set
15576            if (doTrim) {
15577                trimApplications();
15578                return;
15579            }
15580
15581        } finally {
15582            Binder.restoreCallingIdentity(origId);
15583        }
15584    }
15585
15586    void removeReceiverLocked(ReceiverList rl) {
15587        mRegisteredReceivers.remove(rl.receiver.asBinder());
15588        int N = rl.size();
15589        for (int i=0; i<N; i++) {
15590            mReceiverResolver.removeFilter(rl.get(i));
15591        }
15592    }
15593
15594    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15595        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15596            ProcessRecord r = mLruProcesses.get(i);
15597            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15598                try {
15599                    r.thread.dispatchPackageBroadcast(cmd, packages);
15600                } catch (RemoteException ex) {
15601                }
15602            }
15603        }
15604    }
15605
15606    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15607            int callingUid, int[] users) {
15608        List<ResolveInfo> receivers = null;
15609        try {
15610            HashSet<ComponentName> singleUserReceivers = null;
15611            boolean scannedFirstReceivers = false;
15612            for (int user : users) {
15613                // Skip users that have Shell restrictions
15614                if (callingUid == Process.SHELL_UID
15615                        && getUserManagerLocked().hasUserRestriction(
15616                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15617                    continue;
15618                }
15619                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15620                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15621                if (user != 0 && newReceivers != null) {
15622                    // If this is not the primary user, we need to check for
15623                    // any receivers that should be filtered out.
15624                    for (int i=0; i<newReceivers.size(); i++) {
15625                        ResolveInfo ri = newReceivers.get(i);
15626                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15627                            newReceivers.remove(i);
15628                            i--;
15629                        }
15630                    }
15631                }
15632                if (newReceivers != null && newReceivers.size() == 0) {
15633                    newReceivers = null;
15634                }
15635                if (receivers == null) {
15636                    receivers = newReceivers;
15637                } else if (newReceivers != null) {
15638                    // We need to concatenate the additional receivers
15639                    // found with what we have do far.  This would be easy,
15640                    // but we also need to de-dup any receivers that are
15641                    // singleUser.
15642                    if (!scannedFirstReceivers) {
15643                        // Collect any single user receivers we had already retrieved.
15644                        scannedFirstReceivers = true;
15645                        for (int i=0; i<receivers.size(); i++) {
15646                            ResolveInfo ri = receivers.get(i);
15647                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15648                                ComponentName cn = new ComponentName(
15649                                        ri.activityInfo.packageName, ri.activityInfo.name);
15650                                if (singleUserReceivers == null) {
15651                                    singleUserReceivers = new HashSet<ComponentName>();
15652                                }
15653                                singleUserReceivers.add(cn);
15654                            }
15655                        }
15656                    }
15657                    // Add the new results to the existing results, tracking
15658                    // and de-dupping single user receivers.
15659                    for (int i=0; i<newReceivers.size(); i++) {
15660                        ResolveInfo ri = newReceivers.get(i);
15661                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15662                            ComponentName cn = new ComponentName(
15663                                    ri.activityInfo.packageName, ri.activityInfo.name);
15664                            if (singleUserReceivers == null) {
15665                                singleUserReceivers = new HashSet<ComponentName>();
15666                            }
15667                            if (!singleUserReceivers.contains(cn)) {
15668                                singleUserReceivers.add(cn);
15669                                receivers.add(ri);
15670                            }
15671                        } else {
15672                            receivers.add(ri);
15673                        }
15674                    }
15675                }
15676            }
15677        } catch (RemoteException ex) {
15678            // pm is in same process, this will never happen.
15679        }
15680        return receivers;
15681    }
15682
15683    private final int broadcastIntentLocked(ProcessRecord callerApp,
15684            String callerPackage, Intent intent, String resolvedType,
15685            IIntentReceiver resultTo, int resultCode, String resultData,
15686            Bundle map, String requiredPermission, int appOp,
15687            boolean ordered, boolean sticky, int callingPid, int callingUid,
15688            int userId) {
15689        intent = new Intent(intent);
15690
15691        // By default broadcasts do not go to stopped apps.
15692        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15693
15694        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15695            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15696            + " ordered=" + ordered + " userid=" + userId);
15697        if ((resultTo != null) && !ordered) {
15698            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15699        }
15700
15701        userId = handleIncomingUser(callingPid, callingUid, userId,
15702                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15703
15704        // Make sure that the user who is receiving this broadcast is running.
15705        // If not, we will just skip it. Make an exception for shutdown broadcasts
15706        // and upgrade steps.
15707
15708        if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15709            if ((callingUid != Process.SYSTEM_UID
15710                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15711                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15712                Slog.w(TAG, "Skipping broadcast of " + intent
15713                        + ": user " + userId + " is stopped");
15714                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15715            }
15716        }
15717
15718        /*
15719         * Prevent non-system code (defined here to be non-persistent
15720         * processes) from sending protected broadcasts.
15721         */
15722        int callingAppId = UserHandle.getAppId(callingUid);
15723        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15724            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15725            || callingAppId == Process.NFC_UID || callingUid == 0) {
15726            // Always okay.
15727        } else if (callerApp == null || !callerApp.persistent) {
15728            try {
15729                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15730                        intent.getAction())) {
15731                    String msg = "Permission Denial: not allowed to send broadcast "
15732                            + intent.getAction() + " from pid="
15733                            + callingPid + ", uid=" + callingUid;
15734                    Slog.w(TAG, msg);
15735                    throw new SecurityException(msg);
15736                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15737                    // Special case for compatibility: we don't want apps to send this,
15738                    // but historically it has not been protected and apps may be using it
15739                    // to poke their own app widget.  So, instead of making it protected,
15740                    // just limit it to the caller.
15741                    if (callerApp == null) {
15742                        String msg = "Permission Denial: not allowed to send broadcast "
15743                                + intent.getAction() + " from unknown caller.";
15744                        Slog.w(TAG, msg);
15745                        throw new SecurityException(msg);
15746                    } else if (intent.getComponent() != null) {
15747                        // They are good enough to send to an explicit component...  verify
15748                        // it is being sent to the calling app.
15749                        if (!intent.getComponent().getPackageName().equals(
15750                                callerApp.info.packageName)) {
15751                            String msg = "Permission Denial: not allowed to send broadcast "
15752                                    + intent.getAction() + " to "
15753                                    + intent.getComponent().getPackageName() + " from "
15754                                    + callerApp.info.packageName;
15755                            Slog.w(TAG, msg);
15756                            throw new SecurityException(msg);
15757                        }
15758                    } else {
15759                        // Limit broadcast to their own package.
15760                        intent.setPackage(callerApp.info.packageName);
15761                    }
15762                }
15763            } catch (RemoteException e) {
15764                Slog.w(TAG, "Remote exception", e);
15765                return ActivityManager.BROADCAST_SUCCESS;
15766            }
15767        }
15768
15769        final String action = intent.getAction();
15770        if (action != null) {
15771            switch (action) {
15772                case Intent.ACTION_UID_REMOVED:
15773                case Intent.ACTION_PACKAGE_REMOVED:
15774                case Intent.ACTION_PACKAGE_CHANGED:
15775                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15776                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15777                    // Handle special intents: if this broadcast is from the package
15778                    // manager about a package being removed, we need to remove all of
15779                    // its activities from the history stack.
15780                    if (checkComponentPermission(
15781                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15782                            callingPid, callingUid, -1, true)
15783                            != PackageManager.PERMISSION_GRANTED) {
15784                        String msg = "Permission Denial: " + intent.getAction()
15785                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15786                                + ", uid=" + callingUid + ")"
15787                                + " requires "
15788                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15789                        Slog.w(TAG, msg);
15790                        throw new SecurityException(msg);
15791                    }
15792                    switch (action) {
15793                        case Intent.ACTION_UID_REMOVED:
15794                            final Bundle intentExtras = intent.getExtras();
15795                            final int uid = intentExtras != null
15796                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15797                            if (uid >= 0) {
15798                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15799                                synchronized (bs) {
15800                                    bs.removeUidStatsLocked(uid);
15801                                }
15802                                mAppOpsService.uidRemoved(uid);
15803                            }
15804                            break;
15805                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15806                            // If resources are unavailable just force stop all those packages
15807                            // and flush the attribute cache as well.
15808                            String list[] =
15809                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15810                            if (list != null && list.length > 0) {
15811                                for (int i = 0; i < list.length; i++) {
15812                                    forceStopPackageLocked(list[i], -1, false, true, true,
15813                                            false, false, userId, "storage unmount");
15814                                }
15815                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15816                                sendPackageBroadcastLocked(
15817                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15818                                        userId);
15819                            }
15820                            break;
15821                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15822                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15823                            break;
15824                        case Intent.ACTION_PACKAGE_REMOVED:
15825                        case Intent.ACTION_PACKAGE_CHANGED:
15826                            Uri data = intent.getData();
15827                            String ssp;
15828                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15829                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15830                                boolean fullUninstall = removed &&
15831                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15832                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15833                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15834                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15835                                            false, true, true, false, fullUninstall, userId,
15836                                            removed ? "pkg removed" : "pkg changed");
15837                                }
15838                                if (removed) {
15839                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15840                                            new String[] {ssp}, userId);
15841                                    if (fullUninstall) {
15842                                        mAppOpsService.packageRemoved(
15843                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15844
15845                                        // Remove all permissions granted from/to this package
15846                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15847
15848                                        removeTasksByPackageNameLocked(ssp, userId);
15849                                    }
15850                                } else {
15851                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15852                                    if (userId == UserHandle.USER_OWNER) {
15853                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15854                                    }
15855                                }
15856                            }
15857                            break;
15858                    }
15859                    break;
15860                case Intent.ACTION_PACKAGE_ADDED:
15861                    // Special case for adding a package: by default turn on compatibility mode.
15862                    Uri data = intent.getData();
15863                    String ssp;
15864                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15865                        final boolean replacing =
15866                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15867                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15868
15869                        if (replacing) {
15870                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15871                        }
15872                        if (userId == UserHandle.USER_OWNER) {
15873                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15874                        }
15875                    }
15876                    break;
15877                case Intent.ACTION_TIMEZONE_CHANGED:
15878                    // If this is the time zone changed action, queue up a message that will reset
15879                    // the timezone of all currently running processes. This message will get
15880                    // queued up before the broadcast happens.
15881                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15882                    break;
15883                case Intent.ACTION_TIME_CHANGED:
15884                    // If the user set the time, let all running processes know.
15885                    final int is24Hour =
15886                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15887                                    : 0;
15888                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15889                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15890                    synchronized (stats) {
15891                        stats.noteCurrentTimeChangedLocked();
15892                    }
15893                    break;
15894                case Intent.ACTION_CLEAR_DNS_CACHE:
15895                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15896                    break;
15897                case Proxy.PROXY_CHANGE_ACTION:
15898                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15899                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15900                    break;
15901            }
15902        }
15903
15904        // Add to the sticky list if requested.
15905        if (sticky) {
15906            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15907                    callingPid, callingUid)
15908                    != PackageManager.PERMISSION_GRANTED) {
15909                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15910                        + callingPid + ", uid=" + callingUid
15911                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15912                Slog.w(TAG, msg);
15913                throw new SecurityException(msg);
15914            }
15915            if (requiredPermission != null) {
15916                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15917                        + " and enforce permission " + requiredPermission);
15918                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15919            }
15920            if (intent.getComponent() != null) {
15921                throw new SecurityException(
15922                        "Sticky broadcasts can't target a specific component");
15923            }
15924            // We use userId directly here, since the "all" target is maintained
15925            // as a separate set of sticky broadcasts.
15926            if (userId != UserHandle.USER_ALL) {
15927                // But first, if this is not a broadcast to all users, then
15928                // make sure it doesn't conflict with an existing broadcast to
15929                // all users.
15930                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15931                        UserHandle.USER_ALL);
15932                if (stickies != null) {
15933                    ArrayList<Intent> list = stickies.get(intent.getAction());
15934                    if (list != null) {
15935                        int N = list.size();
15936                        int i;
15937                        for (i=0; i<N; i++) {
15938                            if (intent.filterEquals(list.get(i))) {
15939                                throw new IllegalArgumentException(
15940                                        "Sticky broadcast " + intent + " for user "
15941                                        + userId + " conflicts with existing global broadcast");
15942                            }
15943                        }
15944                    }
15945                }
15946            }
15947            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15948            if (stickies == null) {
15949                stickies = new ArrayMap<String, ArrayList<Intent>>();
15950                mStickyBroadcasts.put(userId, stickies);
15951            }
15952            ArrayList<Intent> list = stickies.get(intent.getAction());
15953            if (list == null) {
15954                list = new ArrayList<Intent>();
15955                stickies.put(intent.getAction(), list);
15956            }
15957            int N = list.size();
15958            int i;
15959            for (i=0; i<N; i++) {
15960                if (intent.filterEquals(list.get(i))) {
15961                    // This sticky already exists, replace it.
15962                    list.set(i, new Intent(intent));
15963                    break;
15964                }
15965            }
15966            if (i >= N) {
15967                list.add(new Intent(intent));
15968            }
15969        }
15970
15971        int[] users;
15972        if (userId == UserHandle.USER_ALL) {
15973            // Caller wants broadcast to go to all started users.
15974            users = mStartedUserArray;
15975        } else {
15976            // Caller wants broadcast to go to one specific user.
15977            users = new int[] {userId};
15978        }
15979
15980        // Figure out who all will receive this broadcast.
15981        List receivers = null;
15982        List<BroadcastFilter> registeredReceivers = null;
15983        // Need to resolve the intent to interested receivers...
15984        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15985                 == 0) {
15986            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15987        }
15988        if (intent.getComponent() == null) {
15989            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15990                // Query one target user at a time, excluding shell-restricted users
15991                UserManagerService ums = getUserManagerLocked();
15992                for (int i = 0; i < users.length; i++) {
15993                    if (ums.hasUserRestriction(
15994                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15995                        continue;
15996                    }
15997                    List<BroadcastFilter> registeredReceiversForUser =
15998                            mReceiverResolver.queryIntent(intent,
15999                                    resolvedType, false, users[i]);
16000                    if (registeredReceivers == null) {
16001                        registeredReceivers = registeredReceiversForUser;
16002                    } else if (registeredReceiversForUser != null) {
16003                        registeredReceivers.addAll(registeredReceiversForUser);
16004                    }
16005                }
16006            } else {
16007                registeredReceivers = mReceiverResolver.queryIntent(intent,
16008                        resolvedType, false, userId);
16009            }
16010        }
16011
16012        final boolean replacePending =
16013                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16014
16015        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16016                + " replacePending=" + replacePending);
16017
16018        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16019        if (!ordered && NR > 0) {
16020            // If we are not serializing this broadcast, then send the
16021            // registered receivers separately so they don't wait for the
16022            // components to be launched.
16023            final BroadcastQueue queue = broadcastQueueForIntent(intent);
16024            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16025                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16026                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16027                    ordered, sticky, false, userId);
16028            if (DEBUG_BROADCAST) Slog.v(
16029                    TAG, "Enqueueing parallel broadcast " + r);
16030            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16031            if (!replaced) {
16032                queue.enqueueParallelBroadcastLocked(r);
16033                queue.scheduleBroadcastsLocked();
16034            }
16035            registeredReceivers = null;
16036            NR = 0;
16037        }
16038
16039        // Merge into one list.
16040        int ir = 0;
16041        if (receivers != null) {
16042            // A special case for PACKAGE_ADDED: do not allow the package
16043            // being added to see this broadcast.  This prevents them from
16044            // using this as a back door to get run as soon as they are
16045            // installed.  Maybe in the future we want to have a special install
16046            // broadcast or such for apps, but we'd like to deliberately make
16047            // this decision.
16048            String skipPackages[] = null;
16049            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16050                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16051                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16052                Uri data = intent.getData();
16053                if (data != null) {
16054                    String pkgName = data.getSchemeSpecificPart();
16055                    if (pkgName != null) {
16056                        skipPackages = new String[] { pkgName };
16057                    }
16058                }
16059            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16060                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16061            }
16062            if (skipPackages != null && (skipPackages.length > 0)) {
16063                for (String skipPackage : skipPackages) {
16064                    if (skipPackage != null) {
16065                        int NT = receivers.size();
16066                        for (int it=0; it<NT; it++) {
16067                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16068                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16069                                receivers.remove(it);
16070                                it--;
16071                                NT--;
16072                            }
16073                        }
16074                    }
16075                }
16076            }
16077
16078            int NT = receivers != null ? receivers.size() : 0;
16079            int it = 0;
16080            ResolveInfo curt = null;
16081            BroadcastFilter curr = null;
16082            while (it < NT && ir < NR) {
16083                if (curt == null) {
16084                    curt = (ResolveInfo)receivers.get(it);
16085                }
16086                if (curr == null) {
16087                    curr = registeredReceivers.get(ir);
16088                }
16089                if (curr.getPriority() >= curt.priority) {
16090                    // Insert this broadcast record into the final list.
16091                    receivers.add(it, curr);
16092                    ir++;
16093                    curr = null;
16094                    it++;
16095                    NT++;
16096                } else {
16097                    // Skip to the next ResolveInfo in the final list.
16098                    it++;
16099                    curt = null;
16100                }
16101            }
16102        }
16103        while (ir < NR) {
16104            if (receivers == null) {
16105                receivers = new ArrayList();
16106            }
16107            receivers.add(registeredReceivers.get(ir));
16108            ir++;
16109        }
16110
16111        if ((receivers != null && receivers.size() > 0)
16112                || resultTo != null) {
16113            BroadcastQueue queue = broadcastQueueForIntent(intent);
16114            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16115                    callerPackage, callingPid, callingUid, resolvedType,
16116                    requiredPermission, appOp, receivers, resultTo, resultCode,
16117                    resultData, map, ordered, sticky, false, userId);
16118            if (DEBUG_BROADCAST) Slog.v(
16119                    TAG, "Enqueueing ordered broadcast " + r
16120                    + ": prev had " + queue.mOrderedBroadcasts.size());
16121            if (DEBUG_BROADCAST) {
16122                int seq = r.intent.getIntExtra("seq", -1);
16123                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16124            }
16125            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16126            if (!replaced) {
16127                queue.enqueueOrderedBroadcastLocked(r);
16128                queue.scheduleBroadcastsLocked();
16129            }
16130        }
16131
16132        return ActivityManager.BROADCAST_SUCCESS;
16133    }
16134
16135    final Intent verifyBroadcastLocked(Intent intent) {
16136        // Refuse possible leaked file descriptors
16137        if (intent != null && intent.hasFileDescriptors() == true) {
16138            throw new IllegalArgumentException("File descriptors passed in Intent");
16139        }
16140
16141        int flags = intent.getFlags();
16142
16143        if (!mProcessesReady) {
16144            // if the caller really truly claims to know what they're doing, go
16145            // ahead and allow the broadcast without launching any receivers
16146            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16147                intent = new Intent(intent);
16148                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16149            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16150                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16151                        + " before boot completion");
16152                throw new IllegalStateException("Cannot broadcast before boot completed");
16153            }
16154        }
16155
16156        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16157            throw new IllegalArgumentException(
16158                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16159        }
16160
16161        return intent;
16162    }
16163
16164    public final int broadcastIntent(IApplicationThread caller,
16165            Intent intent, String resolvedType, IIntentReceiver resultTo,
16166            int resultCode, String resultData, Bundle map,
16167            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16168        enforceNotIsolatedCaller("broadcastIntent");
16169        synchronized(this) {
16170            intent = verifyBroadcastLocked(intent);
16171
16172            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16173            final int callingPid = Binder.getCallingPid();
16174            final int callingUid = Binder.getCallingUid();
16175            final long origId = Binder.clearCallingIdentity();
16176            int res = broadcastIntentLocked(callerApp,
16177                    callerApp != null ? callerApp.info.packageName : null,
16178                    intent, resolvedType, resultTo,
16179                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16180                    callingPid, callingUid, userId);
16181            Binder.restoreCallingIdentity(origId);
16182            return res;
16183        }
16184    }
16185
16186    int broadcastIntentInPackage(String packageName, int uid,
16187            Intent intent, String resolvedType, IIntentReceiver resultTo,
16188            int resultCode, String resultData, Bundle map,
16189            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16190        synchronized(this) {
16191            intent = verifyBroadcastLocked(intent);
16192
16193            final long origId = Binder.clearCallingIdentity();
16194            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16195                    resultTo, resultCode, resultData, map, requiredPermission,
16196                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16197            Binder.restoreCallingIdentity(origId);
16198            return res;
16199        }
16200    }
16201
16202    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16203        // Refuse possible leaked file descriptors
16204        if (intent != null && intent.hasFileDescriptors() == true) {
16205            throw new IllegalArgumentException("File descriptors passed in Intent");
16206        }
16207
16208        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16209                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16210
16211        synchronized(this) {
16212            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16213                    != PackageManager.PERMISSION_GRANTED) {
16214                String msg = "Permission Denial: unbroadcastIntent() from pid="
16215                        + Binder.getCallingPid()
16216                        + ", uid=" + Binder.getCallingUid()
16217                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16218                Slog.w(TAG, msg);
16219                throw new SecurityException(msg);
16220            }
16221            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16222            if (stickies != null) {
16223                ArrayList<Intent> list = stickies.get(intent.getAction());
16224                if (list != null) {
16225                    int N = list.size();
16226                    int i;
16227                    for (i=0; i<N; i++) {
16228                        if (intent.filterEquals(list.get(i))) {
16229                            list.remove(i);
16230                            break;
16231                        }
16232                    }
16233                    if (list.size() <= 0) {
16234                        stickies.remove(intent.getAction());
16235                    }
16236                }
16237                if (stickies.size() <= 0) {
16238                    mStickyBroadcasts.remove(userId);
16239                }
16240            }
16241        }
16242    }
16243
16244    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16245            String resultData, Bundle resultExtras, boolean resultAbort) {
16246        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16247        if (r == null) {
16248            Slog.w(TAG, "finishReceiver called but not found on queue");
16249            return false;
16250        }
16251
16252        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16253    }
16254
16255    void backgroundServicesFinishedLocked(int userId) {
16256        for (BroadcastQueue queue : mBroadcastQueues) {
16257            queue.backgroundServicesFinishedLocked(userId);
16258        }
16259    }
16260
16261    public void finishReceiver(IBinder who, int resultCode, String resultData,
16262            Bundle resultExtras, boolean resultAbort) {
16263        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16264
16265        // Refuse possible leaked file descriptors
16266        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16267            throw new IllegalArgumentException("File descriptors passed in Bundle");
16268        }
16269
16270        final long origId = Binder.clearCallingIdentity();
16271        try {
16272            boolean doNext = false;
16273            BroadcastRecord r;
16274
16275            synchronized(this) {
16276                r = broadcastRecordForReceiverLocked(who);
16277                if (r != null) {
16278                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16279                        resultData, resultExtras, resultAbort, true);
16280                }
16281            }
16282
16283            if (doNext) {
16284                r.queue.processNextBroadcast(false);
16285            }
16286            trimApplications();
16287        } finally {
16288            Binder.restoreCallingIdentity(origId);
16289        }
16290    }
16291
16292    // =========================================================
16293    // INSTRUMENTATION
16294    // =========================================================
16295
16296    public boolean startInstrumentation(ComponentName className,
16297            String profileFile, int flags, Bundle arguments,
16298            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16299            int userId, String abiOverride) {
16300        enforceNotIsolatedCaller("startInstrumentation");
16301        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16302                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16303        // Refuse possible leaked file descriptors
16304        if (arguments != null && arguments.hasFileDescriptors()) {
16305            throw new IllegalArgumentException("File descriptors passed in Bundle");
16306        }
16307
16308        synchronized(this) {
16309            InstrumentationInfo ii = null;
16310            ApplicationInfo ai = null;
16311            try {
16312                ii = mContext.getPackageManager().getInstrumentationInfo(
16313                    className, STOCK_PM_FLAGS);
16314                ai = AppGlobals.getPackageManager().getApplicationInfo(
16315                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16316            } catch (PackageManager.NameNotFoundException e) {
16317            } catch (RemoteException e) {
16318            }
16319            if (ii == null) {
16320                reportStartInstrumentationFailure(watcher, className,
16321                        "Unable to find instrumentation info for: " + className);
16322                return false;
16323            }
16324            if (ai == null) {
16325                reportStartInstrumentationFailure(watcher, className,
16326                        "Unable to find instrumentation target package: " + ii.targetPackage);
16327                return false;
16328            }
16329
16330            int match = mContext.getPackageManager().checkSignatures(
16331                    ii.targetPackage, ii.packageName);
16332            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16333                String msg = "Permission Denial: starting instrumentation "
16334                        + className + " from pid="
16335                        + Binder.getCallingPid()
16336                        + ", uid=" + Binder.getCallingPid()
16337                        + " not allowed because package " + ii.packageName
16338                        + " does not have a signature matching the target "
16339                        + ii.targetPackage;
16340                reportStartInstrumentationFailure(watcher, className, msg);
16341                throw new SecurityException(msg);
16342            }
16343
16344            final long origId = Binder.clearCallingIdentity();
16345            // Instrumentation can kill and relaunch even persistent processes
16346            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16347                    "start instr");
16348            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16349            app.instrumentationClass = className;
16350            app.instrumentationInfo = ai;
16351            app.instrumentationProfileFile = profileFile;
16352            app.instrumentationArguments = arguments;
16353            app.instrumentationWatcher = watcher;
16354            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16355            app.instrumentationResultClass = className;
16356            Binder.restoreCallingIdentity(origId);
16357        }
16358
16359        return true;
16360    }
16361
16362    /**
16363     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16364     * error to the logs, but if somebody is watching, send the report there too.  This enables
16365     * the "am" command to report errors with more information.
16366     *
16367     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16368     * @param cn The component name of the instrumentation.
16369     * @param report The error report.
16370     */
16371    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16372            ComponentName cn, String report) {
16373        Slog.w(TAG, report);
16374        try {
16375            if (watcher != null) {
16376                Bundle results = new Bundle();
16377                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16378                results.putString("Error", report);
16379                watcher.instrumentationStatus(cn, -1, results);
16380            }
16381        } catch (RemoteException e) {
16382            Slog.w(TAG, e);
16383        }
16384    }
16385
16386    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16387        if (app.instrumentationWatcher != null) {
16388            try {
16389                // NOTE:  IInstrumentationWatcher *must* be oneway here
16390                app.instrumentationWatcher.instrumentationFinished(
16391                    app.instrumentationClass,
16392                    resultCode,
16393                    results);
16394            } catch (RemoteException e) {
16395            }
16396        }
16397        if (app.instrumentationUiAutomationConnection != null) {
16398            try {
16399                app.instrumentationUiAutomationConnection.shutdown();
16400            } catch (RemoteException re) {
16401                /* ignore */
16402            }
16403            // Only a UiAutomation can set this flag and now that
16404            // it is finished we make sure it is reset to its default.
16405            mUserIsMonkey = false;
16406        }
16407        app.instrumentationWatcher = null;
16408        app.instrumentationUiAutomationConnection = null;
16409        app.instrumentationClass = null;
16410        app.instrumentationInfo = null;
16411        app.instrumentationProfileFile = null;
16412        app.instrumentationArguments = null;
16413
16414        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16415                "finished inst");
16416    }
16417
16418    public void finishInstrumentation(IApplicationThread target,
16419            int resultCode, Bundle results) {
16420        int userId = UserHandle.getCallingUserId();
16421        // Refuse possible leaked file descriptors
16422        if (results != null && results.hasFileDescriptors()) {
16423            throw new IllegalArgumentException("File descriptors passed in Intent");
16424        }
16425
16426        synchronized(this) {
16427            ProcessRecord app = getRecordForAppLocked(target);
16428            if (app == null) {
16429                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16430                return;
16431            }
16432            final long origId = Binder.clearCallingIdentity();
16433            finishInstrumentationLocked(app, resultCode, results);
16434            Binder.restoreCallingIdentity(origId);
16435        }
16436    }
16437
16438    // =========================================================
16439    // CONFIGURATION
16440    // =========================================================
16441
16442    public ConfigurationInfo getDeviceConfigurationInfo() {
16443        ConfigurationInfo config = new ConfigurationInfo();
16444        synchronized (this) {
16445            config.reqTouchScreen = mConfiguration.touchscreen;
16446            config.reqKeyboardType = mConfiguration.keyboard;
16447            config.reqNavigation = mConfiguration.navigation;
16448            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16449                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16450                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16451            }
16452            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16453                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16454                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16455            }
16456            config.reqGlEsVersion = GL_ES_VERSION;
16457        }
16458        return config;
16459    }
16460
16461    ActivityStack getFocusedStack() {
16462        return mStackSupervisor.getFocusedStack();
16463    }
16464
16465    public Configuration getConfiguration() {
16466        Configuration ci;
16467        synchronized(this) {
16468            ci = new Configuration(mConfiguration);
16469        }
16470        return ci;
16471    }
16472
16473    public void updatePersistentConfiguration(Configuration values) {
16474        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16475                "updateConfiguration()");
16476        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16477                "updateConfiguration()");
16478        if (values == null) {
16479            throw new NullPointerException("Configuration must not be null");
16480        }
16481
16482        synchronized(this) {
16483            final long origId = Binder.clearCallingIdentity();
16484            updateConfigurationLocked(values, null, true, false);
16485            Binder.restoreCallingIdentity(origId);
16486        }
16487    }
16488
16489    public void updateConfiguration(Configuration values) {
16490        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16491                "updateConfiguration()");
16492
16493        synchronized(this) {
16494            if (values == null && mWindowManager != null) {
16495                // sentinel: fetch the current configuration from the window manager
16496                values = mWindowManager.computeNewConfiguration();
16497            }
16498
16499            if (mWindowManager != null) {
16500                mProcessList.applyDisplaySize(mWindowManager);
16501            }
16502
16503            final long origId = Binder.clearCallingIdentity();
16504            if (values != null) {
16505                Settings.System.clearConfiguration(values);
16506            }
16507            updateConfigurationLocked(values, null, false, false);
16508            Binder.restoreCallingIdentity(origId);
16509        }
16510    }
16511
16512    /**
16513     * Do either or both things: (1) change the current configuration, and (2)
16514     * make sure the given activity is running with the (now) current
16515     * configuration.  Returns true if the activity has been left running, or
16516     * false if <var>starting</var> is being destroyed to match the new
16517     * configuration.
16518     * @param persistent TODO
16519     */
16520    boolean updateConfigurationLocked(Configuration values,
16521            ActivityRecord starting, boolean persistent, boolean initLocale) {
16522        int changes = 0;
16523
16524        if (values != null) {
16525            Configuration newConfig = new Configuration(mConfiguration);
16526            changes = newConfig.updateFrom(values);
16527            if (changes != 0) {
16528                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16529                    Slog.i(TAG, "Updating configuration to: " + values);
16530                }
16531
16532                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16533
16534                if (values.locale != null && !initLocale) {
16535                    saveLocaleLocked(values.locale,
16536                                     !values.locale.equals(mConfiguration.locale),
16537                                     values.userSetLocale);
16538                }
16539
16540                mConfigurationSeq++;
16541                if (mConfigurationSeq <= 0) {
16542                    mConfigurationSeq = 1;
16543                }
16544                newConfig.seq = mConfigurationSeq;
16545                mConfiguration = newConfig;
16546                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16547                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16548                //mUsageStatsService.noteStartConfig(newConfig);
16549
16550                final Configuration configCopy = new Configuration(mConfiguration);
16551
16552                // TODO: If our config changes, should we auto dismiss any currently
16553                // showing dialogs?
16554                mShowDialogs = shouldShowDialogs(newConfig);
16555
16556                AttributeCache ac = AttributeCache.instance();
16557                if (ac != null) {
16558                    ac.updateConfiguration(configCopy);
16559                }
16560
16561                // Make sure all resources in our process are updated
16562                // right now, so that anyone who is going to retrieve
16563                // resource values after we return will be sure to get
16564                // the new ones.  This is especially important during
16565                // boot, where the first config change needs to guarantee
16566                // all resources have that config before following boot
16567                // code is executed.
16568                mSystemThread.applyConfigurationToResources(configCopy);
16569
16570                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16571                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16572                    msg.obj = new Configuration(configCopy);
16573                    mHandler.sendMessage(msg);
16574                }
16575
16576                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16577                    ProcessRecord app = mLruProcesses.get(i);
16578                    try {
16579                        if (app.thread != null) {
16580                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16581                                    + app.processName + " new config " + mConfiguration);
16582                            app.thread.scheduleConfigurationChanged(configCopy);
16583                        }
16584                    } catch (Exception e) {
16585                    }
16586                }
16587                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16588                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16589                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16590                        | Intent.FLAG_RECEIVER_FOREGROUND);
16591                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16592                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16593                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16594                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16595                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16596                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16597                    broadcastIntentLocked(null, null, intent,
16598                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16599                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16600                }
16601            }
16602        }
16603
16604        boolean kept = true;
16605        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16606        // mainStack is null during startup.
16607        if (mainStack != null) {
16608            if (changes != 0 && starting == null) {
16609                // If the configuration changed, and the caller is not already
16610                // in the process of starting an activity, then find the top
16611                // activity to check if its configuration needs to change.
16612                starting = mainStack.topRunningActivityLocked(null);
16613            }
16614
16615            if (starting != null) {
16616                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16617                // And we need to make sure at this point that all other activities
16618                // are made visible with the correct configuration.
16619                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16620            }
16621        }
16622
16623        if (values != null && mWindowManager != null) {
16624            mWindowManager.setNewConfiguration(mConfiguration);
16625        }
16626
16627        return kept;
16628    }
16629
16630    /**
16631     * Decide based on the configuration whether we should shouw the ANR,
16632     * crash, etc dialogs.  The idea is that if there is no affordnace to
16633     * press the on-screen buttons, we shouldn't show the dialog.
16634     *
16635     * A thought: SystemUI might also want to get told about this, the Power
16636     * dialog / global actions also might want different behaviors.
16637     */
16638    private static final boolean shouldShowDialogs(Configuration config) {
16639        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16640                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16641    }
16642
16643    /**
16644     * Save the locale.  You must be inside a synchronized (this) block.
16645     */
16646    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16647        if(isDiff) {
16648            SystemProperties.set("user.language", l.getLanguage());
16649            SystemProperties.set("user.region", l.getCountry());
16650        }
16651
16652        if(isPersist) {
16653            SystemProperties.set("persist.sys.language", l.getLanguage());
16654            SystemProperties.set("persist.sys.country", l.getCountry());
16655            SystemProperties.set("persist.sys.localevar", l.getVariant());
16656
16657            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16658        }
16659    }
16660
16661    @Override
16662    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16663        synchronized (this) {
16664            ActivityRecord srec = ActivityRecord.forToken(token);
16665            if (srec.task != null && srec.task.stack != null) {
16666                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16667            }
16668        }
16669        return false;
16670    }
16671
16672    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16673            Intent resultData) {
16674
16675        synchronized (this) {
16676            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16677            if (stack != null) {
16678                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16679            }
16680            return false;
16681        }
16682    }
16683
16684    public int getLaunchedFromUid(IBinder activityToken) {
16685        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16686        if (srec == null) {
16687            return -1;
16688        }
16689        return srec.launchedFromUid;
16690    }
16691
16692    public String getLaunchedFromPackage(IBinder activityToken) {
16693        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16694        if (srec == null) {
16695            return null;
16696        }
16697        return srec.launchedFromPackage;
16698    }
16699
16700    // =========================================================
16701    // LIFETIME MANAGEMENT
16702    // =========================================================
16703
16704    // Returns which broadcast queue the app is the current [or imminent] receiver
16705    // on, or 'null' if the app is not an active broadcast recipient.
16706    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16707        BroadcastRecord r = app.curReceiver;
16708        if (r != null) {
16709            return r.queue;
16710        }
16711
16712        // It's not the current receiver, but it might be starting up to become one
16713        synchronized (this) {
16714            for (BroadcastQueue queue : mBroadcastQueues) {
16715                r = queue.mPendingBroadcast;
16716                if (r != null && r.curApp == app) {
16717                    // found it; report which queue it's in
16718                    return queue;
16719                }
16720            }
16721        }
16722
16723        return null;
16724    }
16725
16726    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16727            boolean doingAll, long now) {
16728        if (mAdjSeq == app.adjSeq) {
16729            // This adjustment has already been computed.
16730            return app.curRawAdj;
16731        }
16732
16733        if (app.thread == null) {
16734            app.adjSeq = mAdjSeq;
16735            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16736            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16737            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16738        }
16739
16740        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16741        app.adjSource = null;
16742        app.adjTarget = null;
16743        app.empty = false;
16744        app.cached = false;
16745
16746        final int activitiesSize = app.activities.size();
16747
16748        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16749            // The max adjustment doesn't allow this app to be anything
16750            // below foreground, so it is not worth doing work for it.
16751            app.adjType = "fixed";
16752            app.adjSeq = mAdjSeq;
16753            app.curRawAdj = app.maxAdj;
16754            app.foregroundActivities = false;
16755            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16756            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16757            // System processes can do UI, and when they do we want to have
16758            // them trim their memory after the user leaves the UI.  To
16759            // facilitate this, here we need to determine whether or not it
16760            // is currently showing UI.
16761            app.systemNoUi = true;
16762            if (app == TOP_APP) {
16763                app.systemNoUi = false;
16764            } else if (activitiesSize > 0) {
16765                for (int j = 0; j < activitiesSize; j++) {
16766                    final ActivityRecord r = app.activities.get(j);
16767                    if (r.visible) {
16768                        app.systemNoUi = false;
16769                    }
16770                }
16771            }
16772            if (!app.systemNoUi) {
16773                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16774            }
16775            return (app.curAdj=app.maxAdj);
16776        }
16777
16778        app.systemNoUi = false;
16779
16780        // Determine the importance of the process, starting with most
16781        // important to least, and assign an appropriate OOM adjustment.
16782        int adj;
16783        int schedGroup;
16784        int procState;
16785        boolean foregroundActivities = false;
16786        BroadcastQueue queue;
16787        if (app == TOP_APP) {
16788            // The last app on the list is the foreground app.
16789            adj = ProcessList.FOREGROUND_APP_ADJ;
16790            schedGroup = Process.THREAD_GROUP_DEFAULT;
16791            app.adjType = "top-activity";
16792            foregroundActivities = true;
16793            procState = ActivityManager.PROCESS_STATE_TOP;
16794        } else if (app.instrumentationClass != null) {
16795            // Don't want to kill running instrumentation.
16796            adj = ProcessList.FOREGROUND_APP_ADJ;
16797            schedGroup = Process.THREAD_GROUP_DEFAULT;
16798            app.adjType = "instrumentation";
16799            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16800        } else if ((queue = isReceivingBroadcast(app)) != null) {
16801            // An app that is currently receiving a broadcast also
16802            // counts as being in the foreground for OOM killer purposes.
16803            // It's placed in a sched group based on the nature of the
16804            // broadcast as reflected by which queue it's active in.
16805            adj = ProcessList.FOREGROUND_APP_ADJ;
16806            schedGroup = (queue == mFgBroadcastQueue)
16807                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16808            app.adjType = "broadcast";
16809            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16810        } else if (app.executingServices.size() > 0) {
16811            // An app that is currently executing a service callback also
16812            // counts as being in the foreground.
16813            adj = ProcessList.FOREGROUND_APP_ADJ;
16814            schedGroup = app.execServicesFg ?
16815                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16816            app.adjType = "exec-service";
16817            procState = ActivityManager.PROCESS_STATE_SERVICE;
16818            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16819        } else {
16820            // As far as we know the process is empty.  We may change our mind later.
16821            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16822            // At this point we don't actually know the adjustment.  Use the cached adj
16823            // value that the caller wants us to.
16824            adj = cachedAdj;
16825            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16826            app.cached = true;
16827            app.empty = true;
16828            app.adjType = "cch-empty";
16829        }
16830
16831        // Examine all activities if not already foreground.
16832        if (!foregroundActivities && activitiesSize > 0) {
16833            for (int j = 0; j < activitiesSize; j++) {
16834                final ActivityRecord r = app.activities.get(j);
16835                if (r.app != app) {
16836                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16837                            + app + "?!?");
16838                    continue;
16839                }
16840                if (r.visible) {
16841                    // App has a visible activity; only upgrade adjustment.
16842                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16843                        adj = ProcessList.VISIBLE_APP_ADJ;
16844                        app.adjType = "visible";
16845                    }
16846                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16847                        procState = ActivityManager.PROCESS_STATE_TOP;
16848                    }
16849                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16850                    app.cached = false;
16851                    app.empty = false;
16852                    foregroundActivities = true;
16853                    break;
16854                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16855                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16856                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16857                        app.adjType = "pausing";
16858                    }
16859                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16860                        procState = ActivityManager.PROCESS_STATE_TOP;
16861                    }
16862                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16863                    app.cached = false;
16864                    app.empty = false;
16865                    foregroundActivities = true;
16866                } else if (r.state == ActivityState.STOPPING) {
16867                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16868                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16869                        app.adjType = "stopping";
16870                    }
16871                    // For the process state, we will at this point consider the
16872                    // process to be cached.  It will be cached either as an activity
16873                    // or empty depending on whether the activity is finishing.  We do
16874                    // this so that we can treat the process as cached for purposes of
16875                    // memory trimming (determing current memory level, trim command to
16876                    // send to process) since there can be an arbitrary number of stopping
16877                    // processes and they should soon all go into the cached state.
16878                    if (!r.finishing) {
16879                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16880                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16881                        }
16882                    }
16883                    app.cached = false;
16884                    app.empty = false;
16885                    foregroundActivities = true;
16886                } else {
16887                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16888                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16889                        app.adjType = "cch-act";
16890                    }
16891                }
16892            }
16893        }
16894
16895        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16896            if (app.foregroundServices) {
16897                // The user is aware of this app, so make it visible.
16898                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16899                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16900                app.cached = false;
16901                app.adjType = "fg-service";
16902                schedGroup = Process.THREAD_GROUP_DEFAULT;
16903            } else if (app.forcingToForeground != null) {
16904                // The user is aware of this app, so make it visible.
16905                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16906                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16907                app.cached = false;
16908                app.adjType = "force-fg";
16909                app.adjSource = app.forcingToForeground;
16910                schedGroup = Process.THREAD_GROUP_DEFAULT;
16911            }
16912        }
16913
16914        if (app == mHeavyWeightProcess) {
16915            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16916                // We don't want to kill the current heavy-weight process.
16917                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16918                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16919                app.cached = false;
16920                app.adjType = "heavy";
16921            }
16922            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16923                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16924            }
16925        }
16926
16927        if (app == mHomeProcess) {
16928            if (adj > ProcessList.HOME_APP_ADJ) {
16929                // This process is hosting what we currently consider to be the
16930                // home app, so we don't want to let it go into the background.
16931                adj = ProcessList.HOME_APP_ADJ;
16932                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16933                app.cached = false;
16934                app.adjType = "home";
16935            }
16936            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16937                procState = ActivityManager.PROCESS_STATE_HOME;
16938            }
16939        }
16940
16941        if (app == mPreviousProcess && app.activities.size() > 0) {
16942            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16943                // This was the previous process that showed UI to the user.
16944                // We want to try to keep it around more aggressively, to give
16945                // a good experience around switching between two apps.
16946                adj = ProcessList.PREVIOUS_APP_ADJ;
16947                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16948                app.cached = false;
16949                app.adjType = "previous";
16950            }
16951            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16952                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16953            }
16954        }
16955
16956        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16957                + " reason=" + app.adjType);
16958
16959        // By default, we use the computed adjustment.  It may be changed if
16960        // there are applications dependent on our services or providers, but
16961        // this gives us a baseline and makes sure we don't get into an
16962        // infinite recursion.
16963        app.adjSeq = mAdjSeq;
16964        app.curRawAdj = adj;
16965        app.hasStartedServices = false;
16966
16967        if (mBackupTarget != null && app == mBackupTarget.app) {
16968            // If possible we want to avoid killing apps while they're being backed up
16969            if (adj > ProcessList.BACKUP_APP_ADJ) {
16970                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16971                adj = ProcessList.BACKUP_APP_ADJ;
16972                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16973                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16974                }
16975                app.adjType = "backup";
16976                app.cached = false;
16977            }
16978            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16979                procState = ActivityManager.PROCESS_STATE_BACKUP;
16980            }
16981        }
16982
16983        boolean mayBeTop = false;
16984
16985        for (int is = app.services.size()-1;
16986                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16987                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16988                        || procState > ActivityManager.PROCESS_STATE_TOP);
16989                is--) {
16990            ServiceRecord s = app.services.valueAt(is);
16991            if (s.startRequested) {
16992                app.hasStartedServices = true;
16993                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16994                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16995                }
16996                if (app.hasShownUi && app != mHomeProcess) {
16997                    // If this process has shown some UI, let it immediately
16998                    // go to the LRU list because it may be pretty heavy with
16999                    // UI stuff.  We'll tag it with a label just to help
17000                    // debug and understand what is going on.
17001                    if (adj > ProcessList.SERVICE_ADJ) {
17002                        app.adjType = "cch-started-ui-services";
17003                    }
17004                } else {
17005                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17006                        // This service has seen some activity within
17007                        // recent memory, so we will keep its process ahead
17008                        // of the background processes.
17009                        if (adj > ProcessList.SERVICE_ADJ) {
17010                            adj = ProcessList.SERVICE_ADJ;
17011                            app.adjType = "started-services";
17012                            app.cached = false;
17013                        }
17014                    }
17015                    // If we have let the service slide into the background
17016                    // state, still have some text describing what it is doing
17017                    // even though the service no longer has an impact.
17018                    if (adj > ProcessList.SERVICE_ADJ) {
17019                        app.adjType = "cch-started-services";
17020                    }
17021                }
17022            }
17023            for (int conni = s.connections.size()-1;
17024                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17025                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17026                            || procState > ActivityManager.PROCESS_STATE_TOP);
17027                    conni--) {
17028                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17029                for (int i = 0;
17030                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17031                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17032                                || procState > ActivityManager.PROCESS_STATE_TOP);
17033                        i++) {
17034                    // XXX should compute this based on the max of
17035                    // all connected clients.
17036                    ConnectionRecord cr = clist.get(i);
17037                    if (cr.binding.client == app) {
17038                        // Binding to ourself is not interesting.
17039                        continue;
17040                    }
17041                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17042                        ProcessRecord client = cr.binding.client;
17043                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
17044                                TOP_APP, doingAll, now);
17045                        int clientProcState = client.curProcState;
17046                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17047                            // If the other app is cached for any reason, for purposes here
17048                            // we are going to consider it empty.  The specific cached state
17049                            // doesn't propagate except under certain conditions.
17050                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17051                        }
17052                        String adjType = null;
17053                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17054                            // Not doing bind OOM management, so treat
17055                            // this guy more like a started service.
17056                            if (app.hasShownUi && app != mHomeProcess) {
17057                                // If this process has shown some UI, let it immediately
17058                                // go to the LRU list because it may be pretty heavy with
17059                                // UI stuff.  We'll tag it with a label just to help
17060                                // debug and understand what is going on.
17061                                if (adj > clientAdj) {
17062                                    adjType = "cch-bound-ui-services";
17063                                }
17064                                app.cached = false;
17065                                clientAdj = adj;
17066                                clientProcState = procState;
17067                            } else {
17068                                if (now >= (s.lastActivity
17069                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17070                                    // This service has not seen activity within
17071                                    // recent memory, so allow it to drop to the
17072                                    // LRU list if there is no other reason to keep
17073                                    // it around.  We'll also tag it with a label just
17074                                    // to help debug and undertand what is going on.
17075                                    if (adj > clientAdj) {
17076                                        adjType = "cch-bound-services";
17077                                    }
17078                                    clientAdj = adj;
17079                                }
17080                            }
17081                        }
17082                        if (adj > clientAdj) {
17083                            // If this process has recently shown UI, and
17084                            // the process that is binding to it is less
17085                            // important than being visible, then we don't
17086                            // care about the binding as much as we care
17087                            // about letting this process get into the LRU
17088                            // list to be killed and restarted if needed for
17089                            // memory.
17090                            if (app.hasShownUi && app != mHomeProcess
17091                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17092                                adjType = "cch-bound-ui-services";
17093                            } else {
17094                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17095                                        |Context.BIND_IMPORTANT)) != 0) {
17096                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17097                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17098                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17099                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17100                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17101                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17102                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17103                                    adj = clientAdj;
17104                                } else {
17105                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17106                                        adj = ProcessList.VISIBLE_APP_ADJ;
17107                                    }
17108                                }
17109                                if (!client.cached) {
17110                                    app.cached = false;
17111                                }
17112                                adjType = "service";
17113                            }
17114                        }
17115                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17116                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17117                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17118                            }
17119                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17120                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17121                                    // Special handling of clients who are in the top state.
17122                                    // We *may* want to consider this process to be in the
17123                                    // top state as well, but only if there is not another
17124                                    // reason for it to be running.  Being on the top is a
17125                                    // special state, meaning you are specifically running
17126                                    // for the current top app.  If the process is already
17127                                    // running in the background for some other reason, it
17128                                    // is more important to continue considering it to be
17129                                    // in the background state.
17130                                    mayBeTop = true;
17131                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17132                                } else {
17133                                    // Special handling for above-top states (persistent
17134                                    // processes).  These should not bring the current process
17135                                    // into the top state, since they are not on top.  Instead
17136                                    // give them the best state after that.
17137                                    clientProcState =
17138                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17139                                }
17140                            }
17141                        } else {
17142                            if (clientProcState <
17143                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17144                                clientProcState =
17145                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17146                            }
17147                        }
17148                        if (procState > clientProcState) {
17149                            procState = clientProcState;
17150                        }
17151                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17152                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17153                            app.pendingUiClean = true;
17154                        }
17155                        if (adjType != null) {
17156                            app.adjType = adjType;
17157                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17158                                    .REASON_SERVICE_IN_USE;
17159                            app.adjSource = cr.binding.client;
17160                            app.adjSourceProcState = clientProcState;
17161                            app.adjTarget = s.name;
17162                        }
17163                    }
17164                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17165                        app.treatLikeActivity = true;
17166                    }
17167                    final ActivityRecord a = cr.activity;
17168                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17169                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17170                                (a.visible || a.state == ActivityState.RESUMED
17171                                 || a.state == ActivityState.PAUSING)) {
17172                            adj = ProcessList.FOREGROUND_APP_ADJ;
17173                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17174                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17175                            }
17176                            app.cached = false;
17177                            app.adjType = "service";
17178                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17179                                    .REASON_SERVICE_IN_USE;
17180                            app.adjSource = a;
17181                            app.adjSourceProcState = procState;
17182                            app.adjTarget = s.name;
17183                        }
17184                    }
17185                }
17186            }
17187        }
17188
17189        for (int provi = app.pubProviders.size()-1;
17190                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17191                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17192                        || procState > ActivityManager.PROCESS_STATE_TOP);
17193                provi--) {
17194            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17195            for (int i = cpr.connections.size()-1;
17196                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17197                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17198                            || procState > ActivityManager.PROCESS_STATE_TOP);
17199                    i--) {
17200                ContentProviderConnection conn = cpr.connections.get(i);
17201                ProcessRecord client = conn.client;
17202                if (client == app) {
17203                    // Being our own client is not interesting.
17204                    continue;
17205                }
17206                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17207                int clientProcState = client.curProcState;
17208                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17209                    // If the other app is cached for any reason, for purposes here
17210                    // we are going to consider it empty.
17211                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17212                }
17213                if (adj > clientAdj) {
17214                    if (app.hasShownUi && app != mHomeProcess
17215                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17216                        app.adjType = "cch-ui-provider";
17217                    } else {
17218                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17219                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17220                        app.adjType = "provider";
17221                    }
17222                    app.cached &= client.cached;
17223                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17224                            .REASON_PROVIDER_IN_USE;
17225                    app.adjSource = client;
17226                    app.adjSourceProcState = clientProcState;
17227                    app.adjTarget = cpr.name;
17228                }
17229                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17230                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17231                        // Special handling of clients who are in the top state.
17232                        // We *may* want to consider this process to be in the
17233                        // top state as well, but only if there is not another
17234                        // reason for it to be running.  Being on the top is a
17235                        // special state, meaning you are specifically running
17236                        // for the current top app.  If the process is already
17237                        // running in the background for some other reason, it
17238                        // is more important to continue considering it to be
17239                        // in the background state.
17240                        mayBeTop = true;
17241                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17242                    } else {
17243                        // Special handling for above-top states (persistent
17244                        // processes).  These should not bring the current process
17245                        // into the top state, since they are not on top.  Instead
17246                        // give them the best state after that.
17247                        clientProcState =
17248                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17249                    }
17250                }
17251                if (procState > clientProcState) {
17252                    procState = clientProcState;
17253                }
17254                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17255                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17256                }
17257            }
17258            // If the provider has external (non-framework) process
17259            // dependencies, ensure that its adjustment is at least
17260            // FOREGROUND_APP_ADJ.
17261            if (cpr.hasExternalProcessHandles()) {
17262                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17263                    adj = ProcessList.FOREGROUND_APP_ADJ;
17264                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17265                    app.cached = false;
17266                    app.adjType = "provider";
17267                    app.adjTarget = cpr.name;
17268                }
17269                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17270                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17271                }
17272            }
17273        }
17274
17275        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17276            // A client of one of our services or providers is in the top state.  We
17277            // *may* want to be in the top state, but not if we are already running in
17278            // the background for some other reason.  For the decision here, we are going
17279            // to pick out a few specific states that we want to remain in when a client
17280            // is top (states that tend to be longer-term) and otherwise allow it to go
17281            // to the top state.
17282            switch (procState) {
17283                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17284                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17285                case ActivityManager.PROCESS_STATE_SERVICE:
17286                    // These all are longer-term states, so pull them up to the top
17287                    // of the background states, but not all the way to the top state.
17288                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17289                    break;
17290                default:
17291                    // Otherwise, top is a better choice, so take it.
17292                    procState = ActivityManager.PROCESS_STATE_TOP;
17293                    break;
17294            }
17295        }
17296
17297        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17298            if (app.hasClientActivities) {
17299                // This is a cached process, but with client activities.  Mark it so.
17300                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17301                app.adjType = "cch-client-act";
17302            } else if (app.treatLikeActivity) {
17303                // This is a cached process, but somebody wants us to treat it like it has
17304                // an activity, okay!
17305                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17306                app.adjType = "cch-as-act";
17307            }
17308        }
17309
17310        if (adj == ProcessList.SERVICE_ADJ) {
17311            if (doingAll) {
17312                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17313                mNewNumServiceProcs++;
17314                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17315                if (!app.serviceb) {
17316                    // This service isn't far enough down on the LRU list to
17317                    // normally be a B service, but if we are low on RAM and it
17318                    // is large we want to force it down since we would prefer to
17319                    // keep launcher over it.
17320                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17321                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17322                        app.serviceHighRam = true;
17323                        app.serviceb = true;
17324                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17325                    } else {
17326                        mNewNumAServiceProcs++;
17327                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17328                    }
17329                } else {
17330                    app.serviceHighRam = false;
17331                }
17332            }
17333            if (app.serviceb) {
17334                adj = ProcessList.SERVICE_B_ADJ;
17335            }
17336        }
17337
17338        app.curRawAdj = adj;
17339
17340        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17341        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17342        if (adj > app.maxAdj) {
17343            adj = app.maxAdj;
17344            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17345                schedGroup = Process.THREAD_GROUP_DEFAULT;
17346            }
17347        }
17348
17349        // Do final modification to adj.  Everything we do between here and applying
17350        // the final setAdj must be done in this function, because we will also use
17351        // it when computing the final cached adj later.  Note that we don't need to
17352        // worry about this for max adj above, since max adj will always be used to
17353        // keep it out of the cached vaues.
17354        app.curAdj = app.modifyRawOomAdj(adj);
17355        app.curSchedGroup = schedGroup;
17356        app.curProcState = procState;
17357        app.foregroundActivities = foregroundActivities;
17358
17359        return app.curRawAdj;
17360    }
17361
17362    /**
17363     * Record new PSS sample for a process.
17364     */
17365    void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17366        proc.lastPssTime = now;
17367        proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17368        if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17369                + ": " + pss + " lastPss=" + proc.lastPss
17370                + " state=" + ProcessList.makeProcStateString(procState));
17371        if (proc.initialIdlePss == 0) {
17372            proc.initialIdlePss = pss;
17373        }
17374        proc.lastPss = pss;
17375        if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17376            proc.lastCachedPss = pss;
17377        }
17378    }
17379
17380    /**
17381     * Schedule PSS collection of a process.
17382     */
17383    void requestPssLocked(ProcessRecord proc, int procState) {
17384        if (mPendingPssProcesses.contains(proc)) {
17385            return;
17386        }
17387        if (mPendingPssProcesses.size() == 0) {
17388            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17389        }
17390        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17391        proc.pssProcState = procState;
17392        mPendingPssProcesses.add(proc);
17393    }
17394
17395    /**
17396     * Schedule PSS collection of all processes.
17397     */
17398    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17399        if (!always) {
17400            if (now < (mLastFullPssTime +
17401                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17402                return;
17403            }
17404        }
17405        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17406        mLastFullPssTime = now;
17407        mFullPssPending = true;
17408        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17409        mPendingPssProcesses.clear();
17410        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17411            ProcessRecord app = mLruProcesses.get(i);
17412            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17413                app.pssProcState = app.setProcState;
17414                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17415                        mTestPssMode, isSleeping(), now);
17416                mPendingPssProcesses.add(app);
17417            }
17418        }
17419        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17420    }
17421
17422    public void setTestPssMode(boolean enabled) {
17423        synchronized (this) {
17424            mTestPssMode = enabled;
17425            if (enabled) {
17426                // Whenever we enable the mode, we want to take a snapshot all of current
17427                // process mem use.
17428                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17429            }
17430        }
17431    }
17432
17433    /**
17434     * Ask a given process to GC right now.
17435     */
17436    final void performAppGcLocked(ProcessRecord app) {
17437        try {
17438            app.lastRequestedGc = SystemClock.uptimeMillis();
17439            if (app.thread != null) {
17440                if (app.reportLowMemory) {
17441                    app.reportLowMemory = false;
17442                    app.thread.scheduleLowMemory();
17443                } else {
17444                    app.thread.processInBackground();
17445                }
17446            }
17447        } catch (Exception e) {
17448            // whatever.
17449        }
17450    }
17451
17452    /**
17453     * Returns true if things are idle enough to perform GCs.
17454     */
17455    private final boolean canGcNowLocked() {
17456        boolean processingBroadcasts = false;
17457        for (BroadcastQueue q : mBroadcastQueues) {
17458            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17459                processingBroadcasts = true;
17460            }
17461        }
17462        return !processingBroadcasts
17463                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17464    }
17465
17466    /**
17467     * Perform GCs on all processes that are waiting for it, but only
17468     * if things are idle.
17469     */
17470    final void performAppGcsLocked() {
17471        final int N = mProcessesToGc.size();
17472        if (N <= 0) {
17473            return;
17474        }
17475        if (canGcNowLocked()) {
17476            while (mProcessesToGc.size() > 0) {
17477                ProcessRecord proc = mProcessesToGc.remove(0);
17478                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17479                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17480                            <= SystemClock.uptimeMillis()) {
17481                        // To avoid spamming the system, we will GC processes one
17482                        // at a time, waiting a few seconds between each.
17483                        performAppGcLocked(proc);
17484                        scheduleAppGcsLocked();
17485                        return;
17486                    } else {
17487                        // It hasn't been long enough since we last GCed this
17488                        // process...  put it in the list to wait for its time.
17489                        addProcessToGcListLocked(proc);
17490                        break;
17491                    }
17492                }
17493            }
17494
17495            scheduleAppGcsLocked();
17496        }
17497    }
17498
17499    /**
17500     * If all looks good, perform GCs on all processes waiting for them.
17501     */
17502    final void performAppGcsIfAppropriateLocked() {
17503        if (canGcNowLocked()) {
17504            performAppGcsLocked();
17505            return;
17506        }
17507        // Still not idle, wait some more.
17508        scheduleAppGcsLocked();
17509    }
17510
17511    /**
17512     * Schedule the execution of all pending app GCs.
17513     */
17514    final void scheduleAppGcsLocked() {
17515        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17516
17517        if (mProcessesToGc.size() > 0) {
17518            // Schedule a GC for the time to the next process.
17519            ProcessRecord proc = mProcessesToGc.get(0);
17520            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17521
17522            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17523            long now = SystemClock.uptimeMillis();
17524            if (when < (now+GC_TIMEOUT)) {
17525                when = now + GC_TIMEOUT;
17526            }
17527            mHandler.sendMessageAtTime(msg, when);
17528        }
17529    }
17530
17531    /**
17532     * Add a process to the array of processes waiting to be GCed.  Keeps the
17533     * list in sorted order by the last GC time.  The process can't already be
17534     * on the list.
17535     */
17536    final void addProcessToGcListLocked(ProcessRecord proc) {
17537        boolean added = false;
17538        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17539            if (mProcessesToGc.get(i).lastRequestedGc <
17540                    proc.lastRequestedGc) {
17541                added = true;
17542                mProcessesToGc.add(i+1, proc);
17543                break;
17544            }
17545        }
17546        if (!added) {
17547            mProcessesToGc.add(0, proc);
17548        }
17549    }
17550
17551    /**
17552     * Set up to ask a process to GC itself.  This will either do it
17553     * immediately, or put it on the list of processes to gc the next
17554     * time things are idle.
17555     */
17556    final void scheduleAppGcLocked(ProcessRecord app) {
17557        long now = SystemClock.uptimeMillis();
17558        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17559            return;
17560        }
17561        if (!mProcessesToGc.contains(app)) {
17562            addProcessToGcListLocked(app);
17563            scheduleAppGcsLocked();
17564        }
17565    }
17566
17567    final void checkExcessivePowerUsageLocked(boolean doKills) {
17568        updateCpuStatsNow();
17569
17570        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17571        boolean doWakeKills = doKills;
17572        boolean doCpuKills = doKills;
17573        if (mLastPowerCheckRealtime == 0) {
17574            doWakeKills = false;
17575        }
17576        if (mLastPowerCheckUptime == 0) {
17577            doCpuKills = false;
17578        }
17579        if (stats.isScreenOn()) {
17580            doWakeKills = false;
17581        }
17582        final long curRealtime = SystemClock.elapsedRealtime();
17583        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17584        final long curUptime = SystemClock.uptimeMillis();
17585        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17586        mLastPowerCheckRealtime = curRealtime;
17587        mLastPowerCheckUptime = curUptime;
17588        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17589            doWakeKills = false;
17590        }
17591        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17592            doCpuKills = false;
17593        }
17594        int i = mLruProcesses.size();
17595        while (i > 0) {
17596            i--;
17597            ProcessRecord app = mLruProcesses.get(i);
17598            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17599                long wtime;
17600                synchronized (stats) {
17601                    wtime = stats.getProcessWakeTime(app.info.uid,
17602                            app.pid, curRealtime);
17603                }
17604                long wtimeUsed = wtime - app.lastWakeTime;
17605                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17606                if (DEBUG_POWER) {
17607                    StringBuilder sb = new StringBuilder(128);
17608                    sb.append("Wake for ");
17609                    app.toShortString(sb);
17610                    sb.append(": over ");
17611                    TimeUtils.formatDuration(realtimeSince, sb);
17612                    sb.append(" used ");
17613                    TimeUtils.formatDuration(wtimeUsed, sb);
17614                    sb.append(" (");
17615                    sb.append((wtimeUsed*100)/realtimeSince);
17616                    sb.append("%)");
17617                    Slog.i(TAG, sb.toString());
17618                    sb.setLength(0);
17619                    sb.append("CPU for ");
17620                    app.toShortString(sb);
17621                    sb.append(": over ");
17622                    TimeUtils.formatDuration(uptimeSince, sb);
17623                    sb.append(" used ");
17624                    TimeUtils.formatDuration(cputimeUsed, sb);
17625                    sb.append(" (");
17626                    sb.append((cputimeUsed*100)/uptimeSince);
17627                    sb.append("%)");
17628                    Slog.i(TAG, sb.toString());
17629                }
17630                // If a process has held a wake lock for more
17631                // than 50% of the time during this period,
17632                // that sounds bad.  Kill!
17633                if (doWakeKills && realtimeSince > 0
17634                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17635                    synchronized (stats) {
17636                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17637                                realtimeSince, wtimeUsed);
17638                    }
17639                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17640                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17641                } else if (doCpuKills && uptimeSince > 0
17642                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17643                    synchronized (stats) {
17644                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17645                                uptimeSince, cputimeUsed);
17646                    }
17647                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17648                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17649                } else {
17650                    app.lastWakeTime = wtime;
17651                    app.lastCpuTime = app.curCpuTime;
17652                }
17653            }
17654        }
17655    }
17656
17657    private final boolean applyOomAdjLocked(ProcessRecord app,
17658            ProcessRecord TOP_APP, boolean doingAll, long now) {
17659        boolean success = true;
17660
17661        if (app.curRawAdj != app.setRawAdj) {
17662            app.setRawAdj = app.curRawAdj;
17663        }
17664
17665        int changes = 0;
17666
17667        if (app.curAdj != app.setAdj) {
17668            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17669            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17670                TAG, "Set " + app.pid + " " + app.processName +
17671                " adj " + app.curAdj + ": " + app.adjType);
17672            app.setAdj = app.curAdj;
17673        }
17674
17675        if (app.setSchedGroup != app.curSchedGroup) {
17676            app.setSchedGroup = app.curSchedGroup;
17677            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17678                    "Setting process group of " + app.processName
17679                    + " to " + app.curSchedGroup);
17680            if (app.waitingToKill != null &&
17681                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17682                app.kill(app.waitingToKill, true);
17683                success = false;
17684            } else {
17685                if (true) {
17686                    long oldId = Binder.clearCallingIdentity();
17687                    try {
17688                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17689                    } catch (Exception e) {
17690                        Slog.w(TAG, "Failed setting process group of " + app.pid
17691                                + " to " + app.curSchedGroup);
17692                        e.printStackTrace();
17693                    } finally {
17694                        Binder.restoreCallingIdentity(oldId);
17695                    }
17696                } else {
17697                    if (app.thread != null) {
17698                        try {
17699                            app.thread.setSchedulingGroup(app.curSchedGroup);
17700                        } catch (RemoteException e) {
17701                        }
17702                    }
17703                }
17704                Process.setSwappiness(app.pid,
17705                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17706            }
17707        }
17708        if (app.repForegroundActivities != app.foregroundActivities) {
17709            app.repForegroundActivities = app.foregroundActivities;
17710            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17711        }
17712        if (app.repProcState != app.curProcState) {
17713            app.repProcState = app.curProcState;
17714            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17715            if (app.thread != null) {
17716                try {
17717                    if (false) {
17718                        //RuntimeException h = new RuntimeException("here");
17719                        Slog.i(TAG, "Sending new process state " + app.repProcState
17720                                + " to " + app /*, h*/);
17721                    }
17722                    app.thread.setProcessState(app.repProcState);
17723                } catch (RemoteException e) {
17724                }
17725            }
17726        }
17727        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17728                app.setProcState)) {
17729            if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
17730                // Experimental code to more aggressively collect pss while
17731                // running test...  the problem is that this tends to collect
17732                // the data right when a process is transitioning between process
17733                // states, which well tend to give noisy data.
17734                long start = SystemClock.uptimeMillis();
17735                long pss = Debug.getPss(app.pid, mTmpLong, null);
17736                recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
17737                mPendingPssProcesses.remove(app);
17738                Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
17739                        + " to " + app.curProcState + ": "
17740                        + (SystemClock.uptimeMillis()-start) + "ms");
17741            }
17742            app.lastStateTime = now;
17743            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17744                    mTestPssMode, isSleeping(), now);
17745            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17746                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17747                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17748                    + (app.nextPssTime-now) + ": " + app);
17749        } else {
17750            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17751                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17752                requestPssLocked(app, app.setProcState);
17753                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17754                        mTestPssMode, isSleeping(), now);
17755            } else if (false && DEBUG_PSS) {
17756                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17757            }
17758        }
17759        if (app.setProcState != app.curProcState) {
17760            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17761                    "Proc state change of " + app.processName
17762                    + " to " + app.curProcState);
17763            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17764            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17765            if (setImportant && !curImportant) {
17766                // This app is no longer something we consider important enough to allow to
17767                // use arbitrary amounts of battery power.  Note
17768                // its current wake lock time to later know to kill it if
17769                // it is not behaving well.
17770                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17771                synchronized (stats) {
17772                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17773                            app.pid, SystemClock.elapsedRealtime());
17774                }
17775                app.lastCpuTime = app.curCpuTime;
17776
17777            }
17778            app.setProcState = app.curProcState;
17779            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17780                app.notCachedSinceIdle = false;
17781            }
17782            if (!doingAll) {
17783                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17784            } else {
17785                app.procStateChanged = true;
17786            }
17787        }
17788
17789        if (changes != 0) {
17790            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17791            int i = mPendingProcessChanges.size()-1;
17792            ProcessChangeItem item = null;
17793            while (i >= 0) {
17794                item = mPendingProcessChanges.get(i);
17795                if (item.pid == app.pid) {
17796                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17797                    break;
17798                }
17799                i--;
17800            }
17801            if (i < 0) {
17802                // No existing item in pending changes; need a new one.
17803                final int NA = mAvailProcessChanges.size();
17804                if (NA > 0) {
17805                    item = mAvailProcessChanges.remove(NA-1);
17806                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17807                } else {
17808                    item = new ProcessChangeItem();
17809                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17810                }
17811                item.changes = 0;
17812                item.pid = app.pid;
17813                item.uid = app.info.uid;
17814                if (mPendingProcessChanges.size() == 0) {
17815                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17816                            "*** Enqueueing dispatch processes changed!");
17817                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17818                }
17819                mPendingProcessChanges.add(item);
17820            }
17821            item.changes |= changes;
17822            item.processState = app.repProcState;
17823            item.foregroundActivities = app.repForegroundActivities;
17824            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17825                    + Integer.toHexString(System.identityHashCode(item))
17826                    + " " + app.toShortString() + ": changes=" + item.changes
17827                    + " procState=" + item.processState
17828                    + " foreground=" + item.foregroundActivities
17829                    + " type=" + app.adjType + " source=" + app.adjSource
17830                    + " target=" + app.adjTarget);
17831        }
17832
17833        return success;
17834    }
17835
17836    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17837        if (proc.thread != null) {
17838            if (proc.baseProcessTracker != null) {
17839                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17840            }
17841            if (proc.repProcState >= 0) {
17842                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17843                        proc.repProcState);
17844            }
17845        }
17846    }
17847
17848    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17849            ProcessRecord TOP_APP, boolean doingAll, long now) {
17850        if (app.thread == null) {
17851            return false;
17852        }
17853
17854        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17855
17856        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17857    }
17858
17859    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17860            boolean oomAdj) {
17861        if (isForeground != proc.foregroundServices) {
17862            proc.foregroundServices = isForeground;
17863            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17864                    proc.info.uid);
17865            if (isForeground) {
17866                if (curProcs == null) {
17867                    curProcs = new ArrayList<ProcessRecord>();
17868                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17869                }
17870                if (!curProcs.contains(proc)) {
17871                    curProcs.add(proc);
17872                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17873                            proc.info.packageName, proc.info.uid);
17874                }
17875            } else {
17876                if (curProcs != null) {
17877                    if (curProcs.remove(proc)) {
17878                        mBatteryStatsService.noteEvent(
17879                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17880                                proc.info.packageName, proc.info.uid);
17881                        if (curProcs.size() <= 0) {
17882                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17883                        }
17884                    }
17885                }
17886            }
17887            if (oomAdj) {
17888                updateOomAdjLocked();
17889            }
17890        }
17891    }
17892
17893    private final ActivityRecord resumedAppLocked() {
17894        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17895        String pkg;
17896        int uid;
17897        if (act != null) {
17898            pkg = act.packageName;
17899            uid = act.info.applicationInfo.uid;
17900        } else {
17901            pkg = null;
17902            uid = -1;
17903        }
17904        // Has the UID or resumed package name changed?
17905        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17906                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17907            if (mCurResumedPackage != null) {
17908                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17909                        mCurResumedPackage, mCurResumedUid);
17910            }
17911            mCurResumedPackage = pkg;
17912            mCurResumedUid = uid;
17913            if (mCurResumedPackage != null) {
17914                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17915                        mCurResumedPackage, mCurResumedUid);
17916            }
17917        }
17918        return act;
17919    }
17920
17921    final boolean updateOomAdjLocked(ProcessRecord app) {
17922        final ActivityRecord TOP_ACT = resumedAppLocked();
17923        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17924        final boolean wasCached = app.cached;
17925
17926        mAdjSeq++;
17927
17928        // This is the desired cached adjusment we want to tell it to use.
17929        // If our app is currently cached, we know it, and that is it.  Otherwise,
17930        // we don't know it yet, and it needs to now be cached we will then
17931        // need to do a complete oom adj.
17932        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17933                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17934        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17935                SystemClock.uptimeMillis());
17936        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17937            // Changed to/from cached state, so apps after it in the LRU
17938            // list may also be changed.
17939            updateOomAdjLocked();
17940        }
17941        return success;
17942    }
17943
17944    final void updateOomAdjLocked() {
17945        final ActivityRecord TOP_ACT = resumedAppLocked();
17946        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17947        final long now = SystemClock.uptimeMillis();
17948        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17949        final int N = mLruProcesses.size();
17950
17951        if (false) {
17952            RuntimeException e = new RuntimeException();
17953            e.fillInStackTrace();
17954            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17955        }
17956
17957        mAdjSeq++;
17958        mNewNumServiceProcs = 0;
17959        mNewNumAServiceProcs = 0;
17960
17961        final int emptyProcessLimit;
17962        final int cachedProcessLimit;
17963        if (mProcessLimit <= 0) {
17964            emptyProcessLimit = cachedProcessLimit = 0;
17965        } else if (mProcessLimit == 1) {
17966            emptyProcessLimit = 1;
17967            cachedProcessLimit = 0;
17968        } else {
17969            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17970            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17971        }
17972
17973        // Let's determine how many processes we have running vs.
17974        // how many slots we have for background processes; we may want
17975        // to put multiple processes in a slot of there are enough of
17976        // them.
17977        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17978                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17979        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17980        if (numEmptyProcs > cachedProcessLimit) {
17981            // If there are more empty processes than our limit on cached
17982            // processes, then use the cached process limit for the factor.
17983            // This ensures that the really old empty processes get pushed
17984            // down to the bottom, so if we are running low on memory we will
17985            // have a better chance at keeping around more cached processes
17986            // instead of a gazillion empty processes.
17987            numEmptyProcs = cachedProcessLimit;
17988        }
17989        int emptyFactor = numEmptyProcs/numSlots;
17990        if (emptyFactor < 1) emptyFactor = 1;
17991        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17992        if (cachedFactor < 1) cachedFactor = 1;
17993        int stepCached = 0;
17994        int stepEmpty = 0;
17995        int numCached = 0;
17996        int numEmpty = 0;
17997        int numTrimming = 0;
17998
17999        mNumNonCachedProcs = 0;
18000        mNumCachedHiddenProcs = 0;
18001
18002        // First update the OOM adjustment for each of the
18003        // application processes based on their current state.
18004        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18005        int nextCachedAdj = curCachedAdj+1;
18006        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18007        int nextEmptyAdj = curEmptyAdj+2;
18008        for (int i=N-1; i>=0; i--) {
18009            ProcessRecord app = mLruProcesses.get(i);
18010            if (!app.killedByAm && app.thread != null) {
18011                app.procStateChanged = false;
18012                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18013
18014                // If we haven't yet assigned the final cached adj
18015                // to the process, do that now.
18016                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18017                    switch (app.curProcState) {
18018                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18019                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18020                            // This process is a cached process holding activities...
18021                            // assign it the next cached value for that type, and then
18022                            // step that cached level.
18023                            app.curRawAdj = curCachedAdj;
18024                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18025                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18026                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18027                                    + ")");
18028                            if (curCachedAdj != nextCachedAdj) {
18029                                stepCached++;
18030                                if (stepCached >= cachedFactor) {
18031                                    stepCached = 0;
18032                                    curCachedAdj = nextCachedAdj;
18033                                    nextCachedAdj += 2;
18034                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18035                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18036                                    }
18037                                }
18038                            }
18039                            break;
18040                        default:
18041                            // For everything else, assign next empty cached process
18042                            // level and bump that up.  Note that this means that
18043                            // long-running services that have dropped down to the
18044                            // cached level will be treated as empty (since their process
18045                            // state is still as a service), which is what we want.
18046                            app.curRawAdj = curEmptyAdj;
18047                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18048                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18049                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18050                                    + ")");
18051                            if (curEmptyAdj != nextEmptyAdj) {
18052                                stepEmpty++;
18053                                if (stepEmpty >= emptyFactor) {
18054                                    stepEmpty = 0;
18055                                    curEmptyAdj = nextEmptyAdj;
18056                                    nextEmptyAdj += 2;
18057                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18058                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18059                                    }
18060                                }
18061                            }
18062                            break;
18063                    }
18064                }
18065
18066                applyOomAdjLocked(app, TOP_APP, true, now);
18067
18068                // Count the number of process types.
18069                switch (app.curProcState) {
18070                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18071                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18072                        mNumCachedHiddenProcs++;
18073                        numCached++;
18074                        if (numCached > cachedProcessLimit) {
18075                            app.kill("cached #" + numCached, true);
18076                        }
18077                        break;
18078                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18079                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18080                                && app.lastActivityTime < oldTime) {
18081                            app.kill("empty for "
18082                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18083                                    / 1000) + "s", true);
18084                        } else {
18085                            numEmpty++;
18086                            if (numEmpty > emptyProcessLimit) {
18087                                app.kill("empty #" + numEmpty, true);
18088                            }
18089                        }
18090                        break;
18091                    default:
18092                        mNumNonCachedProcs++;
18093                        break;
18094                }
18095
18096                if (app.isolated && app.services.size() <= 0) {
18097                    // If this is an isolated process, and there are no
18098                    // services running in it, then the process is no longer
18099                    // needed.  We agressively kill these because we can by
18100                    // definition not re-use the same process again, and it is
18101                    // good to avoid having whatever code was running in them
18102                    // left sitting around after no longer needed.
18103                    app.kill("isolated not needed", true);
18104                }
18105
18106                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18107                        && !app.killedByAm) {
18108                    numTrimming++;
18109                }
18110            }
18111        }
18112
18113        mNumServiceProcs = mNewNumServiceProcs;
18114
18115        // Now determine the memory trimming level of background processes.
18116        // Unfortunately we need to start at the back of the list to do this
18117        // properly.  We only do this if the number of background apps we
18118        // are managing to keep around is less than half the maximum we desire;
18119        // if we are keeping a good number around, we'll let them use whatever
18120        // memory they want.
18121        final int numCachedAndEmpty = numCached + numEmpty;
18122        int memFactor;
18123        if (numCached <= ProcessList.TRIM_CACHED_APPS
18124                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18125            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18126                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18127            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18128                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18129            } else {
18130                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18131            }
18132        } else {
18133            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18134        }
18135        // We always allow the memory level to go up (better).  We only allow it to go
18136        // down if we are in a state where that is allowed, *and* the total number of processes
18137        // has gone down since last time.
18138        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18139                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18140                + " last=" + mLastNumProcesses);
18141        if (memFactor > mLastMemoryLevel) {
18142            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18143                memFactor = mLastMemoryLevel;
18144                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18145            }
18146        }
18147        mLastMemoryLevel = memFactor;
18148        mLastNumProcesses = mLruProcesses.size();
18149        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18150        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18151        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18152            if (mLowRamStartTime == 0) {
18153                mLowRamStartTime = now;
18154            }
18155            int step = 0;
18156            int fgTrimLevel;
18157            switch (memFactor) {
18158                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18159                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18160                    break;
18161                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18162                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18163                    break;
18164                default:
18165                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18166                    break;
18167            }
18168            int factor = numTrimming/3;
18169            int minFactor = 2;
18170            if (mHomeProcess != null) minFactor++;
18171            if (mPreviousProcess != null) minFactor++;
18172            if (factor < minFactor) factor = minFactor;
18173            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18174            for (int i=N-1; i>=0; i--) {
18175                ProcessRecord app = mLruProcesses.get(i);
18176                if (allChanged || app.procStateChanged) {
18177                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18178                    app.procStateChanged = false;
18179                }
18180                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18181                        && !app.killedByAm) {
18182                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18183                        try {
18184                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18185                                    "Trimming memory of " + app.processName
18186                                    + " to " + curLevel);
18187                            app.thread.scheduleTrimMemory(curLevel);
18188                        } catch (RemoteException e) {
18189                        }
18190                        if (false) {
18191                            // For now we won't do this; our memory trimming seems
18192                            // to be good enough at this point that destroying
18193                            // activities causes more harm than good.
18194                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18195                                    && app != mHomeProcess && app != mPreviousProcess) {
18196                                // Need to do this on its own message because the stack may not
18197                                // be in a consistent state at this point.
18198                                // For these apps we will also finish their activities
18199                                // to help them free memory.
18200                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18201                            }
18202                        }
18203                    }
18204                    app.trimMemoryLevel = curLevel;
18205                    step++;
18206                    if (step >= factor) {
18207                        step = 0;
18208                        switch (curLevel) {
18209                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18210                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18211                                break;
18212                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18213                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18214                                break;
18215                        }
18216                    }
18217                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18218                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18219                            && app.thread != null) {
18220                        try {
18221                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18222                                    "Trimming memory of heavy-weight " + app.processName
18223                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18224                            app.thread.scheduleTrimMemory(
18225                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18226                        } catch (RemoteException e) {
18227                        }
18228                    }
18229                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18230                } else {
18231                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18232                            || app.systemNoUi) && app.pendingUiClean) {
18233                        // If this application is now in the background and it
18234                        // had done UI, then give it the special trim level to
18235                        // have it free UI resources.
18236                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18237                        if (app.trimMemoryLevel < level && app.thread != null) {
18238                            try {
18239                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18240                                        "Trimming memory of bg-ui " + app.processName
18241                                        + " to " + level);
18242                                app.thread.scheduleTrimMemory(level);
18243                            } catch (RemoteException e) {
18244                            }
18245                        }
18246                        app.pendingUiClean = false;
18247                    }
18248                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18249                        try {
18250                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18251                                    "Trimming memory of fg " + app.processName
18252                                    + " to " + fgTrimLevel);
18253                            app.thread.scheduleTrimMemory(fgTrimLevel);
18254                        } catch (RemoteException e) {
18255                        }
18256                    }
18257                    app.trimMemoryLevel = fgTrimLevel;
18258                }
18259            }
18260        } else {
18261            if (mLowRamStartTime != 0) {
18262                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18263                mLowRamStartTime = 0;
18264            }
18265            for (int i=N-1; i>=0; i--) {
18266                ProcessRecord app = mLruProcesses.get(i);
18267                if (allChanged || app.procStateChanged) {
18268                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18269                    app.procStateChanged = false;
18270                }
18271                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18272                        || app.systemNoUi) && app.pendingUiClean) {
18273                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18274                            && app.thread != null) {
18275                        try {
18276                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18277                                    "Trimming memory of ui hidden " + app.processName
18278                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18279                            app.thread.scheduleTrimMemory(
18280                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18281                        } catch (RemoteException e) {
18282                        }
18283                    }
18284                    app.pendingUiClean = false;
18285                }
18286                app.trimMemoryLevel = 0;
18287            }
18288        }
18289
18290        if (mAlwaysFinishActivities) {
18291            // Need to do this on its own message because the stack may not
18292            // be in a consistent state at this point.
18293            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18294        }
18295
18296        if (allChanged) {
18297            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18298        }
18299
18300        if (mProcessStats.shouldWriteNowLocked(now)) {
18301            mHandler.post(new Runnable() {
18302                @Override public void run() {
18303                    synchronized (ActivityManagerService.this) {
18304                        mProcessStats.writeStateAsyncLocked();
18305                    }
18306                }
18307            });
18308        }
18309
18310        if (DEBUG_OOM_ADJ) {
18311            if (false) {
18312                RuntimeException here = new RuntimeException("here");
18313                here.fillInStackTrace();
18314                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18315            } else {
18316                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18317            }
18318        }
18319    }
18320
18321    final void trimApplications() {
18322        synchronized (this) {
18323            int i;
18324
18325            // First remove any unused application processes whose package
18326            // has been removed.
18327            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18328                final ProcessRecord app = mRemovedProcesses.get(i);
18329                if (app.activities.size() == 0
18330                        && app.curReceiver == null && app.services.size() == 0) {
18331                    Slog.i(
18332                        TAG, "Exiting empty application process "
18333                        + app.processName + " ("
18334                        + (app.thread != null ? app.thread.asBinder() : null)
18335                        + ")\n");
18336                    if (app.pid > 0 && app.pid != MY_PID) {
18337                        app.kill("empty", false);
18338                    } else {
18339                        try {
18340                            app.thread.scheduleExit();
18341                        } catch (Exception e) {
18342                            // Ignore exceptions.
18343                        }
18344                    }
18345                    cleanUpApplicationRecordLocked(app, false, true, -1);
18346                    mRemovedProcesses.remove(i);
18347
18348                    if (app.persistent) {
18349                        addAppLocked(app.info, false, null /* ABI override */);
18350                    }
18351                }
18352            }
18353
18354            // Now update the oom adj for all processes.
18355            updateOomAdjLocked();
18356        }
18357    }
18358
18359    /** This method sends the specified signal to each of the persistent apps */
18360    public void signalPersistentProcesses(int sig) throws RemoteException {
18361        if (sig != Process.SIGNAL_USR1) {
18362            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18363        }
18364
18365        synchronized (this) {
18366            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18367                    != PackageManager.PERMISSION_GRANTED) {
18368                throw new SecurityException("Requires permission "
18369                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18370            }
18371
18372            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18373                ProcessRecord r = mLruProcesses.get(i);
18374                if (r.thread != null && r.persistent) {
18375                    Process.sendSignal(r.pid, sig);
18376                }
18377            }
18378        }
18379    }
18380
18381    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18382        if (proc == null || proc == mProfileProc) {
18383            proc = mProfileProc;
18384            profileType = mProfileType;
18385            clearProfilerLocked();
18386        }
18387        if (proc == null) {
18388            return;
18389        }
18390        try {
18391            proc.thread.profilerControl(false, null, profileType);
18392        } catch (RemoteException e) {
18393            throw new IllegalStateException("Process disappeared");
18394        }
18395    }
18396
18397    private void clearProfilerLocked() {
18398        if (mProfileFd != null) {
18399            try {
18400                mProfileFd.close();
18401            } catch (IOException e) {
18402            }
18403        }
18404        mProfileApp = null;
18405        mProfileProc = null;
18406        mProfileFile = null;
18407        mProfileType = 0;
18408        mAutoStopProfiler = false;
18409        mSamplingInterval = 0;
18410    }
18411
18412    public boolean profileControl(String process, int userId, boolean start,
18413            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18414
18415        try {
18416            synchronized (this) {
18417                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18418                // its own permission.
18419                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18420                        != PackageManager.PERMISSION_GRANTED) {
18421                    throw new SecurityException("Requires permission "
18422                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18423                }
18424
18425                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18426                    throw new IllegalArgumentException("null profile info or fd");
18427                }
18428
18429                ProcessRecord proc = null;
18430                if (process != null) {
18431                    proc = findProcessLocked(process, userId, "profileControl");
18432                }
18433
18434                if (start && (proc == null || proc.thread == null)) {
18435                    throw new IllegalArgumentException("Unknown process: " + process);
18436                }
18437
18438                if (start) {
18439                    stopProfilerLocked(null, 0);
18440                    setProfileApp(proc.info, proc.processName, profilerInfo);
18441                    mProfileProc = proc;
18442                    mProfileType = profileType;
18443                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18444                    try {
18445                        fd = fd.dup();
18446                    } catch (IOException e) {
18447                        fd = null;
18448                    }
18449                    profilerInfo.profileFd = fd;
18450                    proc.thread.profilerControl(start, profilerInfo, profileType);
18451                    fd = null;
18452                    mProfileFd = null;
18453                } else {
18454                    stopProfilerLocked(proc, profileType);
18455                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18456                        try {
18457                            profilerInfo.profileFd.close();
18458                        } catch (IOException e) {
18459                        }
18460                    }
18461                }
18462
18463                return true;
18464            }
18465        } catch (RemoteException e) {
18466            throw new IllegalStateException("Process disappeared");
18467        } finally {
18468            if (profilerInfo != null && profilerInfo.profileFd != null) {
18469                try {
18470                    profilerInfo.profileFd.close();
18471                } catch (IOException e) {
18472                }
18473            }
18474        }
18475    }
18476
18477    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18478        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18479                userId, true, ALLOW_FULL_ONLY, callName, null);
18480        ProcessRecord proc = null;
18481        try {
18482            int pid = Integer.parseInt(process);
18483            synchronized (mPidsSelfLocked) {
18484                proc = mPidsSelfLocked.get(pid);
18485            }
18486        } catch (NumberFormatException e) {
18487        }
18488
18489        if (proc == null) {
18490            ArrayMap<String, SparseArray<ProcessRecord>> all
18491                    = mProcessNames.getMap();
18492            SparseArray<ProcessRecord> procs = all.get(process);
18493            if (procs != null && procs.size() > 0) {
18494                proc = procs.valueAt(0);
18495                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18496                    for (int i=1; i<procs.size(); i++) {
18497                        ProcessRecord thisProc = procs.valueAt(i);
18498                        if (thisProc.userId == userId) {
18499                            proc = thisProc;
18500                            break;
18501                        }
18502                    }
18503                }
18504            }
18505        }
18506
18507        return proc;
18508    }
18509
18510    public boolean dumpHeap(String process, int userId, boolean managed,
18511            String path, ParcelFileDescriptor fd) throws RemoteException {
18512
18513        try {
18514            synchronized (this) {
18515                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18516                // its own permission (same as profileControl).
18517                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18518                        != PackageManager.PERMISSION_GRANTED) {
18519                    throw new SecurityException("Requires permission "
18520                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18521                }
18522
18523                if (fd == null) {
18524                    throw new IllegalArgumentException("null fd");
18525                }
18526
18527                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18528                if (proc == null || proc.thread == null) {
18529                    throw new IllegalArgumentException("Unknown process: " + process);
18530                }
18531
18532                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18533                if (!isDebuggable) {
18534                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18535                        throw new SecurityException("Process not debuggable: " + proc);
18536                    }
18537                }
18538
18539                proc.thread.dumpHeap(managed, path, fd);
18540                fd = null;
18541                return true;
18542            }
18543        } catch (RemoteException e) {
18544            throw new IllegalStateException("Process disappeared");
18545        } finally {
18546            if (fd != null) {
18547                try {
18548                    fd.close();
18549                } catch (IOException e) {
18550                }
18551            }
18552        }
18553    }
18554
18555    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18556    public void monitor() {
18557        synchronized (this) { }
18558    }
18559
18560    void onCoreSettingsChange(Bundle settings) {
18561        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18562            ProcessRecord processRecord = mLruProcesses.get(i);
18563            try {
18564                if (processRecord.thread != null) {
18565                    processRecord.thread.setCoreSettings(settings);
18566                }
18567            } catch (RemoteException re) {
18568                /* ignore */
18569            }
18570        }
18571    }
18572
18573    // Multi-user methods
18574
18575    /**
18576     * Start user, if its not already running, but don't bring it to foreground.
18577     */
18578    @Override
18579    public boolean startUserInBackground(final int userId) {
18580        return startUser(userId, /* foreground */ false);
18581    }
18582
18583    /**
18584     * Start user, if its not already running, and bring it to foreground.
18585     */
18586    boolean startUserInForeground(final int userId, Dialog dlg) {
18587        boolean result = startUser(userId, /* foreground */ true);
18588        dlg.dismiss();
18589        return result;
18590    }
18591
18592    /**
18593     * Refreshes the list of users related to the current user when either a
18594     * user switch happens or when a new related user is started in the
18595     * background.
18596     */
18597    private void updateCurrentProfileIdsLocked() {
18598        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18599                mCurrentUserId, false /* enabledOnly */);
18600        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18601        for (int i = 0; i < currentProfileIds.length; i++) {
18602            currentProfileIds[i] = profiles.get(i).id;
18603        }
18604        mCurrentProfileIds = currentProfileIds;
18605
18606        synchronized (mUserProfileGroupIdsSelfLocked) {
18607            mUserProfileGroupIdsSelfLocked.clear();
18608            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18609            for (int i = 0; i < users.size(); i++) {
18610                UserInfo user = users.get(i);
18611                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18612                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18613                }
18614            }
18615        }
18616    }
18617
18618    private Set getProfileIdsLocked(int userId) {
18619        Set userIds = new HashSet<Integer>();
18620        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18621                userId, false /* enabledOnly */);
18622        for (UserInfo user : profiles) {
18623            userIds.add(Integer.valueOf(user.id));
18624        }
18625        return userIds;
18626    }
18627
18628    @Override
18629    public boolean switchUser(final int userId) {
18630        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18631        String userName;
18632        synchronized (this) {
18633            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18634            if (userInfo == null) {
18635                Slog.w(TAG, "No user info for user #" + userId);
18636                return false;
18637            }
18638            if (userInfo.isManagedProfile()) {
18639                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18640                return false;
18641            }
18642            userName = userInfo.name;
18643            mTargetUserId = userId;
18644        }
18645        mHandler.removeMessages(START_USER_SWITCH_MSG);
18646        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18647        return true;
18648    }
18649
18650    private void showUserSwitchDialog(int userId, String userName) {
18651        // The dialog will show and then initiate the user switch by calling startUserInForeground
18652        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18653                true /* above system */);
18654        d.show();
18655    }
18656
18657    private boolean startUser(final int userId, final boolean foreground) {
18658        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18659                != PackageManager.PERMISSION_GRANTED) {
18660            String msg = "Permission Denial: switchUser() from pid="
18661                    + Binder.getCallingPid()
18662                    + ", uid=" + Binder.getCallingUid()
18663                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18664            Slog.w(TAG, msg);
18665            throw new SecurityException(msg);
18666        }
18667
18668        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18669
18670        final long ident = Binder.clearCallingIdentity();
18671        try {
18672            synchronized (this) {
18673                final int oldUserId = mCurrentUserId;
18674                if (oldUserId == userId) {
18675                    return true;
18676                }
18677
18678                mStackSupervisor.setLockTaskModeLocked(null, false);
18679
18680                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18681                if (userInfo == null) {
18682                    Slog.w(TAG, "No user info for user #" + userId);
18683                    return false;
18684                }
18685                if (foreground && userInfo.isManagedProfile()) {
18686                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18687                    return false;
18688                }
18689
18690                if (foreground) {
18691                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18692                            R.anim.screen_user_enter);
18693                }
18694
18695                boolean needStart = false;
18696
18697                // If the user we are switching to is not currently started, then
18698                // we need to start it now.
18699                if (mStartedUsers.get(userId) == null) {
18700                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18701                    updateStartedUserArrayLocked();
18702                    needStart = true;
18703                }
18704
18705                final Integer userIdInt = Integer.valueOf(userId);
18706                mUserLru.remove(userIdInt);
18707                mUserLru.add(userIdInt);
18708
18709                if (foreground) {
18710                    mCurrentUserId = userId;
18711                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18712                    updateCurrentProfileIdsLocked();
18713                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18714                    // Once the internal notion of the active user has switched, we lock the device
18715                    // with the option to show the user switcher on the keyguard.
18716                    mWindowManager.lockNow(null);
18717                } else {
18718                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18719                    updateCurrentProfileIdsLocked();
18720                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18721                    mUserLru.remove(currentUserIdInt);
18722                    mUserLru.add(currentUserIdInt);
18723                }
18724
18725                final UserStartedState uss = mStartedUsers.get(userId);
18726
18727                // Make sure user is in the started state.  If it is currently
18728                // stopping, we need to knock that off.
18729                if (uss.mState == UserStartedState.STATE_STOPPING) {
18730                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18731                    // so we can just fairly silently bring the user back from
18732                    // the almost-dead.
18733                    uss.mState = UserStartedState.STATE_RUNNING;
18734                    updateStartedUserArrayLocked();
18735                    needStart = true;
18736                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18737                    // This means ACTION_SHUTDOWN has been sent, so we will
18738                    // need to treat this as a new boot of the user.
18739                    uss.mState = UserStartedState.STATE_BOOTING;
18740                    updateStartedUserArrayLocked();
18741                    needStart = true;
18742                }
18743
18744                if (uss.mState == UserStartedState.STATE_BOOTING) {
18745                    // Booting up a new user, need to tell system services about it.
18746                    // Note that this is on the same handler as scheduling of broadcasts,
18747                    // which is important because it needs to go first.
18748                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18749                }
18750
18751                if (foreground) {
18752                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18753                            oldUserId));
18754                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18755                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18756                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18757                            oldUserId, userId, uss));
18758                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18759                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18760                }
18761
18762                if (needStart) {
18763                    // Send USER_STARTED broadcast
18764                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18765                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18766                            | Intent.FLAG_RECEIVER_FOREGROUND);
18767                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18768                    broadcastIntentLocked(null, null, intent,
18769                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18770                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18771                }
18772
18773                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18774                    if (userId != UserHandle.USER_OWNER) {
18775                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18776                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18777                        broadcastIntentLocked(null, null, intent, null,
18778                                new IIntentReceiver.Stub() {
18779                                    public void performReceive(Intent intent, int resultCode,
18780                                            String data, Bundle extras, boolean ordered,
18781                                            boolean sticky, int sendingUser) {
18782                                        onUserInitialized(uss, foreground, oldUserId, userId);
18783                                    }
18784                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18785                                true, false, MY_PID, Process.SYSTEM_UID,
18786                                userId);
18787                        uss.initializing = true;
18788                    } else {
18789                        getUserManagerLocked().makeInitialized(userInfo.id);
18790                    }
18791                }
18792
18793                if (foreground) {
18794                    if (!uss.initializing) {
18795                        moveUserToForeground(uss, oldUserId, userId);
18796                    }
18797                } else {
18798                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18799                }
18800
18801                if (needStart) {
18802                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18803                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18804                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18805                    broadcastIntentLocked(null, null, intent,
18806                            null, new IIntentReceiver.Stub() {
18807                                @Override
18808                                public void performReceive(Intent intent, int resultCode, String data,
18809                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18810                                        throws RemoteException {
18811                                }
18812                            }, 0, null, null,
18813                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18814                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18815                }
18816            }
18817        } finally {
18818            Binder.restoreCallingIdentity(ident);
18819        }
18820
18821        return true;
18822    }
18823
18824    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18825        long ident = Binder.clearCallingIdentity();
18826        try {
18827            Intent intent;
18828            if (oldUserId >= 0) {
18829                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18830                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18831                int count = profiles.size();
18832                for (int i = 0; i < count; i++) {
18833                    int profileUserId = profiles.get(i).id;
18834                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18835                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18836                            | Intent.FLAG_RECEIVER_FOREGROUND);
18837                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18838                    broadcastIntentLocked(null, null, intent,
18839                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18840                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18841                }
18842            }
18843            if (newUserId >= 0) {
18844                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18845                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18846                int count = profiles.size();
18847                for (int i = 0; i < count; i++) {
18848                    int profileUserId = profiles.get(i).id;
18849                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18850                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18851                            | Intent.FLAG_RECEIVER_FOREGROUND);
18852                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18853                    broadcastIntentLocked(null, null, intent,
18854                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18855                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18856                }
18857                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18858                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18859                        | Intent.FLAG_RECEIVER_FOREGROUND);
18860                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18861                broadcastIntentLocked(null, null, intent,
18862                        null, null, 0, null, null,
18863                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18864                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18865            }
18866        } finally {
18867            Binder.restoreCallingIdentity(ident);
18868        }
18869    }
18870
18871    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18872            final int newUserId) {
18873        final int N = mUserSwitchObservers.beginBroadcast();
18874        if (N > 0) {
18875            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18876                int mCount = 0;
18877                @Override
18878                public void sendResult(Bundle data) throws RemoteException {
18879                    synchronized (ActivityManagerService.this) {
18880                        if (mCurUserSwitchCallback == this) {
18881                            mCount++;
18882                            if (mCount == N) {
18883                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18884                            }
18885                        }
18886                    }
18887                }
18888            };
18889            synchronized (this) {
18890                uss.switching = true;
18891                mCurUserSwitchCallback = callback;
18892            }
18893            for (int i=0; i<N; i++) {
18894                try {
18895                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18896                            newUserId, callback);
18897                } catch (RemoteException e) {
18898                }
18899            }
18900        } else {
18901            synchronized (this) {
18902                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18903            }
18904        }
18905        mUserSwitchObservers.finishBroadcast();
18906    }
18907
18908    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18909        synchronized (this) {
18910            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18911            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18912        }
18913    }
18914
18915    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18916        mCurUserSwitchCallback = null;
18917        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18918        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18919                oldUserId, newUserId, uss));
18920    }
18921
18922    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18923        synchronized (this) {
18924            if (foreground) {
18925                moveUserToForeground(uss, oldUserId, newUserId);
18926            }
18927        }
18928
18929        completeSwitchAndInitalize(uss, newUserId, true, false);
18930    }
18931
18932    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18933        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18934        if (homeInFront) {
18935            startHomeActivityLocked(newUserId);
18936        } else {
18937            mStackSupervisor.resumeTopActivitiesLocked();
18938        }
18939        EventLogTags.writeAmSwitchUser(newUserId);
18940        getUserManagerLocked().userForeground(newUserId);
18941        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18942    }
18943
18944    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18945        completeSwitchAndInitalize(uss, newUserId, false, true);
18946    }
18947
18948    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18949            boolean clearInitializing, boolean clearSwitching) {
18950        boolean unfrozen = false;
18951        synchronized (this) {
18952            if (clearInitializing) {
18953                uss.initializing = false;
18954                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18955            }
18956            if (clearSwitching) {
18957                uss.switching = false;
18958            }
18959            if (!uss.switching && !uss.initializing) {
18960                mWindowManager.stopFreezingScreen();
18961                unfrozen = true;
18962            }
18963        }
18964        if (unfrozen) {
18965            final int N = mUserSwitchObservers.beginBroadcast();
18966            for (int i=0; i<N; i++) {
18967                try {
18968                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18969                } catch (RemoteException e) {
18970                }
18971            }
18972            mUserSwitchObservers.finishBroadcast();
18973        }
18974    }
18975
18976    void scheduleStartProfilesLocked() {
18977        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18978            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18979                    DateUtils.SECOND_IN_MILLIS);
18980        }
18981    }
18982
18983    void startProfilesLocked() {
18984        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18985        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18986                mCurrentUserId, false /* enabledOnly */);
18987        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18988        for (UserInfo user : profiles) {
18989            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18990                    && user.id != mCurrentUserId) {
18991                toStart.add(user);
18992            }
18993        }
18994        final int n = toStart.size();
18995        int i = 0;
18996        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18997            startUserInBackground(toStart.get(i).id);
18998        }
18999        if (i < n) {
19000            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19001        }
19002    }
19003
19004    void finishUserBoot(UserStartedState uss) {
19005        synchronized (this) {
19006            if (uss.mState == UserStartedState.STATE_BOOTING
19007                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19008                uss.mState = UserStartedState.STATE_RUNNING;
19009                final int userId = uss.mHandle.getIdentifier();
19010                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19011                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19012                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19013                broadcastIntentLocked(null, null, intent,
19014                        null, null, 0, null, null,
19015                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19016                        true, false, MY_PID, Process.SYSTEM_UID, userId);
19017            }
19018        }
19019    }
19020
19021    void finishUserSwitch(UserStartedState uss) {
19022        synchronized (this) {
19023            finishUserBoot(uss);
19024
19025            startProfilesLocked();
19026
19027            int num = mUserLru.size();
19028            int i = 0;
19029            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19030                Integer oldUserId = mUserLru.get(i);
19031                UserStartedState oldUss = mStartedUsers.get(oldUserId);
19032                if (oldUss == null) {
19033                    // Shouldn't happen, but be sane if it does.
19034                    mUserLru.remove(i);
19035                    num--;
19036                    continue;
19037                }
19038                if (oldUss.mState == UserStartedState.STATE_STOPPING
19039                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19040                    // This user is already stopping, doesn't count.
19041                    num--;
19042                    i++;
19043                    continue;
19044                }
19045                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19046                    // Owner and current can't be stopped, but count as running.
19047                    i++;
19048                    continue;
19049                }
19050                // This is a user to be stopped.
19051                stopUserLocked(oldUserId, null);
19052                num--;
19053                i++;
19054            }
19055        }
19056    }
19057
19058    @Override
19059    public int stopUser(final int userId, final IStopUserCallback callback) {
19060        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19061                != PackageManager.PERMISSION_GRANTED) {
19062            String msg = "Permission Denial: switchUser() from pid="
19063                    + Binder.getCallingPid()
19064                    + ", uid=" + Binder.getCallingUid()
19065                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19066            Slog.w(TAG, msg);
19067            throw new SecurityException(msg);
19068        }
19069        if (userId <= 0) {
19070            throw new IllegalArgumentException("Can't stop primary user " + userId);
19071        }
19072        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19073        synchronized (this) {
19074            return stopUserLocked(userId, callback);
19075        }
19076    }
19077
19078    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19079        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19080        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19081            return ActivityManager.USER_OP_IS_CURRENT;
19082        }
19083
19084        final UserStartedState uss = mStartedUsers.get(userId);
19085        if (uss == null) {
19086            // User is not started, nothing to do...  but we do need to
19087            // callback if requested.
19088            if (callback != null) {
19089                mHandler.post(new Runnable() {
19090                    @Override
19091                    public void run() {
19092                        try {
19093                            callback.userStopped(userId);
19094                        } catch (RemoteException e) {
19095                        }
19096                    }
19097                });
19098            }
19099            return ActivityManager.USER_OP_SUCCESS;
19100        }
19101
19102        if (callback != null) {
19103            uss.mStopCallbacks.add(callback);
19104        }
19105
19106        if (uss.mState != UserStartedState.STATE_STOPPING
19107                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19108            uss.mState = UserStartedState.STATE_STOPPING;
19109            updateStartedUserArrayLocked();
19110
19111            long ident = Binder.clearCallingIdentity();
19112            try {
19113                // We are going to broadcast ACTION_USER_STOPPING and then
19114                // once that is done send a final ACTION_SHUTDOWN and then
19115                // stop the user.
19116                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19117                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19118                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19119                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19120                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19121                // This is the result receiver for the final shutdown broadcast.
19122                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19123                    @Override
19124                    public void performReceive(Intent intent, int resultCode, String data,
19125                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19126                        finishUserStop(uss);
19127                    }
19128                };
19129                // This is the result receiver for the initial stopping broadcast.
19130                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19131                    @Override
19132                    public void performReceive(Intent intent, int resultCode, String data,
19133                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19134                        // On to the next.
19135                        synchronized (ActivityManagerService.this) {
19136                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19137                                // Whoops, we are being started back up.  Abort, abort!
19138                                return;
19139                            }
19140                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19141                        }
19142                        mBatteryStatsService.noteEvent(
19143                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19144                                Integer.toString(userId), userId);
19145                        mSystemServiceManager.stopUser(userId);
19146                        broadcastIntentLocked(null, null, shutdownIntent,
19147                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19148                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19149                    }
19150                };
19151                // Kick things off.
19152                broadcastIntentLocked(null, null, stoppingIntent,
19153                        null, stoppingReceiver, 0, null, null,
19154                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19155                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19156            } finally {
19157                Binder.restoreCallingIdentity(ident);
19158            }
19159        }
19160
19161        return ActivityManager.USER_OP_SUCCESS;
19162    }
19163
19164    void finishUserStop(UserStartedState uss) {
19165        final int userId = uss.mHandle.getIdentifier();
19166        boolean stopped;
19167        ArrayList<IStopUserCallback> callbacks;
19168        synchronized (this) {
19169            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19170            if (mStartedUsers.get(userId) != uss) {
19171                stopped = false;
19172            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19173                stopped = false;
19174            } else {
19175                stopped = true;
19176                // User can no longer run.
19177                mStartedUsers.remove(userId);
19178                mUserLru.remove(Integer.valueOf(userId));
19179                updateStartedUserArrayLocked();
19180
19181                // Clean up all state and processes associated with the user.
19182                // Kill all the processes for the user.
19183                forceStopUserLocked(userId, "finish user");
19184            }
19185
19186            // Explicitly remove the old information in mRecentTasks.
19187            removeRecentTasksForUserLocked(userId);
19188        }
19189
19190        for (int i=0; i<callbacks.size(); i++) {
19191            try {
19192                if (stopped) callbacks.get(i).userStopped(userId);
19193                else callbacks.get(i).userStopAborted(userId);
19194            } catch (RemoteException e) {
19195            }
19196        }
19197
19198        if (stopped) {
19199            mSystemServiceManager.cleanupUser(userId);
19200            synchronized (this) {
19201                mStackSupervisor.removeUserLocked(userId);
19202            }
19203        }
19204    }
19205
19206    @Override
19207    public UserInfo getCurrentUser() {
19208        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19209                != PackageManager.PERMISSION_GRANTED) && (
19210                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19211                != PackageManager.PERMISSION_GRANTED)) {
19212            String msg = "Permission Denial: getCurrentUser() from pid="
19213                    + Binder.getCallingPid()
19214                    + ", uid=" + Binder.getCallingUid()
19215                    + " requires " + INTERACT_ACROSS_USERS;
19216            Slog.w(TAG, msg);
19217            throw new SecurityException(msg);
19218        }
19219        synchronized (this) {
19220            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19221            return getUserManagerLocked().getUserInfo(userId);
19222        }
19223    }
19224
19225    int getCurrentUserIdLocked() {
19226        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19227    }
19228
19229    @Override
19230    public boolean isUserRunning(int userId, boolean orStopped) {
19231        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19232                != PackageManager.PERMISSION_GRANTED) {
19233            String msg = "Permission Denial: isUserRunning() from pid="
19234                    + Binder.getCallingPid()
19235                    + ", uid=" + Binder.getCallingUid()
19236                    + " requires " + INTERACT_ACROSS_USERS;
19237            Slog.w(TAG, msg);
19238            throw new SecurityException(msg);
19239        }
19240        synchronized (this) {
19241            return isUserRunningLocked(userId, orStopped);
19242        }
19243    }
19244
19245    boolean isUserRunningLocked(int userId, boolean orStopped) {
19246        UserStartedState state = mStartedUsers.get(userId);
19247        if (state == null) {
19248            return false;
19249        }
19250        if (orStopped) {
19251            return true;
19252        }
19253        return state.mState != UserStartedState.STATE_STOPPING
19254                && state.mState != UserStartedState.STATE_SHUTDOWN;
19255    }
19256
19257    @Override
19258    public int[] getRunningUserIds() {
19259        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19260                != PackageManager.PERMISSION_GRANTED) {
19261            String msg = "Permission Denial: isUserRunning() from pid="
19262                    + Binder.getCallingPid()
19263                    + ", uid=" + Binder.getCallingUid()
19264                    + " requires " + INTERACT_ACROSS_USERS;
19265            Slog.w(TAG, msg);
19266            throw new SecurityException(msg);
19267        }
19268        synchronized (this) {
19269            return mStartedUserArray;
19270        }
19271    }
19272
19273    private void updateStartedUserArrayLocked() {
19274        int num = 0;
19275        for (int i=0; i<mStartedUsers.size();  i++) {
19276            UserStartedState uss = mStartedUsers.valueAt(i);
19277            // This list does not include stopping users.
19278            if (uss.mState != UserStartedState.STATE_STOPPING
19279                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19280                num++;
19281            }
19282        }
19283        mStartedUserArray = new int[num];
19284        num = 0;
19285        for (int i=0; i<mStartedUsers.size();  i++) {
19286            UserStartedState uss = mStartedUsers.valueAt(i);
19287            if (uss.mState != UserStartedState.STATE_STOPPING
19288                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19289                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19290                num++;
19291            }
19292        }
19293    }
19294
19295    @Override
19296    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19297        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19298                != PackageManager.PERMISSION_GRANTED) {
19299            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19300                    + Binder.getCallingPid()
19301                    + ", uid=" + Binder.getCallingUid()
19302                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19303            Slog.w(TAG, msg);
19304            throw new SecurityException(msg);
19305        }
19306
19307        mUserSwitchObservers.register(observer);
19308    }
19309
19310    @Override
19311    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19312        mUserSwitchObservers.unregister(observer);
19313    }
19314
19315    private boolean userExists(int userId) {
19316        if (userId == 0) {
19317            return true;
19318        }
19319        UserManagerService ums = getUserManagerLocked();
19320        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19321    }
19322
19323    int[] getUsersLocked() {
19324        UserManagerService ums = getUserManagerLocked();
19325        return ums != null ? ums.getUserIds() : new int[] { 0 };
19326    }
19327
19328    UserManagerService getUserManagerLocked() {
19329        if (mUserManager == null) {
19330            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19331            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19332        }
19333        return mUserManager;
19334    }
19335
19336    private int applyUserId(int uid, int userId) {
19337        return UserHandle.getUid(userId, uid);
19338    }
19339
19340    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19341        if (info == null) return null;
19342        ApplicationInfo newInfo = new ApplicationInfo(info);
19343        newInfo.uid = applyUserId(info.uid, userId);
19344        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19345                + info.packageName;
19346        return newInfo;
19347    }
19348
19349    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19350        if (aInfo == null
19351                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19352            return aInfo;
19353        }
19354
19355        ActivityInfo info = new ActivityInfo(aInfo);
19356        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19357        return info;
19358    }
19359
19360    private final class LocalService extends ActivityManagerInternal {
19361        @Override
19362        public void onWakefulnessChanged(int wakefulness) {
19363            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19364        }
19365
19366        @Override
19367        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19368                String processName, String abiOverride, int uid, Runnable crashHandler) {
19369            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19370                    processName, abiOverride, uid, crashHandler);
19371        }
19372    }
19373
19374    /**
19375     * An implementation of IAppTask, that allows an app to manage its own tasks via
19376     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19377     * only the process that calls getAppTasks() can call the AppTask methods.
19378     */
19379    class AppTaskImpl extends IAppTask.Stub {
19380        private int mTaskId;
19381        private int mCallingUid;
19382
19383        public AppTaskImpl(int taskId, int callingUid) {
19384            mTaskId = taskId;
19385            mCallingUid = callingUid;
19386        }
19387
19388        private void checkCaller() {
19389            if (mCallingUid != Binder.getCallingUid()) {
19390                throw new SecurityException("Caller " + mCallingUid
19391                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19392            }
19393        }
19394
19395        @Override
19396        public void finishAndRemoveTask() {
19397            checkCaller();
19398
19399            synchronized (ActivityManagerService.this) {
19400                long origId = Binder.clearCallingIdentity();
19401                try {
19402                    if (!removeTaskByIdLocked(mTaskId, false)) {
19403                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19404                    }
19405                } finally {
19406                    Binder.restoreCallingIdentity(origId);
19407                }
19408            }
19409        }
19410
19411        @Override
19412        public ActivityManager.RecentTaskInfo getTaskInfo() {
19413            checkCaller();
19414
19415            synchronized (ActivityManagerService.this) {
19416                long origId = Binder.clearCallingIdentity();
19417                try {
19418                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19419                    if (tr == null) {
19420                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19421                    }
19422                    return createRecentTaskInfoFromTaskRecord(tr);
19423                } finally {
19424                    Binder.restoreCallingIdentity(origId);
19425                }
19426            }
19427        }
19428
19429        @Override
19430        public void moveToFront() {
19431            checkCaller();
19432
19433            final TaskRecord tr;
19434            synchronized (ActivityManagerService.this) {
19435                tr = recentTaskForIdLocked(mTaskId);
19436                if (tr == null) {
19437                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19438                }
19439                if (tr.getRootActivity() != null) {
19440                    moveTaskToFrontLocked(tr.taskId, 0, null);
19441                    return;
19442                }
19443            }
19444
19445            startActivityFromRecentsInner(tr.taskId, null);
19446        }
19447
19448        @Override
19449        public int startActivity(IBinder whoThread, String callingPackage,
19450                Intent intent, String resolvedType, Bundle options) {
19451            checkCaller();
19452
19453            int callingUser = UserHandle.getCallingUserId();
19454            TaskRecord tr;
19455            IApplicationThread appThread;
19456            synchronized (ActivityManagerService.this) {
19457                tr = recentTaskForIdLocked(mTaskId);
19458                if (tr == null) {
19459                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19460                }
19461                appThread = ApplicationThreadNative.asInterface(whoThread);
19462                if (appThread == null) {
19463                    throw new IllegalArgumentException("Bad app thread " + appThread);
19464                }
19465            }
19466            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19467                    resolvedType, null, null, null, null, 0, 0, null, null,
19468                    null, options, callingUser, null, tr);
19469        }
19470
19471        @Override
19472        public void setExcludeFromRecents(boolean exclude) {
19473            checkCaller();
19474
19475            synchronized (ActivityManagerService.this) {
19476                long origId = Binder.clearCallingIdentity();
19477                try {
19478                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19479                    if (tr == null) {
19480                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19481                    }
19482                    Intent intent = tr.getBaseIntent();
19483                    if (exclude) {
19484                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19485                    } else {
19486                        intent.setFlags(intent.getFlags()
19487                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19488                    }
19489                } finally {
19490                    Binder.restoreCallingIdentity(origId);
19491                }
19492            }
19493        }
19494    }
19495}
19496