ActivityManagerService.java revision 18795a2299fefd88ee16393f22324b999ace6ce4
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    String mDebugApp = null;
1079    boolean mWaitForDebugger = false;
1080    boolean mDebugTransient = false;
1081    String mOrigDebugApp = null;
1082    boolean mOrigWaitForDebugger = false;
1083    boolean mAlwaysFinishActivities = false;
1084    IActivityController mController = null;
1085    String mProfileApp = null;
1086    ProcessRecord mProfileProc = null;
1087    String mProfileFile;
1088    ParcelFileDescriptor mProfileFd;
1089    int mSamplingInterval = 0;
1090    boolean mAutoStopProfiler = false;
1091    int mProfileType = 0;
1092    String mOpenGlTraceApp = null;
1093
1094    static class ProcessChangeItem {
1095        static final int CHANGE_ACTIVITIES = 1<<0;
1096        static final int CHANGE_PROCESS_STATE = 1<<1;
1097        int changes;
1098        int uid;
1099        int pid;
1100        int processState;
1101        boolean foregroundActivities;
1102    }
1103
1104    final RemoteCallbackList<IProcessObserver> mProcessObservers
1105            = new RemoteCallbackList<IProcessObserver>();
1106    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1107
1108    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1109            = new ArrayList<ProcessChangeItem>();
1110    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1111            = new ArrayList<ProcessChangeItem>();
1112
1113    /**
1114     * Runtime CPU use collection thread.  This object's lock is used to
1115     * perform synchronization with the thread (notifying it to run).
1116     */
1117    final Thread mProcessCpuThread;
1118
1119    /**
1120     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1121     * Must acquire this object's lock when accessing it.
1122     * NOTE: this lock will be held while doing long operations (trawling
1123     * through all processes in /proc), so it should never be acquired by
1124     * any critical paths such as when holding the main activity manager lock.
1125     */
1126    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1127            MONITOR_THREAD_CPU_USAGE);
1128    final AtomicLong mLastCpuTime = new AtomicLong(0);
1129    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1130
1131    long mLastWriteTime = 0;
1132
1133    /**
1134     * Used to retain an update lock when the foreground activity is in
1135     * immersive mode.
1136     */
1137    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1138
1139    /**
1140     * Set to true after the system has finished booting.
1141     */
1142    boolean mBooted = false;
1143
1144    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1145    int mProcessLimitOverride = -1;
1146
1147    WindowManagerService mWindowManager;
1148
1149    final ActivityThread mSystemThread;
1150
1151    // Holds the current foreground user's id
1152    int mCurrentUserId = 0;
1153    // Holds the target user's id during a user switch
1154    int mTargetUserId = UserHandle.USER_NULL;
1155    // If there are multiple profiles for the current user, their ids are here
1156    // Currently only the primary user can have managed profiles
1157    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1158
1159    /**
1160     * Mapping from each known user ID to the profile group ID it is associated with.
1161     */
1162    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1163
1164    private UserManagerService mUserManager;
1165
1166    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1167        final ProcessRecord mApp;
1168        final int mPid;
1169        final IApplicationThread mAppThread;
1170
1171        AppDeathRecipient(ProcessRecord app, int pid,
1172                IApplicationThread thread) {
1173            if (localLOGV) Slog.v(
1174                TAG, "New death recipient " + this
1175                + " for thread " + thread.asBinder());
1176            mApp = app;
1177            mPid = pid;
1178            mAppThread = thread;
1179        }
1180
1181        @Override
1182        public void binderDied() {
1183            if (localLOGV) Slog.v(
1184                TAG, "Death received in " + this
1185                + " for thread " + mAppThread.asBinder());
1186            synchronized(ActivityManagerService.this) {
1187                appDiedLocked(mApp, mPid, mAppThread);
1188            }
1189        }
1190    }
1191
1192    static final int SHOW_ERROR_MSG = 1;
1193    static final int SHOW_NOT_RESPONDING_MSG = 2;
1194    static final int SHOW_FACTORY_ERROR_MSG = 3;
1195    static final int UPDATE_CONFIGURATION_MSG = 4;
1196    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1197    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1198    static final int SERVICE_TIMEOUT_MSG = 12;
1199    static final int UPDATE_TIME_ZONE = 13;
1200    static final int SHOW_UID_ERROR_MSG = 14;
1201    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1202    static final int PROC_START_TIMEOUT_MSG = 20;
1203    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1204    static final int KILL_APPLICATION_MSG = 22;
1205    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1206    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1207    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1208    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1209    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1210    static final int CLEAR_DNS_CACHE_MSG = 28;
1211    static final int UPDATE_HTTP_PROXY_MSG = 29;
1212    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1213    static final int DISPATCH_PROCESSES_CHANGED = 31;
1214    static final int DISPATCH_PROCESS_DIED = 32;
1215    static final int REPORT_MEM_USAGE_MSG = 33;
1216    static final int REPORT_USER_SWITCH_MSG = 34;
1217    static final int CONTINUE_USER_SWITCH_MSG = 35;
1218    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1219    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1220    static final int PERSIST_URI_GRANTS_MSG = 38;
1221    static final int REQUEST_ALL_PSS_MSG = 39;
1222    static final int START_PROFILES_MSG = 40;
1223    static final int UPDATE_TIME = 41;
1224    static final int SYSTEM_USER_START_MSG = 42;
1225    static final int SYSTEM_USER_CURRENT_MSG = 43;
1226    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1227    static final int FINISH_BOOTING_MSG = 45;
1228    static final int START_USER_SWITCH_MSG = 46;
1229    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1230    static final int DISMISS_DIALOG_MSG = 48;
1231    static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1232
1233    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1234    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1235    static final int FIRST_COMPAT_MODE_MSG = 300;
1236    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1237
1238    CompatModeDialog mCompatModeDialog;
1239    long mLastMemUsageReportTime = 0;
1240
1241    /**
1242     * Flag whether the current user is a "monkey", i.e. whether
1243     * the UI is driven by a UI automation tool.
1244     */
1245    private boolean mUserIsMonkey;
1246
1247    /** Flag whether the device has a Recents UI */
1248    boolean mHasRecents;
1249
1250    /** The dimensions of the thumbnails in the Recents UI. */
1251    int mThumbnailWidth;
1252    int mThumbnailHeight;
1253
1254    final ServiceThread mHandlerThread;
1255    final MainHandler mHandler;
1256
1257    final class MainHandler extends Handler {
1258        public MainHandler(Looper looper) {
1259            super(looper, null, true);
1260        }
1261
1262        @Override
1263        public void handleMessage(Message msg) {
1264            switch (msg.what) {
1265            case SHOW_ERROR_MSG: {
1266                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1267                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1268                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1269                synchronized (ActivityManagerService.this) {
1270                    ProcessRecord proc = (ProcessRecord)data.get("app");
1271                    AppErrorResult res = (AppErrorResult) data.get("result");
1272                    if (proc != null && proc.crashDialog != null) {
1273                        Slog.e(TAG, "App already has crash dialog: " + proc);
1274                        if (res != null) {
1275                            res.set(0);
1276                        }
1277                        return;
1278                    }
1279                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1280                            >= Process.FIRST_APPLICATION_UID
1281                            && proc.pid != MY_PID);
1282                    for (int userId : mCurrentProfileIds) {
1283                        isBackground &= (proc.userId != userId);
1284                    }
1285                    if (isBackground && !showBackground) {
1286                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1287                        if (res != null) {
1288                            res.set(0);
1289                        }
1290                        return;
1291                    }
1292                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1293                        Dialog d = new AppErrorDialog(mContext,
1294                                ActivityManagerService.this, res, proc);
1295                        d.show();
1296                        proc.crashDialog = d;
1297                    } else {
1298                        // The device is asleep, so just pretend that the user
1299                        // saw a crash dialog and hit "force quit".
1300                        if (res != null) {
1301                            res.set(0);
1302                        }
1303                    }
1304                }
1305
1306                ensureBootCompleted();
1307            } break;
1308            case SHOW_NOT_RESPONDING_MSG: {
1309                synchronized (ActivityManagerService.this) {
1310                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1311                    ProcessRecord proc = (ProcessRecord)data.get("app");
1312                    if (proc != null && proc.anrDialog != null) {
1313                        Slog.e(TAG, "App already has anr dialog: " + proc);
1314                        return;
1315                    }
1316
1317                    Intent intent = new Intent("android.intent.action.ANR");
1318                    if (!mProcessesReady) {
1319                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1320                                | Intent.FLAG_RECEIVER_FOREGROUND);
1321                    }
1322                    broadcastIntentLocked(null, null, intent,
1323                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1324                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1325
1326                    if (mShowDialogs) {
1327                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1328                                mContext, proc, (ActivityRecord)data.get("activity"),
1329                                msg.arg1 != 0);
1330                        d.show();
1331                        proc.anrDialog = d;
1332                    } else {
1333                        // Just kill the app if there is no dialog to be shown.
1334                        killAppAtUsersRequest(proc, null);
1335                    }
1336                }
1337
1338                ensureBootCompleted();
1339            } break;
1340            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1341                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1342                synchronized (ActivityManagerService.this) {
1343                    ProcessRecord proc = (ProcessRecord) data.get("app");
1344                    if (proc == null) {
1345                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1346                        break;
1347                    }
1348                    if (proc.crashDialog != null) {
1349                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1350                        return;
1351                    }
1352                    AppErrorResult res = (AppErrorResult) data.get("result");
1353                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1354                        Dialog d = new StrictModeViolationDialog(mContext,
1355                                ActivityManagerService.this, res, proc);
1356                        d.show();
1357                        proc.crashDialog = d;
1358                    } else {
1359                        // The device is asleep, so just pretend that the user
1360                        // saw a crash dialog and hit "force quit".
1361                        res.set(0);
1362                    }
1363                }
1364                ensureBootCompleted();
1365            } break;
1366            case SHOW_FACTORY_ERROR_MSG: {
1367                Dialog d = new FactoryErrorDialog(
1368                    mContext, msg.getData().getCharSequence("msg"));
1369                d.show();
1370                ensureBootCompleted();
1371            } break;
1372            case UPDATE_CONFIGURATION_MSG: {
1373                final ContentResolver resolver = mContext.getContentResolver();
1374                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1375            } break;
1376            case GC_BACKGROUND_PROCESSES_MSG: {
1377                synchronized (ActivityManagerService.this) {
1378                    performAppGcsIfAppropriateLocked();
1379                }
1380            } break;
1381            case WAIT_FOR_DEBUGGER_MSG: {
1382                synchronized (ActivityManagerService.this) {
1383                    ProcessRecord app = (ProcessRecord)msg.obj;
1384                    if (msg.arg1 != 0) {
1385                        if (!app.waitedForDebugger) {
1386                            Dialog d = new AppWaitingForDebuggerDialog(
1387                                    ActivityManagerService.this,
1388                                    mContext, app);
1389                            app.waitDialog = d;
1390                            app.waitedForDebugger = true;
1391                            d.show();
1392                        }
1393                    } else {
1394                        if (app.waitDialog != null) {
1395                            app.waitDialog.dismiss();
1396                            app.waitDialog = null;
1397                        }
1398                    }
1399                }
1400            } break;
1401            case SERVICE_TIMEOUT_MSG: {
1402                if (mDidDexOpt) {
1403                    mDidDexOpt = false;
1404                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1405                    nmsg.obj = msg.obj;
1406                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1407                    return;
1408                }
1409                mServices.serviceTimeout((ProcessRecord)msg.obj);
1410            } break;
1411            case UPDATE_TIME_ZONE: {
1412                synchronized (ActivityManagerService.this) {
1413                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1414                        ProcessRecord r = mLruProcesses.get(i);
1415                        if (r.thread != null) {
1416                            try {
1417                                r.thread.updateTimeZone();
1418                            } catch (RemoteException ex) {
1419                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1420                            }
1421                        }
1422                    }
1423                }
1424            } break;
1425            case CLEAR_DNS_CACHE_MSG: {
1426                synchronized (ActivityManagerService.this) {
1427                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1428                        ProcessRecord r = mLruProcesses.get(i);
1429                        if (r.thread != null) {
1430                            try {
1431                                r.thread.clearDnsCache();
1432                            } catch (RemoteException ex) {
1433                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1434                            }
1435                        }
1436                    }
1437                }
1438            } break;
1439            case UPDATE_HTTP_PROXY_MSG: {
1440                ProxyInfo proxy = (ProxyInfo)msg.obj;
1441                String host = "";
1442                String port = "";
1443                String exclList = "";
1444                Uri pacFileUrl = Uri.EMPTY;
1445                if (proxy != null) {
1446                    host = proxy.getHost();
1447                    port = Integer.toString(proxy.getPort());
1448                    exclList = proxy.getExclusionListAsString();
1449                    pacFileUrl = proxy.getPacFileUrl();
1450                }
1451                synchronized (ActivityManagerService.this) {
1452                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1453                        ProcessRecord r = mLruProcesses.get(i);
1454                        if (r.thread != null) {
1455                            try {
1456                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1457                            } catch (RemoteException ex) {
1458                                Slog.w(TAG, "Failed to update http proxy for: " +
1459                                        r.info.processName);
1460                            }
1461                        }
1462                    }
1463                }
1464            } break;
1465            case SHOW_UID_ERROR_MSG: {
1466                if (mShowDialogs) {
1467                    AlertDialog d = new BaseErrorDialog(mContext);
1468                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1469                    d.setCancelable(false);
1470                    d.setTitle(mContext.getText(R.string.android_system_label));
1471                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1472                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1473                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1474                    d.show();
1475                }
1476            } break;
1477            case SHOW_FINGERPRINT_ERROR_MSG: {
1478                if (mShowDialogs) {
1479                    AlertDialog d = new BaseErrorDialog(mContext);
1480                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1481                    d.setCancelable(false);
1482                    d.setTitle(mContext.getText(R.string.android_system_label));
1483                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1484                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1485                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1486                    d.show();
1487                }
1488            } break;
1489            case PROC_START_TIMEOUT_MSG: {
1490                if (mDidDexOpt) {
1491                    mDidDexOpt = false;
1492                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1493                    nmsg.obj = msg.obj;
1494                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1495                    return;
1496                }
1497                ProcessRecord app = (ProcessRecord)msg.obj;
1498                synchronized (ActivityManagerService.this) {
1499                    processStartTimedOutLocked(app);
1500                }
1501            } break;
1502            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1503                synchronized (ActivityManagerService.this) {
1504                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1505                }
1506            } break;
1507            case KILL_APPLICATION_MSG: {
1508                synchronized (ActivityManagerService.this) {
1509                    int appid = msg.arg1;
1510                    boolean restart = (msg.arg2 == 1);
1511                    Bundle bundle = (Bundle)msg.obj;
1512                    String pkg = bundle.getString("pkg");
1513                    String reason = bundle.getString("reason");
1514                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1515                            false, UserHandle.USER_ALL, reason);
1516                }
1517            } break;
1518            case FINALIZE_PENDING_INTENT_MSG: {
1519                ((PendingIntentRecord)msg.obj).completeFinalize();
1520            } break;
1521            case POST_HEAVY_NOTIFICATION_MSG: {
1522                INotificationManager inm = NotificationManager.getService();
1523                if (inm == null) {
1524                    return;
1525                }
1526
1527                ActivityRecord root = (ActivityRecord)msg.obj;
1528                ProcessRecord process = root.app;
1529                if (process == null) {
1530                    return;
1531                }
1532
1533                try {
1534                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1535                    String text = mContext.getString(R.string.heavy_weight_notification,
1536                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1537                    Notification notification = new Notification();
1538                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1539                    notification.when = 0;
1540                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1541                    notification.tickerText = text;
1542                    notification.defaults = 0; // please be quiet
1543                    notification.sound = null;
1544                    notification.vibrate = null;
1545                    notification.color = mContext.getResources().getColor(
1546                            com.android.internal.R.color.system_notification_accent_color);
1547                    notification.setLatestEventInfo(context, text,
1548                            mContext.getText(R.string.heavy_weight_notification_detail),
1549                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1550                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1551                                    new UserHandle(root.userId)));
1552
1553                    try {
1554                        int[] outId = new int[1];
1555                        inm.enqueueNotificationWithTag("android", "android", null,
1556                                R.string.heavy_weight_notification,
1557                                notification, outId, root.userId);
1558                    } catch (RuntimeException e) {
1559                        Slog.w(ActivityManagerService.TAG,
1560                                "Error showing notification for heavy-weight app", e);
1561                    } catch (RemoteException e) {
1562                    }
1563                } catch (NameNotFoundException e) {
1564                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1565                }
1566            } break;
1567            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1568                INotificationManager inm = NotificationManager.getService();
1569                if (inm == null) {
1570                    return;
1571                }
1572                try {
1573                    inm.cancelNotificationWithTag("android", null,
1574                            R.string.heavy_weight_notification,  msg.arg1);
1575                } catch (RuntimeException e) {
1576                    Slog.w(ActivityManagerService.TAG,
1577                            "Error canceling notification for service", e);
1578                } catch (RemoteException e) {
1579                }
1580            } break;
1581            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1582                synchronized (ActivityManagerService.this) {
1583                    checkExcessivePowerUsageLocked(true);
1584                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1585                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1586                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1587                }
1588            } break;
1589            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1590                synchronized (ActivityManagerService.this) {
1591                    ActivityRecord ar = (ActivityRecord)msg.obj;
1592                    if (mCompatModeDialog != null) {
1593                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1594                                ar.info.applicationInfo.packageName)) {
1595                            return;
1596                        }
1597                        mCompatModeDialog.dismiss();
1598                        mCompatModeDialog = null;
1599                    }
1600                    if (ar != null && false) {
1601                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1602                                ar.packageName)) {
1603                            int mode = mCompatModePackages.computeCompatModeLocked(
1604                                    ar.info.applicationInfo);
1605                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1606                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1607                                mCompatModeDialog = new CompatModeDialog(
1608                                        ActivityManagerService.this, mContext,
1609                                        ar.info.applicationInfo);
1610                                mCompatModeDialog.show();
1611                            }
1612                        }
1613                    }
1614                }
1615                break;
1616            }
1617            case DISPATCH_PROCESSES_CHANGED: {
1618                dispatchProcessesChanged();
1619                break;
1620            }
1621            case DISPATCH_PROCESS_DIED: {
1622                final int pid = msg.arg1;
1623                final int uid = msg.arg2;
1624                dispatchProcessDied(pid, uid);
1625                break;
1626            }
1627            case REPORT_MEM_USAGE_MSG: {
1628                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1629                Thread thread = new Thread() {
1630                    @Override public void run() {
1631                        reportMemUsage(memInfos);
1632                    }
1633                };
1634                thread.start();
1635                break;
1636            }
1637            case START_USER_SWITCH_MSG: {
1638                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1639                break;
1640            }
1641            case REPORT_USER_SWITCH_MSG: {
1642                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1643                break;
1644            }
1645            case CONTINUE_USER_SWITCH_MSG: {
1646                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1647                break;
1648            }
1649            case USER_SWITCH_TIMEOUT_MSG: {
1650                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1651                break;
1652            }
1653            case IMMERSIVE_MODE_LOCK_MSG: {
1654                final boolean nextState = (msg.arg1 != 0);
1655                if (mUpdateLock.isHeld() != nextState) {
1656                    if (DEBUG_IMMERSIVE) {
1657                        final ActivityRecord r = (ActivityRecord) msg.obj;
1658                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1659                    }
1660                    if (nextState) {
1661                        mUpdateLock.acquire();
1662                    } else {
1663                        mUpdateLock.release();
1664                    }
1665                }
1666                break;
1667            }
1668            case PERSIST_URI_GRANTS_MSG: {
1669                writeGrantedUriPermissions();
1670                break;
1671            }
1672            case REQUEST_ALL_PSS_MSG: {
1673                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1674                break;
1675            }
1676            case START_PROFILES_MSG: {
1677                synchronized (ActivityManagerService.this) {
1678                    startProfilesLocked();
1679                }
1680                break;
1681            }
1682            case UPDATE_TIME: {
1683                synchronized (ActivityManagerService.this) {
1684                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1685                        ProcessRecord r = mLruProcesses.get(i);
1686                        if (r.thread != null) {
1687                            try {
1688                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1689                            } catch (RemoteException ex) {
1690                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1691                            }
1692                        }
1693                    }
1694                }
1695                break;
1696            }
1697            case SYSTEM_USER_START_MSG: {
1698                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1699                        Integer.toString(msg.arg1), msg.arg1);
1700                mSystemServiceManager.startUser(msg.arg1);
1701                break;
1702            }
1703            case SYSTEM_USER_CURRENT_MSG: {
1704                mBatteryStatsService.noteEvent(
1705                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1706                        Integer.toString(msg.arg2), msg.arg2);
1707                mBatteryStatsService.noteEvent(
1708                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1709                        Integer.toString(msg.arg1), msg.arg1);
1710                mSystemServiceManager.switchUser(msg.arg1);
1711                break;
1712            }
1713            case ENTER_ANIMATION_COMPLETE_MSG: {
1714                synchronized (ActivityManagerService.this) {
1715                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1716                    if (r != null && r.app != null && r.app.thread != null) {
1717                        try {
1718                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1719                        } catch (RemoteException e) {
1720                        }
1721                    }
1722                }
1723                break;
1724            }
1725            case FINISH_BOOTING_MSG: {
1726                if (msg.arg1 != 0) {
1727                    finishBooting();
1728                }
1729                if (msg.arg2 != 0) {
1730                    enableScreenAfterBoot();
1731                }
1732                break;
1733            }
1734            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1735                try {
1736                    Locale l = (Locale) msg.obj;
1737                    IBinder service = ServiceManager.getService("mount");
1738                    IMountService mountService = IMountService.Stub.asInterface(service);
1739                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1740                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1741                } catch (RemoteException e) {
1742                    Log.e(TAG, "Error storing locale for decryption UI", e);
1743                }
1744                break;
1745            }
1746            case DISMISS_DIALOG_MSG: {
1747                final Dialog d = (Dialog) msg.obj;
1748                d.dismiss();
1749                break;
1750            }
1751            case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1752                synchronized (ActivityManagerService.this) {
1753                    int i = mTaskStackListeners.beginBroadcast();
1754                    while (i > 0) {
1755                        i--;
1756                        try {
1757                            // Make a one-way callback to the listener
1758                            mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1759                        } catch (RemoteException e){
1760                            // Handled by the RemoteCallbackList
1761                        }
1762                    }
1763                    mTaskStackListeners.finishBroadcast();
1764                }
1765                break;
1766            }
1767            }
1768        }
1769    };
1770
1771    static final int COLLECT_PSS_BG_MSG = 1;
1772
1773    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1774        @Override
1775        public void handleMessage(Message msg) {
1776            switch (msg.what) {
1777            case COLLECT_PSS_BG_MSG: {
1778                long start = SystemClock.uptimeMillis();
1779                MemInfoReader memInfo = null;
1780                synchronized (ActivityManagerService.this) {
1781                    if (mFullPssPending) {
1782                        mFullPssPending = false;
1783                        memInfo = new MemInfoReader();
1784                    }
1785                }
1786                if (memInfo != null) {
1787                    updateCpuStatsNow();
1788                    long nativeTotalPss = 0;
1789                    synchronized (mProcessCpuTracker) {
1790                        final int N = mProcessCpuTracker.countStats();
1791                        for (int j=0; j<N; j++) {
1792                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1793                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1794                                // This is definitely an application process; skip it.
1795                                continue;
1796                            }
1797                            synchronized (mPidsSelfLocked) {
1798                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1799                                    // This is one of our own processes; skip it.
1800                                    continue;
1801                                }
1802                            }
1803                            nativeTotalPss += Debug.getPss(st.pid, null);
1804                        }
1805                    }
1806                    memInfo.readMemInfo();
1807                    synchronized (ActivityManagerService.this) {
1808                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1809                                + (SystemClock.uptimeMillis()-start) + "ms");
1810                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1811                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1812                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1813                    }
1814                }
1815
1816                int i = 0;
1817                int num = 0;
1818                long[] tmp = new long[1];
1819                do {
1820                    ProcessRecord proc;
1821                    int procState;
1822                    int pid;
1823                    synchronized (ActivityManagerService.this) {
1824                        if (i >= mPendingPssProcesses.size()) {
1825                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1826                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1827                            mPendingPssProcesses.clear();
1828                            return;
1829                        }
1830                        proc = mPendingPssProcesses.get(i);
1831                        procState = proc.pssProcState;
1832                        if (proc.thread != null && procState == proc.setProcState) {
1833                            pid = proc.pid;
1834                        } else {
1835                            proc = null;
1836                            pid = 0;
1837                        }
1838                        i++;
1839                    }
1840                    if (proc != null) {
1841                        long pss = Debug.getPss(pid, tmp);
1842                        synchronized (ActivityManagerService.this) {
1843                            if (proc.thread != null && proc.setProcState == procState
1844                                    && proc.pid == pid) {
1845                                num++;
1846                                proc.lastPssTime = SystemClock.uptimeMillis();
1847                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1848                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1849                                        + ": " + pss + " lastPss=" + proc.lastPss
1850                                        + " state=" + ProcessList.makeProcStateString(procState));
1851                                if (proc.initialIdlePss == 0) {
1852                                    proc.initialIdlePss = pss;
1853                                }
1854                                proc.lastPss = pss;
1855                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1856                                    proc.lastCachedPss = pss;
1857                                }
1858                            }
1859                        }
1860                    }
1861                } while (true);
1862            }
1863            }
1864        }
1865    };
1866
1867    public void setSystemProcess() {
1868        try {
1869            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1870            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1871            ServiceManager.addService("meminfo", new MemBinder(this));
1872            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1873            ServiceManager.addService("dbinfo", new DbBinder(this));
1874            if (MONITOR_CPU_USAGE) {
1875                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1876            }
1877            ServiceManager.addService("permission", new PermissionController(this));
1878
1879            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1880                    "android", STOCK_PM_FLAGS);
1881            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1882
1883            synchronized (this) {
1884                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1885                app.persistent = true;
1886                app.pid = MY_PID;
1887                app.maxAdj = ProcessList.SYSTEM_ADJ;
1888                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1889                mProcessNames.put(app.processName, app.uid, app);
1890                synchronized (mPidsSelfLocked) {
1891                    mPidsSelfLocked.put(app.pid, app);
1892                }
1893                updateLruProcessLocked(app, false, null);
1894                updateOomAdjLocked();
1895            }
1896        } catch (PackageManager.NameNotFoundException e) {
1897            throw new RuntimeException(
1898                    "Unable to find android system package", e);
1899        }
1900    }
1901
1902    public void setWindowManager(WindowManagerService wm) {
1903        mWindowManager = wm;
1904        mStackSupervisor.setWindowManager(wm);
1905    }
1906
1907    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1908        mUsageStatsService = usageStatsManager;
1909    }
1910
1911    public void startObservingNativeCrashes() {
1912        final NativeCrashListener ncl = new NativeCrashListener(this);
1913        ncl.start();
1914    }
1915
1916    public IAppOpsService getAppOpsService() {
1917        return mAppOpsService;
1918    }
1919
1920    static class MemBinder extends Binder {
1921        ActivityManagerService mActivityManagerService;
1922        MemBinder(ActivityManagerService activityManagerService) {
1923            mActivityManagerService = activityManagerService;
1924        }
1925
1926        @Override
1927        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1928            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1929                    != PackageManager.PERMISSION_GRANTED) {
1930                pw.println("Permission Denial: can't dump meminfo from from pid="
1931                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1932                        + " without permission " + android.Manifest.permission.DUMP);
1933                return;
1934            }
1935
1936            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1937        }
1938    }
1939
1940    static class GraphicsBinder extends Binder {
1941        ActivityManagerService mActivityManagerService;
1942        GraphicsBinder(ActivityManagerService activityManagerService) {
1943            mActivityManagerService = activityManagerService;
1944        }
1945
1946        @Override
1947        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1948            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1949                    != PackageManager.PERMISSION_GRANTED) {
1950                pw.println("Permission Denial: can't dump gfxinfo from from pid="
1951                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1952                        + " without permission " + android.Manifest.permission.DUMP);
1953                return;
1954            }
1955
1956            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1957        }
1958    }
1959
1960    static class DbBinder extends Binder {
1961        ActivityManagerService mActivityManagerService;
1962        DbBinder(ActivityManagerService activityManagerService) {
1963            mActivityManagerService = activityManagerService;
1964        }
1965
1966        @Override
1967        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1968            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1969                    != PackageManager.PERMISSION_GRANTED) {
1970                pw.println("Permission Denial: can't dump dbinfo from from pid="
1971                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1972                        + " without permission " + android.Manifest.permission.DUMP);
1973                return;
1974            }
1975
1976            mActivityManagerService.dumpDbInfo(fd, pw, args);
1977        }
1978    }
1979
1980    static class CpuBinder extends Binder {
1981        ActivityManagerService mActivityManagerService;
1982        CpuBinder(ActivityManagerService activityManagerService) {
1983            mActivityManagerService = activityManagerService;
1984        }
1985
1986        @Override
1987        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1988            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1989                    != PackageManager.PERMISSION_GRANTED) {
1990                pw.println("Permission Denial: can't dump cpuinfo from from pid="
1991                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1992                        + " without permission " + android.Manifest.permission.DUMP);
1993                return;
1994            }
1995
1996            synchronized (mActivityManagerService.mProcessCpuTracker) {
1997                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
1998                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
1999                        SystemClock.uptimeMillis()));
2000            }
2001        }
2002    }
2003
2004    public static final class Lifecycle extends SystemService {
2005        private final ActivityManagerService mService;
2006
2007        public Lifecycle(Context context) {
2008            super(context);
2009            mService = new ActivityManagerService(context);
2010        }
2011
2012        @Override
2013        public void onStart() {
2014            mService.start();
2015        }
2016
2017        public ActivityManagerService getService() {
2018            return mService;
2019        }
2020    }
2021
2022    // Note: This method is invoked on the main thread but may need to attach various
2023    // handlers to other threads.  So take care to be explicit about the looper.
2024    public ActivityManagerService(Context systemContext) {
2025        mContext = systemContext;
2026        mFactoryTest = FactoryTest.getMode();
2027        mSystemThread = ActivityThread.currentActivityThread();
2028
2029        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2030
2031        mHandlerThread = new ServiceThread(TAG,
2032                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2033        mHandlerThread.start();
2034        mHandler = new MainHandler(mHandlerThread.getLooper());
2035
2036        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2037                "foreground", BROADCAST_FG_TIMEOUT, false);
2038        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2039                "background", BROADCAST_BG_TIMEOUT, true);
2040        mBroadcastQueues[0] = mFgBroadcastQueue;
2041        mBroadcastQueues[1] = mBgBroadcastQueue;
2042
2043        mServices = new ActiveServices(this);
2044        mProviderMap = new ProviderMap(this);
2045
2046        // TODO: Move creation of battery stats service outside of activity manager service.
2047        File dataDir = Environment.getDataDirectory();
2048        File systemDir = new File(dataDir, "system");
2049        systemDir.mkdirs();
2050        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2051        mBatteryStatsService.getActiveStatistics().readLocked();
2052        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2053        mOnBattery = DEBUG_POWER ? true
2054                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2055        mBatteryStatsService.getActiveStatistics().setCallback(this);
2056
2057        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2058
2059        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2060
2061        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2062
2063        // User 0 is the first and only user that runs at boot.
2064        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2065        mUserLru.add(Integer.valueOf(0));
2066        updateStartedUserArrayLocked();
2067
2068        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2069            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2070
2071        mConfiguration.setToDefaults();
2072        mConfiguration.setLocale(Locale.getDefault());
2073
2074        mConfigurationSeq = mConfiguration.seq = 1;
2075        mProcessCpuTracker.init();
2076
2077        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2078        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2079        mStackSupervisor = new ActivityStackSupervisor(this);
2080        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2081
2082        mProcessCpuThread = new Thread("CpuTracker") {
2083            @Override
2084            public void run() {
2085                while (true) {
2086                    try {
2087                        try {
2088                            synchronized(this) {
2089                                final long now = SystemClock.uptimeMillis();
2090                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2091                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2092                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2093                                //        + ", write delay=" + nextWriteDelay);
2094                                if (nextWriteDelay < nextCpuDelay) {
2095                                    nextCpuDelay = nextWriteDelay;
2096                                }
2097                                if (nextCpuDelay > 0) {
2098                                    mProcessCpuMutexFree.set(true);
2099                                    this.wait(nextCpuDelay);
2100                                }
2101                            }
2102                        } catch (InterruptedException e) {
2103                        }
2104                        updateCpuStatsNow();
2105                    } catch (Exception e) {
2106                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2107                    }
2108                }
2109            }
2110        };
2111
2112        Watchdog.getInstance().addMonitor(this);
2113        Watchdog.getInstance().addThread(mHandler);
2114    }
2115
2116    public void setSystemServiceManager(SystemServiceManager mgr) {
2117        mSystemServiceManager = mgr;
2118    }
2119
2120    public void setInstaller(Installer installer) {
2121        mInstaller = installer;
2122    }
2123
2124    private void start() {
2125        Process.removeAllProcessGroups();
2126        mProcessCpuThread.start();
2127
2128        mBatteryStatsService.publish(mContext);
2129        mAppOpsService.publish(mContext);
2130        Slog.d("AppOps", "AppOpsService published");
2131        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2132    }
2133
2134    public void initPowerManagement() {
2135        mStackSupervisor.initPowerManagement();
2136        mBatteryStatsService.initPowerManagement();
2137    }
2138
2139    @Override
2140    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2141            throws RemoteException {
2142        if (code == SYSPROPS_TRANSACTION) {
2143            // We need to tell all apps about the system property change.
2144            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2145            synchronized(this) {
2146                final int NP = mProcessNames.getMap().size();
2147                for (int ip=0; ip<NP; ip++) {
2148                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2149                    final int NA = apps.size();
2150                    for (int ia=0; ia<NA; ia++) {
2151                        ProcessRecord app = apps.valueAt(ia);
2152                        if (app.thread != null) {
2153                            procs.add(app.thread.asBinder());
2154                        }
2155                    }
2156                }
2157            }
2158
2159            int N = procs.size();
2160            for (int i=0; i<N; i++) {
2161                Parcel data2 = Parcel.obtain();
2162                try {
2163                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2164                } catch (RemoteException e) {
2165                }
2166                data2.recycle();
2167            }
2168        }
2169        try {
2170            return super.onTransact(code, data, reply, flags);
2171        } catch (RuntimeException e) {
2172            // The activity manager only throws security exceptions, so let's
2173            // log all others.
2174            if (!(e instanceof SecurityException)) {
2175                Slog.wtf(TAG, "Activity Manager Crash", e);
2176            }
2177            throw e;
2178        }
2179    }
2180
2181    void updateCpuStats() {
2182        final long now = SystemClock.uptimeMillis();
2183        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2184            return;
2185        }
2186        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2187            synchronized (mProcessCpuThread) {
2188                mProcessCpuThread.notify();
2189            }
2190        }
2191    }
2192
2193    void updateCpuStatsNow() {
2194        synchronized (mProcessCpuTracker) {
2195            mProcessCpuMutexFree.set(false);
2196            final long now = SystemClock.uptimeMillis();
2197            boolean haveNewCpuStats = false;
2198
2199            if (MONITOR_CPU_USAGE &&
2200                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2201                mLastCpuTime.set(now);
2202                haveNewCpuStats = true;
2203                mProcessCpuTracker.update();
2204                //Slog.i(TAG, mProcessCpu.printCurrentState());
2205                //Slog.i(TAG, "Total CPU usage: "
2206                //        + mProcessCpu.getTotalCpuPercent() + "%");
2207
2208                // Slog the cpu usage if the property is set.
2209                if ("true".equals(SystemProperties.get("events.cpu"))) {
2210                    int user = mProcessCpuTracker.getLastUserTime();
2211                    int system = mProcessCpuTracker.getLastSystemTime();
2212                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2213                    int irq = mProcessCpuTracker.getLastIrqTime();
2214                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2215                    int idle = mProcessCpuTracker.getLastIdleTime();
2216
2217                    int total = user + system + iowait + irq + softIrq + idle;
2218                    if (total == 0) total = 1;
2219
2220                    EventLog.writeEvent(EventLogTags.CPU,
2221                            ((user+system+iowait+irq+softIrq) * 100) / total,
2222                            (user * 100) / total,
2223                            (system * 100) / total,
2224                            (iowait * 100) / total,
2225                            (irq * 100) / total,
2226                            (softIrq * 100) / total);
2227                }
2228            }
2229
2230            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2231            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2232            synchronized(bstats) {
2233                synchronized(mPidsSelfLocked) {
2234                    if (haveNewCpuStats) {
2235                        if (mOnBattery) {
2236                            int perc = bstats.startAddingCpuLocked();
2237                            int totalUTime = 0;
2238                            int totalSTime = 0;
2239                            final int N = mProcessCpuTracker.countStats();
2240                            for (int i=0; i<N; i++) {
2241                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2242                                if (!st.working) {
2243                                    continue;
2244                                }
2245                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2246                                int otherUTime = (st.rel_utime*perc)/100;
2247                                int otherSTime = (st.rel_stime*perc)/100;
2248                                totalUTime += otherUTime;
2249                                totalSTime += otherSTime;
2250                                if (pr != null) {
2251                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2252                                    if (ps == null || !ps.isActive()) {
2253                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2254                                                pr.info.uid, pr.processName);
2255                                    }
2256                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2257                                            st.rel_stime-otherSTime);
2258                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2259                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2260                                } else {
2261                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2262                                    if (ps == null || !ps.isActive()) {
2263                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2264                                                bstats.mapUid(st.uid), st.name);
2265                                    }
2266                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2267                                            st.rel_stime-otherSTime);
2268                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2269                                }
2270                            }
2271                            bstats.finishAddingCpuLocked(perc, totalUTime,
2272                                    totalSTime, cpuSpeedTimes);
2273                        }
2274                    }
2275                }
2276
2277                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2278                    mLastWriteTime = now;
2279                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2280                }
2281            }
2282        }
2283    }
2284
2285    @Override
2286    public void batteryNeedsCpuUpdate() {
2287        updateCpuStatsNow();
2288    }
2289
2290    @Override
2291    public void batteryPowerChanged(boolean onBattery) {
2292        // When plugging in, update the CPU stats first before changing
2293        // the plug state.
2294        updateCpuStatsNow();
2295        synchronized (this) {
2296            synchronized(mPidsSelfLocked) {
2297                mOnBattery = DEBUG_POWER ? true : onBattery;
2298            }
2299        }
2300    }
2301
2302    /**
2303     * Initialize the application bind args. These are passed to each
2304     * process when the bindApplication() IPC is sent to the process. They're
2305     * lazily setup to make sure the services are running when they're asked for.
2306     */
2307    private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2308        if (mAppBindArgs == null) {
2309            mAppBindArgs = new HashMap<>();
2310
2311            // Isolated processes won't get this optimization, so that we don't
2312            // violate the rules about which services they have access to.
2313            if (!isolated) {
2314                // Setup the application init args
2315                mAppBindArgs.put("package", ServiceManager.getService("package"));
2316                mAppBindArgs.put("window", ServiceManager.getService("window"));
2317                mAppBindArgs.put(Context.ALARM_SERVICE,
2318                        ServiceManager.getService(Context.ALARM_SERVICE));
2319            }
2320        }
2321        return mAppBindArgs;
2322    }
2323
2324    final void setFocusedActivityLocked(ActivityRecord r) {
2325        if (mFocusedActivity != r) {
2326            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2327            mFocusedActivity = r;
2328            if (r.task != null && r.task.voiceInteractor != null) {
2329                startRunningVoiceLocked();
2330            } else {
2331                finishRunningVoiceLocked();
2332            }
2333            mStackSupervisor.setFocusedStack(r);
2334            if (r != null) {
2335                mWindowManager.setFocusedApp(r.appToken, true);
2336            }
2337            applyUpdateLockStateLocked(r);
2338        }
2339    }
2340
2341    final void clearFocusedActivity(ActivityRecord r) {
2342        if (mFocusedActivity == r) {
2343            mFocusedActivity = null;
2344        }
2345    }
2346
2347    @Override
2348    public void setFocusedStack(int stackId) {
2349        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2350        synchronized (ActivityManagerService.this) {
2351            ActivityStack stack = mStackSupervisor.getStack(stackId);
2352            if (stack != null) {
2353                ActivityRecord r = stack.topRunningActivityLocked(null);
2354                if (r != null) {
2355                    setFocusedActivityLocked(r);
2356                }
2357            }
2358        }
2359    }
2360
2361    /** Sets the task stack listener that gets callbacks when a task stack changes. */
2362    @Override
2363    public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2364        synchronized (ActivityManagerService.this) {
2365            if (listener != null) {
2366                mTaskStackListeners.register(listener);
2367            }
2368        }
2369    }
2370
2371    @Override
2372    public void notifyActivityDrawn(IBinder token) {
2373        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2374        synchronized (this) {
2375            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2376            if (r != null) {
2377                r.task.stack.notifyActivityDrawnLocked(r);
2378            }
2379        }
2380    }
2381
2382    final void applyUpdateLockStateLocked(ActivityRecord r) {
2383        // Modifications to the UpdateLock state are done on our handler, outside
2384        // the activity manager's locks.  The new state is determined based on the
2385        // state *now* of the relevant activity record.  The object is passed to
2386        // the handler solely for logging detail, not to be consulted/modified.
2387        final boolean nextState = r != null && r.immersive;
2388        mHandler.sendMessage(
2389                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2390    }
2391
2392    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2393        Message msg = Message.obtain();
2394        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2395        msg.obj = r.task.askedCompatMode ? null : r;
2396        mHandler.sendMessage(msg);
2397    }
2398
2399    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2400            String what, Object obj, ProcessRecord srcApp) {
2401        app.lastActivityTime = now;
2402
2403        if (app.activities.size() > 0) {
2404            // Don't want to touch dependent processes that are hosting activities.
2405            return index;
2406        }
2407
2408        int lrui = mLruProcesses.lastIndexOf(app);
2409        if (lrui < 0) {
2410            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2411                    + what + " " + obj + " from " + srcApp);
2412            return index;
2413        }
2414
2415        if (lrui >= index) {
2416            // Don't want to cause this to move dependent processes *back* in the
2417            // list as if they were less frequently used.
2418            return index;
2419        }
2420
2421        if (lrui >= mLruProcessActivityStart) {
2422            // Don't want to touch dependent processes that are hosting activities.
2423            return index;
2424        }
2425
2426        mLruProcesses.remove(lrui);
2427        if (index > 0) {
2428            index--;
2429        }
2430        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2431                + " in LRU list: " + app);
2432        mLruProcesses.add(index, app);
2433        return index;
2434    }
2435
2436    final void removeLruProcessLocked(ProcessRecord app) {
2437        int lrui = mLruProcesses.lastIndexOf(app);
2438        if (lrui >= 0) {
2439            if (!app.killed) {
2440                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2441                Process.killProcessQuiet(app.pid);
2442                Process.killProcessGroup(app.info.uid, app.pid);
2443            }
2444            if (lrui <= mLruProcessActivityStart) {
2445                mLruProcessActivityStart--;
2446            }
2447            if (lrui <= mLruProcessServiceStart) {
2448                mLruProcessServiceStart--;
2449            }
2450            mLruProcesses.remove(lrui);
2451        }
2452    }
2453
2454    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2455            ProcessRecord client) {
2456        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2457                || app.treatLikeActivity;
2458        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2459        if (!activityChange && hasActivity) {
2460            // The process has activities, so we are only allowing activity-based adjustments
2461            // to move it.  It should be kept in the front of the list with other
2462            // processes that have activities, and we don't want those to change their
2463            // order except due to activity operations.
2464            return;
2465        }
2466
2467        mLruSeq++;
2468        final long now = SystemClock.uptimeMillis();
2469        app.lastActivityTime = now;
2470
2471        // First a quick reject: if the app is already at the position we will
2472        // put it, then there is nothing to do.
2473        if (hasActivity) {
2474            final int N = mLruProcesses.size();
2475            if (N > 0 && mLruProcesses.get(N-1) == app) {
2476                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2477                return;
2478            }
2479        } else {
2480            if (mLruProcessServiceStart > 0
2481                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2482                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2483                return;
2484            }
2485        }
2486
2487        int lrui = mLruProcesses.lastIndexOf(app);
2488
2489        if (app.persistent && lrui >= 0) {
2490            // We don't care about the position of persistent processes, as long as
2491            // they are in the list.
2492            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2493            return;
2494        }
2495
2496        /* In progress: compute new position first, so we can avoid doing work
2497           if the process is not actually going to move.  Not yet working.
2498        int addIndex;
2499        int nextIndex;
2500        boolean inActivity = false, inService = false;
2501        if (hasActivity) {
2502            // Process has activities, put it at the very tipsy-top.
2503            addIndex = mLruProcesses.size();
2504            nextIndex = mLruProcessServiceStart;
2505            inActivity = true;
2506        } else if (hasService) {
2507            // Process has services, put it at the top of the service list.
2508            addIndex = mLruProcessActivityStart;
2509            nextIndex = mLruProcessServiceStart;
2510            inActivity = true;
2511            inService = true;
2512        } else  {
2513            // Process not otherwise of interest, it goes to the top of the non-service area.
2514            addIndex = mLruProcessServiceStart;
2515            if (client != null) {
2516                int clientIndex = mLruProcesses.lastIndexOf(client);
2517                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2518                        + app);
2519                if (clientIndex >= 0 && addIndex > clientIndex) {
2520                    addIndex = clientIndex;
2521                }
2522            }
2523            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2524        }
2525
2526        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2527                + mLruProcessActivityStart + "): " + app);
2528        */
2529
2530        if (lrui >= 0) {
2531            if (lrui < mLruProcessActivityStart) {
2532                mLruProcessActivityStart--;
2533            }
2534            if (lrui < mLruProcessServiceStart) {
2535                mLruProcessServiceStart--;
2536            }
2537            /*
2538            if (addIndex > lrui) {
2539                addIndex--;
2540            }
2541            if (nextIndex > lrui) {
2542                nextIndex--;
2543            }
2544            */
2545            mLruProcesses.remove(lrui);
2546        }
2547
2548        /*
2549        mLruProcesses.add(addIndex, app);
2550        if (inActivity) {
2551            mLruProcessActivityStart++;
2552        }
2553        if (inService) {
2554            mLruProcessActivityStart++;
2555        }
2556        */
2557
2558        int nextIndex;
2559        if (hasActivity) {
2560            final int N = mLruProcesses.size();
2561            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2562                // Process doesn't have activities, but has clients with
2563                // activities...  move it up, but one below the top (the top
2564                // should always have a real activity).
2565                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2566                mLruProcesses.add(N-1, app);
2567                // To keep it from spamming the LRU list (by making a bunch of clients),
2568                // we will push down any other entries owned by the app.
2569                final int uid = app.info.uid;
2570                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2571                    ProcessRecord subProc = mLruProcesses.get(i);
2572                    if (subProc.info.uid == uid) {
2573                        // We want to push this one down the list.  If the process after
2574                        // it is for the same uid, however, don't do so, because we don't
2575                        // want them internally to be re-ordered.
2576                        if (mLruProcesses.get(i-1).info.uid != uid) {
2577                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2578                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2579                            ProcessRecord tmp = mLruProcesses.get(i);
2580                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2581                            mLruProcesses.set(i-1, tmp);
2582                            i--;
2583                        }
2584                    } else {
2585                        // A gap, we can stop here.
2586                        break;
2587                    }
2588                }
2589            } else {
2590                // Process has activities, put it at the very tipsy-top.
2591                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2592                mLruProcesses.add(app);
2593            }
2594            nextIndex = mLruProcessServiceStart;
2595        } else if (hasService) {
2596            // Process has services, put it at the top of the service list.
2597            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2598            mLruProcesses.add(mLruProcessActivityStart, app);
2599            nextIndex = mLruProcessServiceStart;
2600            mLruProcessActivityStart++;
2601        } else  {
2602            // Process not otherwise of interest, it goes to the top of the non-service area.
2603            int index = mLruProcessServiceStart;
2604            if (client != null) {
2605                // If there is a client, don't allow the process to be moved up higher
2606                // in the list than that client.
2607                int clientIndex = mLruProcesses.lastIndexOf(client);
2608                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2609                        + " when updating " + app);
2610                if (clientIndex <= lrui) {
2611                    // Don't allow the client index restriction to push it down farther in the
2612                    // list than it already is.
2613                    clientIndex = lrui;
2614                }
2615                if (clientIndex >= 0 && index > clientIndex) {
2616                    index = clientIndex;
2617                }
2618            }
2619            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2620            mLruProcesses.add(index, app);
2621            nextIndex = index-1;
2622            mLruProcessActivityStart++;
2623            mLruProcessServiceStart++;
2624        }
2625
2626        // If the app is currently using a content provider or service,
2627        // bump those processes as well.
2628        for (int j=app.connections.size()-1; j>=0; j--) {
2629            ConnectionRecord cr = app.connections.valueAt(j);
2630            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2631                    && cr.binding.service.app != null
2632                    && cr.binding.service.app.lruSeq != mLruSeq
2633                    && !cr.binding.service.app.persistent) {
2634                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2635                        "service connection", cr, app);
2636            }
2637        }
2638        for (int j=app.conProviders.size()-1; j>=0; j--) {
2639            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2640            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2641                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2642                        "provider reference", cpr, app);
2643            }
2644        }
2645    }
2646
2647    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2648        if (uid == Process.SYSTEM_UID) {
2649            // The system gets to run in any process.  If there are multiple
2650            // processes with the same uid, just pick the first (this
2651            // should never happen).
2652            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2653            if (procs == null) return null;
2654            final int N = procs.size();
2655            for (int i = 0; i < N; i++) {
2656                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2657            }
2658        }
2659        ProcessRecord proc = mProcessNames.get(processName, uid);
2660        if (false && proc != null && !keepIfLarge
2661                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2662                && proc.lastCachedPss >= 4000) {
2663            // Turn this condition on to cause killing to happen regularly, for testing.
2664            if (proc.baseProcessTracker != null) {
2665                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2666            }
2667            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2668        } else if (proc != null && !keepIfLarge
2669                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2670                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2671            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2672            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2673                if (proc.baseProcessTracker != null) {
2674                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2675                }
2676                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2677            }
2678        }
2679        return proc;
2680    }
2681
2682    void ensurePackageDexOpt(String packageName) {
2683        IPackageManager pm = AppGlobals.getPackageManager();
2684        try {
2685            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2686                mDidDexOpt = true;
2687            }
2688        } catch (RemoteException e) {
2689        }
2690    }
2691
2692    boolean isNextTransitionForward() {
2693        int transit = mWindowManager.getPendingAppTransition();
2694        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2695                || transit == AppTransition.TRANSIT_TASK_OPEN
2696                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2697    }
2698
2699    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2700            String processName, String abiOverride, int uid, Runnable crashHandler) {
2701        synchronized(this) {
2702            ApplicationInfo info = new ApplicationInfo();
2703            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2704            // For isolated processes, the former contains the parent's uid and the latter the
2705            // actual uid of the isolated process.
2706            // In the special case introduced by this method (which is, starting an isolated
2707            // process directly from the SystemServer without an actual parent app process) the
2708            // closest thing to a parent's uid is SYSTEM_UID.
2709            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2710            // the |isolated| logic in the ProcessRecord constructor.
2711            info.uid = Process.SYSTEM_UID;
2712            info.processName = processName;
2713            info.className = entryPoint;
2714            info.packageName = "android";
2715            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2716                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2717                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2718                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2719                    crashHandler);
2720            return proc != null ? proc.pid : 0;
2721        }
2722    }
2723
2724    final ProcessRecord startProcessLocked(String processName,
2725            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2726            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2727            boolean isolated, boolean keepIfLarge) {
2728        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2729                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2730                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2731                null /* crashHandler */);
2732    }
2733
2734    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2735            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2736            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2737            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2738        long startTime = SystemClock.elapsedRealtime();
2739        ProcessRecord app;
2740        if (!isolated) {
2741            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2742            checkTime(startTime, "startProcess: after getProcessRecord");
2743        } else {
2744            // If this is an isolated process, it can't re-use an existing process.
2745            app = null;
2746        }
2747        // We don't have to do anything more if:
2748        // (1) There is an existing application record; and
2749        // (2) The caller doesn't think it is dead, OR there is no thread
2750        //     object attached to it so we know it couldn't have crashed; and
2751        // (3) There is a pid assigned to it, so it is either starting or
2752        //     already running.
2753        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2754                + " app=" + app + " knownToBeDead=" + knownToBeDead
2755                + " thread=" + (app != null ? app.thread : null)
2756                + " pid=" + (app != null ? app.pid : -1));
2757        if (app != null && app.pid > 0) {
2758            if (!knownToBeDead || app.thread == null) {
2759                // We already have the app running, or are waiting for it to
2760                // come up (we have a pid but not yet its thread), so keep it.
2761                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2762                // If this is a new package in the process, add the package to the list
2763                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2764                checkTime(startTime, "startProcess: done, added package to proc");
2765                return app;
2766            }
2767
2768            // An application record is attached to a previous process,
2769            // clean it up now.
2770            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2771            checkTime(startTime, "startProcess: bad proc running, killing");
2772            Process.killProcessGroup(app.info.uid, app.pid);
2773            handleAppDiedLocked(app, true, true);
2774            checkTime(startTime, "startProcess: done killing old proc");
2775        }
2776
2777        String hostingNameStr = hostingName != null
2778                ? hostingName.flattenToShortString() : null;
2779
2780        if (!isolated) {
2781            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2782                // If we are in the background, then check to see if this process
2783                // is bad.  If so, we will just silently fail.
2784                if (mBadProcesses.get(info.processName, info.uid) != null) {
2785                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2786                            + "/" + info.processName);
2787                    return null;
2788                }
2789            } else {
2790                // When the user is explicitly starting a process, then clear its
2791                // crash count so that we won't make it bad until they see at
2792                // least one crash dialog again, and make the process good again
2793                // if it had been bad.
2794                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2795                        + "/" + info.processName);
2796                mProcessCrashTimes.remove(info.processName, info.uid);
2797                if (mBadProcesses.get(info.processName, info.uid) != null) {
2798                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2799                            UserHandle.getUserId(info.uid), info.uid,
2800                            info.processName);
2801                    mBadProcesses.remove(info.processName, info.uid);
2802                    if (app != null) {
2803                        app.bad = false;
2804                    }
2805                }
2806            }
2807        }
2808
2809        if (app == null) {
2810            checkTime(startTime, "startProcess: creating new process record");
2811            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2812            app.crashHandler = crashHandler;
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            mProcessNames.put(processName, app.uid, app);
2819            if (isolated) {
2820                mIsolatedProcesses.put(app.uid, app);
2821            }
2822            checkTime(startTime, "startProcess: done creating new process record");
2823        } else {
2824            // If this is a new package in the process, add the package to the list
2825            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2826            checkTime(startTime, "startProcess: added package to existing proc");
2827        }
2828
2829        // If the system is not ready yet, then hold off on starting this
2830        // process until it is.
2831        if (!mProcessesReady
2832                && !isAllowedWhileBooting(info)
2833                && !allowWhileBooting) {
2834            if (!mProcessesOnHold.contains(app)) {
2835                mProcessesOnHold.add(app);
2836            }
2837            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2838            checkTime(startTime, "startProcess: returning with proc on hold");
2839            return app;
2840        }
2841
2842        checkTime(startTime, "startProcess: stepping in to startProcess");
2843        startProcessLocked(
2844                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2845        checkTime(startTime, "startProcess: done starting proc!");
2846        return (app.pid != 0) ? app : null;
2847    }
2848
2849    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2850        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2851    }
2852
2853    private final void startProcessLocked(ProcessRecord app,
2854            String hostingType, String hostingNameStr) {
2855        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2856                null /* entryPoint */, null /* entryPointArgs */);
2857    }
2858
2859    private final void startProcessLocked(ProcessRecord app, String hostingType,
2860            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2861        long startTime = SystemClock.elapsedRealtime();
2862        if (app.pid > 0 && app.pid != MY_PID) {
2863            checkTime(startTime, "startProcess: removing from pids map");
2864            synchronized (mPidsSelfLocked) {
2865                mPidsSelfLocked.remove(app.pid);
2866                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2867            }
2868            checkTime(startTime, "startProcess: done removing from pids map");
2869            app.setPid(0);
2870        }
2871
2872        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2873                "startProcessLocked removing on hold: " + app);
2874        mProcessesOnHold.remove(app);
2875
2876        checkTime(startTime, "startProcess: starting to update cpu stats");
2877        updateCpuStats();
2878        checkTime(startTime, "startProcess: done updating cpu stats");
2879
2880        try {
2881            int uid = app.uid;
2882
2883            int[] gids = null;
2884            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2885            if (!app.isolated) {
2886                int[] permGids = null;
2887                try {
2888                    checkTime(startTime, "startProcess: getting gids from package manager");
2889                    final PackageManager pm = mContext.getPackageManager();
2890                    permGids = pm.getPackageGids(app.info.packageName);
2891
2892                    if (Environment.isExternalStorageEmulated()) {
2893                        checkTime(startTime, "startProcess: checking external storage perm");
2894                        if (pm.checkPermission(
2895                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2896                                app.info.packageName) == PERMISSION_GRANTED) {
2897                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2898                        } else {
2899                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2900                        }
2901                    }
2902                } catch (PackageManager.NameNotFoundException e) {
2903                    Slog.w(TAG, "Unable to retrieve gids", e);
2904                }
2905
2906                /*
2907                 * Add shared application and profile GIDs so applications can share some
2908                 * resources like shared libraries and access user-wide resources
2909                 */
2910                if (permGids == null) {
2911                    gids = new int[2];
2912                } else {
2913                    gids = new int[permGids.length + 2];
2914                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2915                }
2916                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2917                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2918            }
2919            checkTime(startTime, "startProcess: building args");
2920            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2921                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2922                        && mTopComponent != null
2923                        && app.processName.equals(mTopComponent.getPackageName())) {
2924                    uid = 0;
2925                }
2926                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2927                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2928                    uid = 0;
2929                }
2930            }
2931            int debugFlags = 0;
2932            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2933                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2934                // Also turn on CheckJNI for debuggable apps. It's quite
2935                // awkward to turn on otherwise.
2936                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2937            }
2938            // Run the app in safe mode if its manifest requests so or the
2939            // system is booted in safe mode.
2940            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2941                mSafeMode == true) {
2942                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2943            }
2944            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2945                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2946            }
2947            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2948                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2949            }
2950            if ("1".equals(SystemProperties.get("debug.assert"))) {
2951                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2952            }
2953
2954            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2955            if (requiredAbi == null) {
2956                requiredAbi = Build.SUPPORTED_ABIS[0];
2957            }
2958
2959            String instructionSet = null;
2960            if (app.info.primaryCpuAbi != null) {
2961                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2962            }
2963
2964            // Start the process.  It will either succeed and return a result containing
2965            // the PID of the new process, or else throw a RuntimeException.
2966            boolean isActivityProcess = (entryPoint == null);
2967            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2968            checkTime(startTime, "startProcess: asking zygote to start proc");
2969            Process.ProcessStartResult startResult = Process.start(entryPoint,
2970                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2971                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
2972                    app.info.dataDir, entryPointArgs);
2973            checkTime(startTime, "startProcess: returned from zygote!");
2974
2975            if (app.isolated) {
2976                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
2977            }
2978            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
2979            checkTime(startTime, "startProcess: done updating battery stats");
2980
2981            EventLog.writeEvent(EventLogTags.AM_PROC_START,
2982                    UserHandle.getUserId(uid), startResult.pid, uid,
2983                    app.processName, hostingType,
2984                    hostingNameStr != null ? hostingNameStr : "");
2985
2986            if (app.persistent) {
2987                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2988            }
2989
2990            checkTime(startTime, "startProcess: building log message");
2991            StringBuilder buf = mStringBuilder;
2992            buf.setLength(0);
2993            buf.append("Start proc ");
2994            buf.append(app.processName);
2995            if (!isActivityProcess) {
2996                buf.append(" [");
2997                buf.append(entryPoint);
2998                buf.append("]");
2999            }
3000            buf.append(" for ");
3001            buf.append(hostingType);
3002            if (hostingNameStr != null) {
3003                buf.append(" ");
3004                buf.append(hostingNameStr);
3005            }
3006            buf.append(": pid=");
3007            buf.append(startResult.pid);
3008            buf.append(" uid=");
3009            buf.append(uid);
3010            buf.append(" gids={");
3011            if (gids != null) {
3012                for (int gi=0; gi<gids.length; gi++) {
3013                    if (gi != 0) buf.append(", ");
3014                    buf.append(gids[gi]);
3015
3016                }
3017            }
3018            buf.append("}");
3019            if (requiredAbi != null) {
3020                buf.append(" abi=");
3021                buf.append(requiredAbi);
3022            }
3023            Slog.i(TAG, buf.toString());
3024            app.setPid(startResult.pid);
3025            app.usingWrapper = startResult.usingWrapper;
3026            app.removed = false;
3027            app.killed = false;
3028            app.killedByAm = false;
3029            checkTime(startTime, "startProcess: starting to update pids map");
3030            synchronized (mPidsSelfLocked) {
3031                this.mPidsSelfLocked.put(startResult.pid, app);
3032                if (isActivityProcess) {
3033                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3034                    msg.obj = app;
3035                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3036                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3037                }
3038            }
3039            checkTime(startTime, "startProcess: done updating pids map");
3040        } catch (RuntimeException e) {
3041            // XXX do better error recovery.
3042            app.setPid(0);
3043            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3044            if (app.isolated) {
3045                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3046            }
3047            Slog.e(TAG, "Failure starting process " + app.processName, e);
3048        }
3049    }
3050
3051    void updateUsageStats(ActivityRecord component, boolean resumed) {
3052        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3053        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3054        if (resumed) {
3055            if (mUsageStatsService != null) {
3056                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3057                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3058            }
3059            synchronized (stats) {
3060                stats.noteActivityResumedLocked(component.app.uid);
3061            }
3062        } else {
3063            if (mUsageStatsService != null) {
3064                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3065                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3066            }
3067            synchronized (stats) {
3068                stats.noteActivityPausedLocked(component.app.uid);
3069            }
3070        }
3071    }
3072
3073    Intent getHomeIntent() {
3074        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3075        intent.setComponent(mTopComponent);
3076        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3077            intent.addCategory(Intent.CATEGORY_HOME);
3078        }
3079        return intent;
3080    }
3081
3082    boolean startHomeActivityLocked(int userId) {
3083        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3084                && mTopAction == null) {
3085            // We are running in factory test mode, but unable to find
3086            // the factory test app, so just sit around displaying the
3087            // error message and don't try to start anything.
3088            return false;
3089        }
3090        Intent intent = getHomeIntent();
3091        ActivityInfo aInfo =
3092            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3093        if (aInfo != null) {
3094            intent.setComponent(new ComponentName(
3095                    aInfo.applicationInfo.packageName, aInfo.name));
3096            // Don't do this if the home app is currently being
3097            // instrumented.
3098            aInfo = new ActivityInfo(aInfo);
3099            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3100            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3101                    aInfo.applicationInfo.uid, true);
3102            if (app == null || app.instrumentationClass == null) {
3103                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3104                mStackSupervisor.startHomeActivity(intent, aInfo);
3105            }
3106        }
3107
3108        return true;
3109    }
3110
3111    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3112        ActivityInfo ai = null;
3113        ComponentName comp = intent.getComponent();
3114        try {
3115            if (comp != null) {
3116                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3117            } else {
3118                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3119                        intent,
3120                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3121                            flags, userId);
3122
3123                if (info != null) {
3124                    ai = info.activityInfo;
3125                }
3126            }
3127        } catch (RemoteException e) {
3128            // ignore
3129        }
3130
3131        return ai;
3132    }
3133
3134    /**
3135     * Starts the "new version setup screen" if appropriate.
3136     */
3137    void startSetupActivityLocked() {
3138        // Only do this once per boot.
3139        if (mCheckedForSetup) {
3140            return;
3141        }
3142
3143        // We will show this screen if the current one is a different
3144        // version than the last one shown, and we are not running in
3145        // low-level factory test mode.
3146        final ContentResolver resolver = mContext.getContentResolver();
3147        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3148                Settings.Global.getInt(resolver,
3149                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3150            mCheckedForSetup = true;
3151
3152            // See if we should be showing the platform update setup UI.
3153            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3154            List<ResolveInfo> ris = mContext.getPackageManager()
3155                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3156
3157            // We don't allow third party apps to replace this.
3158            ResolveInfo ri = null;
3159            for (int i=0; ris != null && i<ris.size(); i++) {
3160                if ((ris.get(i).activityInfo.applicationInfo.flags
3161                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3162                    ri = ris.get(i);
3163                    break;
3164                }
3165            }
3166
3167            if (ri != null) {
3168                String vers = ri.activityInfo.metaData != null
3169                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3170                        : null;
3171                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3172                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3173                            Intent.METADATA_SETUP_VERSION);
3174                }
3175                String lastVers = Settings.Secure.getString(
3176                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3177                if (vers != null && !vers.equals(lastVers)) {
3178                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3179                    intent.setComponent(new ComponentName(
3180                            ri.activityInfo.packageName, ri.activityInfo.name));
3181                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3182                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3183                            null);
3184                }
3185            }
3186        }
3187    }
3188
3189    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3190        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3191    }
3192
3193    void enforceNotIsolatedCaller(String caller) {
3194        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3195            throw new SecurityException("Isolated process not allowed to call " + caller);
3196        }
3197    }
3198
3199    void enforceShellRestriction(String restriction, int userHandle) {
3200        if (Binder.getCallingUid() == Process.SHELL_UID) {
3201            if (userHandle < 0
3202                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3203                throw new SecurityException("Shell does not have permission to access user "
3204                        + userHandle);
3205            }
3206        }
3207    }
3208
3209    @Override
3210    public int getFrontActivityScreenCompatMode() {
3211        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3212        synchronized (this) {
3213            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3214        }
3215    }
3216
3217    @Override
3218    public void setFrontActivityScreenCompatMode(int mode) {
3219        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3220                "setFrontActivityScreenCompatMode");
3221        synchronized (this) {
3222            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3223        }
3224    }
3225
3226    @Override
3227    public int getPackageScreenCompatMode(String packageName) {
3228        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3229        synchronized (this) {
3230            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3231        }
3232    }
3233
3234    @Override
3235    public void setPackageScreenCompatMode(String packageName, int mode) {
3236        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3237                "setPackageScreenCompatMode");
3238        synchronized (this) {
3239            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3240        }
3241    }
3242
3243    @Override
3244    public boolean getPackageAskScreenCompat(String packageName) {
3245        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3246        synchronized (this) {
3247            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3248        }
3249    }
3250
3251    @Override
3252    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3253        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3254                "setPackageAskScreenCompat");
3255        synchronized (this) {
3256            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3257        }
3258    }
3259
3260    private void dispatchProcessesChanged() {
3261        int N;
3262        synchronized (this) {
3263            N = mPendingProcessChanges.size();
3264            if (mActiveProcessChanges.length < N) {
3265                mActiveProcessChanges = new ProcessChangeItem[N];
3266            }
3267            mPendingProcessChanges.toArray(mActiveProcessChanges);
3268            mAvailProcessChanges.addAll(mPendingProcessChanges);
3269            mPendingProcessChanges.clear();
3270            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3271        }
3272
3273        int i = mProcessObservers.beginBroadcast();
3274        while (i > 0) {
3275            i--;
3276            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3277            if (observer != null) {
3278                try {
3279                    for (int j=0; j<N; j++) {
3280                        ProcessChangeItem item = mActiveProcessChanges[j];
3281                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3282                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3283                                    + item.pid + " uid=" + item.uid + ": "
3284                                    + item.foregroundActivities);
3285                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3286                                    item.foregroundActivities);
3287                        }
3288                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3289                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3290                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3291                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3292                        }
3293                    }
3294                } catch (RemoteException e) {
3295                }
3296            }
3297        }
3298        mProcessObservers.finishBroadcast();
3299    }
3300
3301    private void dispatchProcessDied(int pid, int uid) {
3302        int i = mProcessObservers.beginBroadcast();
3303        while (i > 0) {
3304            i--;
3305            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3306            if (observer != null) {
3307                try {
3308                    observer.onProcessDied(pid, uid);
3309                } catch (RemoteException e) {
3310                }
3311            }
3312        }
3313        mProcessObservers.finishBroadcast();
3314    }
3315
3316    @Override
3317    public final int startActivity(IApplicationThread caller, String callingPackage,
3318            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3319            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3320        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3321            resultWho, requestCode, startFlags, profilerInfo, options,
3322            UserHandle.getCallingUserId());
3323    }
3324
3325    @Override
3326    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3327            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3328            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3329        enforceNotIsolatedCaller("startActivity");
3330        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3331                false, ALLOW_FULL_ONLY, "startActivity", null);
3332        // TODO: Switch to user app stacks here.
3333        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3334                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3335                profilerInfo, null, null, options, userId, null, null);
3336    }
3337
3338    @Override
3339    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3340            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3341            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3342
3343        // This is very dangerous -- it allows you to perform a start activity (including
3344        // permission grants) as any app that may launch one of your own activities.  So
3345        // we will only allow this to be done from activities that are part of the core framework,
3346        // and then only when they are running as the system.
3347        final ActivityRecord sourceRecord;
3348        final int targetUid;
3349        final String targetPackage;
3350        synchronized (this) {
3351            if (resultTo == null) {
3352                throw new SecurityException("Must be called from an activity");
3353            }
3354            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3355            if (sourceRecord == null) {
3356                throw new SecurityException("Called with bad activity token: " + resultTo);
3357            }
3358            if (!sourceRecord.info.packageName.equals("android")) {
3359                throw new SecurityException(
3360                        "Must be called from an activity that is declared in the android package");
3361            }
3362            if (sourceRecord.app == null) {
3363                throw new SecurityException("Called without a process attached to activity");
3364            }
3365            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3366                // This is still okay, as long as this activity is running under the
3367                // uid of the original calling activity.
3368                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3369                    throw new SecurityException(
3370                            "Calling activity in uid " + sourceRecord.app.uid
3371                                    + " must be system uid or original calling uid "
3372                                    + sourceRecord.launchedFromUid);
3373                }
3374            }
3375            targetUid = sourceRecord.launchedFromUid;
3376            targetPackage = sourceRecord.launchedFromPackage;
3377        }
3378
3379        if (userId == UserHandle.USER_NULL) {
3380            userId = UserHandle.getUserId(sourceRecord.app.uid);
3381        }
3382
3383        // TODO: Switch to user app stacks here.
3384        try {
3385            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3386                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3387                    null, null, options, userId, null, null);
3388            return ret;
3389        } catch (SecurityException e) {
3390            // XXX need to figure out how to propagate to original app.
3391            // A SecurityException here is generally actually a fault of the original
3392            // calling activity (such as a fairly granting permissions), so propagate it
3393            // back to them.
3394            /*
3395            StringBuilder msg = new StringBuilder();
3396            msg.append("While launching");
3397            msg.append(intent.toString());
3398            msg.append(": ");
3399            msg.append(e.getMessage());
3400            */
3401            throw e;
3402        }
3403    }
3404
3405    @Override
3406    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3407            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3408            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3409        enforceNotIsolatedCaller("startActivityAndWait");
3410        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3411                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3412        WaitResult res = new WaitResult();
3413        // TODO: Switch to user app stacks here.
3414        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3415                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3416                options, userId, null, null);
3417        return res;
3418    }
3419
3420    @Override
3421    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3422            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3423            int startFlags, Configuration config, Bundle options, int userId) {
3424        enforceNotIsolatedCaller("startActivityWithConfig");
3425        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3426                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3427        // TODO: Switch to user app stacks here.
3428        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3429                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3430                null, null, config, options, userId, null, null);
3431        return ret;
3432    }
3433
3434    @Override
3435    public int startActivityIntentSender(IApplicationThread caller,
3436            IntentSender intent, Intent fillInIntent, String resolvedType,
3437            IBinder resultTo, String resultWho, int requestCode,
3438            int flagsMask, int flagsValues, Bundle options) {
3439        enforceNotIsolatedCaller("startActivityIntentSender");
3440        // Refuse possible leaked file descriptors
3441        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3442            throw new IllegalArgumentException("File descriptors passed in Intent");
3443        }
3444
3445        IIntentSender sender = intent.getTarget();
3446        if (!(sender instanceof PendingIntentRecord)) {
3447            throw new IllegalArgumentException("Bad PendingIntent object");
3448        }
3449
3450        PendingIntentRecord pir = (PendingIntentRecord)sender;
3451
3452        synchronized (this) {
3453            // If this is coming from the currently resumed activity, it is
3454            // effectively saying that app switches are allowed at this point.
3455            final ActivityStack stack = getFocusedStack();
3456            if (stack.mResumedActivity != null &&
3457                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3458                mAppSwitchesAllowedTime = 0;
3459            }
3460        }
3461        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3462                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3463        return ret;
3464    }
3465
3466    @Override
3467    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3468            Intent intent, String resolvedType, IVoiceInteractionSession session,
3469            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3470            Bundle options, int userId) {
3471        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3472                != PackageManager.PERMISSION_GRANTED) {
3473            String msg = "Permission Denial: startVoiceActivity() from pid="
3474                    + Binder.getCallingPid()
3475                    + ", uid=" + Binder.getCallingUid()
3476                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3477            Slog.w(TAG, msg);
3478            throw new SecurityException(msg);
3479        }
3480        if (session == null || interactor == null) {
3481            throw new NullPointerException("null session or interactor");
3482        }
3483        userId = handleIncomingUser(callingPid, callingUid, userId,
3484                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3485        // TODO: Switch to user app stacks here.
3486        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3487                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3488                null, options, userId, null, null);
3489    }
3490
3491    @Override
3492    public boolean startNextMatchingActivity(IBinder callingActivity,
3493            Intent intent, Bundle options) {
3494        // Refuse possible leaked file descriptors
3495        if (intent != null && intent.hasFileDescriptors() == true) {
3496            throw new IllegalArgumentException("File descriptors passed in Intent");
3497        }
3498
3499        synchronized (this) {
3500            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3501            if (r == null) {
3502                ActivityOptions.abort(options);
3503                return false;
3504            }
3505            if (r.app == null || r.app.thread == null) {
3506                // The caller is not running...  d'oh!
3507                ActivityOptions.abort(options);
3508                return false;
3509            }
3510            intent = new Intent(intent);
3511            // The caller is not allowed to change the data.
3512            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3513            // And we are resetting to find the next component...
3514            intent.setComponent(null);
3515
3516            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3517
3518            ActivityInfo aInfo = null;
3519            try {
3520                List<ResolveInfo> resolves =
3521                    AppGlobals.getPackageManager().queryIntentActivities(
3522                            intent, r.resolvedType,
3523                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3524                            UserHandle.getCallingUserId());
3525
3526                // Look for the original activity in the list...
3527                final int N = resolves != null ? resolves.size() : 0;
3528                for (int i=0; i<N; i++) {
3529                    ResolveInfo rInfo = resolves.get(i);
3530                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3531                            && rInfo.activityInfo.name.equals(r.info.name)) {
3532                        // We found the current one...  the next matching is
3533                        // after it.
3534                        i++;
3535                        if (i<N) {
3536                            aInfo = resolves.get(i).activityInfo;
3537                        }
3538                        if (debug) {
3539                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3540                                    + "/" + r.info.name);
3541                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3542                                    + "/" + aInfo.name);
3543                        }
3544                        break;
3545                    }
3546                }
3547            } catch (RemoteException e) {
3548            }
3549
3550            if (aInfo == null) {
3551                // Nobody who is next!
3552                ActivityOptions.abort(options);
3553                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3554                return false;
3555            }
3556
3557            intent.setComponent(new ComponentName(
3558                    aInfo.applicationInfo.packageName, aInfo.name));
3559            intent.setFlags(intent.getFlags()&~(
3560                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3561                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3562                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3563                    Intent.FLAG_ACTIVITY_NEW_TASK));
3564
3565            // Okay now we need to start the new activity, replacing the
3566            // currently running activity.  This is a little tricky because
3567            // we want to start the new one as if the current one is finished,
3568            // but not finish the current one first so that there is no flicker.
3569            // And thus...
3570            final boolean wasFinishing = r.finishing;
3571            r.finishing = true;
3572
3573            // Propagate reply information over to the new activity.
3574            final ActivityRecord resultTo = r.resultTo;
3575            final String resultWho = r.resultWho;
3576            final int requestCode = r.requestCode;
3577            r.resultTo = null;
3578            if (resultTo != null) {
3579                resultTo.removeResultsLocked(r, resultWho, requestCode);
3580            }
3581
3582            final long origId = Binder.clearCallingIdentity();
3583            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3584                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3585                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3586                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3587            Binder.restoreCallingIdentity(origId);
3588
3589            r.finishing = wasFinishing;
3590            if (res != ActivityManager.START_SUCCESS) {
3591                return false;
3592            }
3593            return true;
3594        }
3595    }
3596
3597    @Override
3598    public final int startActivityFromRecents(int taskId, Bundle options) {
3599        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3600            String msg = "Permission Denial: startActivityFromRecents called without " +
3601                    START_TASKS_FROM_RECENTS;
3602            Slog.w(TAG, msg);
3603            throw new SecurityException(msg);
3604        }
3605        return startActivityFromRecentsInner(taskId, options);
3606    }
3607
3608    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3609        final TaskRecord task;
3610        final int callingUid;
3611        final String callingPackage;
3612        final Intent intent;
3613        final int userId;
3614        synchronized (this) {
3615            task = recentTaskForIdLocked(taskId);
3616            if (task == null) {
3617                throw new IllegalArgumentException("Task " + taskId + " not found.");
3618            }
3619            callingUid = task.mCallingUid;
3620            callingPackage = task.mCallingPackage;
3621            intent = task.intent;
3622            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3623            userId = task.userId;
3624        }
3625        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3626                options, userId, null, task);
3627    }
3628
3629    final int startActivityInPackage(int uid, String callingPackage,
3630            Intent intent, String resolvedType, IBinder resultTo,
3631            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3632            IActivityContainer container, TaskRecord inTask) {
3633
3634        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3635                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3636
3637        // TODO: Switch to user app stacks here.
3638        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3639                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3640                null, null, null, options, userId, container, inTask);
3641        return ret;
3642    }
3643
3644    @Override
3645    public final int startActivities(IApplicationThread caller, String callingPackage,
3646            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3647            int userId) {
3648        enforceNotIsolatedCaller("startActivities");
3649        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3650                false, ALLOW_FULL_ONLY, "startActivity", null);
3651        // TODO: Switch to user app stacks here.
3652        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3653                resolvedTypes, resultTo, options, userId);
3654        return ret;
3655    }
3656
3657    final int startActivitiesInPackage(int uid, String callingPackage,
3658            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3659            Bundle options, int userId) {
3660
3661        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3662                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3663        // TODO: Switch to user app stacks here.
3664        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3665                resultTo, options, userId);
3666        return ret;
3667    }
3668
3669    //explicitly remove thd old information in mRecentTasks when removing existing user.
3670    private void removeRecentTasksForUserLocked(int userId) {
3671        if(userId <= 0) {
3672            Slog.i(TAG, "Can't remove recent task on user " + userId);
3673            return;
3674        }
3675
3676        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3677            TaskRecord tr = mRecentTasks.get(i);
3678            if (tr.userId == userId) {
3679                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3680                        + " when finishing user" + userId);
3681                mRecentTasks.remove(i);
3682                tr.removedFromRecents();
3683            }
3684        }
3685
3686        // Remove tasks from persistent storage.
3687        notifyTaskPersisterLocked(null, true);
3688    }
3689
3690    // Sort by taskId
3691    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3692        @Override
3693        public int compare(TaskRecord lhs, TaskRecord rhs) {
3694            return rhs.taskId - lhs.taskId;
3695        }
3696    };
3697
3698    // Extract the affiliates of the chain containing mRecentTasks[start].
3699    private int processNextAffiliateChainLocked(int start) {
3700        final TaskRecord startTask = mRecentTasks.get(start);
3701        final int affiliateId = startTask.mAffiliatedTaskId;
3702
3703        // Quick identification of isolated tasks. I.e. those not launched behind.
3704        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3705                startTask.mNextAffiliate == null) {
3706            // There is still a slim chance that there are other tasks that point to this task
3707            // and that the chain is so messed up that this task no longer points to them but
3708            // the gain of this optimization outweighs the risk.
3709            startTask.inRecents = true;
3710            return start + 1;
3711        }
3712
3713        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3714        mTmpRecents.clear();
3715        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3716            final TaskRecord task = mRecentTasks.get(i);
3717            if (task.mAffiliatedTaskId == affiliateId) {
3718                mRecentTasks.remove(i);
3719                mTmpRecents.add(task);
3720            }
3721        }
3722
3723        // Sort them all by taskId. That is the order they were create in and that order will
3724        // always be correct.
3725        Collections.sort(mTmpRecents, mTaskRecordComparator);
3726
3727        // Go through and fix up the linked list.
3728        // The first one is the end of the chain and has no next.
3729        final TaskRecord first = mTmpRecents.get(0);
3730        first.inRecents = true;
3731        if (first.mNextAffiliate != null) {
3732            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3733            first.setNextAffiliate(null);
3734            notifyTaskPersisterLocked(first, false);
3735        }
3736        // Everything in the middle is doubly linked from next to prev.
3737        final int tmpSize = mTmpRecents.size();
3738        for (int i = 0; i < tmpSize - 1; ++i) {
3739            final TaskRecord next = mTmpRecents.get(i);
3740            final TaskRecord prev = mTmpRecents.get(i + 1);
3741            if (next.mPrevAffiliate != prev) {
3742                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3743                        " setting prev=" + prev);
3744                next.setPrevAffiliate(prev);
3745                notifyTaskPersisterLocked(next, false);
3746            }
3747            if (prev.mNextAffiliate != next) {
3748                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3749                        " setting next=" + next);
3750                prev.setNextAffiliate(next);
3751                notifyTaskPersisterLocked(prev, false);
3752            }
3753            prev.inRecents = true;
3754        }
3755        // The last one is the beginning of the list and has no prev.
3756        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3757        if (last.mPrevAffiliate != null) {
3758            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3759            last.setPrevAffiliate(null);
3760            notifyTaskPersisterLocked(last, false);
3761        }
3762
3763        // Insert the group back into mRecentTasks at start.
3764        mRecentTasks.addAll(start, mTmpRecents);
3765
3766        // Let the caller know where we left off.
3767        return start + tmpSize;
3768    }
3769
3770    /**
3771     * Update the recent tasks lists: make sure tasks should still be here (their
3772     * applications / activities still exist), update their availability, fixup ordering
3773     * of affiliations.
3774     */
3775    void cleanupRecentTasksLocked(int userId) {
3776        if (mRecentTasks == null) {
3777            // Happens when called from the packagemanager broadcast before boot.
3778            return;
3779        }
3780
3781        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3782        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3783        final IPackageManager pm = AppGlobals.getPackageManager();
3784        final ActivityInfo dummyAct = new ActivityInfo();
3785        final ApplicationInfo dummyApp = new ApplicationInfo();
3786
3787        int N = mRecentTasks.size();
3788
3789        int[] users = userId == UserHandle.USER_ALL
3790                ? getUsersLocked() : new int[] { userId };
3791        for (int user : users) {
3792            for (int i = 0; i < N; i++) {
3793                TaskRecord task = mRecentTasks.get(i);
3794                if (task.userId != user) {
3795                    // Only look at tasks for the user ID of interest.
3796                    continue;
3797                }
3798                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3799                    // This situation is broken, and we should just get rid of it now.
3800                    mRecentTasks.remove(i);
3801                    task.removedFromRecents();
3802                    i--;
3803                    N--;
3804                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3805                    continue;
3806                }
3807                // Check whether this activity is currently available.
3808                if (task.realActivity != null) {
3809                    ActivityInfo ai = availActCache.get(task.realActivity);
3810                    if (ai == null) {
3811                        try {
3812                            ai = pm.getActivityInfo(task.realActivity,
3813                                    PackageManager.GET_UNINSTALLED_PACKAGES
3814                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3815                        } catch (RemoteException e) {
3816                            // Will never happen.
3817                            continue;
3818                        }
3819                        if (ai == null) {
3820                            ai = dummyAct;
3821                        }
3822                        availActCache.put(task.realActivity, ai);
3823                    }
3824                    if (ai == dummyAct) {
3825                        // This could be either because the activity no longer exists, or the
3826                        // app is temporarily gone.  For the former we want to remove the recents
3827                        // entry; for the latter we want to mark it as unavailable.
3828                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3829                        if (app == null) {
3830                            try {
3831                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3832                                        PackageManager.GET_UNINSTALLED_PACKAGES
3833                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3834                            } catch (RemoteException e) {
3835                                // Will never happen.
3836                                continue;
3837                            }
3838                            if (app == null) {
3839                                app = dummyApp;
3840                            }
3841                            availAppCache.put(task.realActivity.getPackageName(), app);
3842                        }
3843                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3844                            // Doesn't exist any more!  Good-bye.
3845                            mRecentTasks.remove(i);
3846                            task.removedFromRecents();
3847                            i--;
3848                            N--;
3849                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3850                            continue;
3851                        } else {
3852                            // Otherwise just not available for now.
3853                            if (task.isAvailable) {
3854                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3855                                        + task);
3856                            }
3857                            task.isAvailable = false;
3858                        }
3859                    } else {
3860                        if (!ai.enabled || !ai.applicationInfo.enabled
3861                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3862                            if (task.isAvailable) {
3863                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3864                                        + task + " (enabled=" + ai.enabled + "/"
3865                                        + ai.applicationInfo.enabled +  " flags="
3866                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3867                            }
3868                            task.isAvailable = false;
3869                        } else {
3870                            if (!task.isAvailable) {
3871                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3872                                        + task);
3873                            }
3874                            task.isAvailable = true;
3875                        }
3876                    }
3877                }
3878            }
3879        }
3880
3881        // Verify the affiliate chain for each task.
3882        for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3883        }
3884
3885        mTmpRecents.clear();
3886        // mRecentTasks is now in sorted, affiliated order.
3887    }
3888
3889    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3890        int N = mRecentTasks.size();
3891        TaskRecord top = task;
3892        int topIndex = taskIndex;
3893        while (top.mNextAffiliate != null && topIndex > 0) {
3894            top = top.mNextAffiliate;
3895            topIndex--;
3896        }
3897        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3898                + topIndex + " from intial " + taskIndex);
3899        // Find the end of the chain, doing a sanity check along the way.
3900        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3901        int endIndex = topIndex;
3902        TaskRecord prev = top;
3903        while (endIndex < N) {
3904            TaskRecord cur = mRecentTasks.get(endIndex);
3905            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3906                    + endIndex + " " + cur);
3907            if (cur == top) {
3908                // Verify start of the chain.
3909                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3910                    Slog.wtf(TAG, "Bad chain @" + endIndex
3911                            + ": first task has next affiliate: " + prev);
3912                    sane = false;
3913                    break;
3914                }
3915            } else {
3916                // Verify middle of the chain's next points back to the one before.
3917                if (cur.mNextAffiliate != prev
3918                        || cur.mNextAffiliateTaskId != prev.taskId) {
3919                    Slog.wtf(TAG, "Bad chain @" + endIndex
3920                            + ": middle task " + cur + " @" + endIndex
3921                            + " has bad next affiliate "
3922                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3923                            + ", expected " + prev);
3924                    sane = false;
3925                    break;
3926                }
3927            }
3928            if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3929                // Chain ends here.
3930                if (cur.mPrevAffiliate != null) {
3931                    Slog.wtf(TAG, "Bad chain @" + endIndex
3932                            + ": last task " + cur + " has previous affiliate "
3933                            + cur.mPrevAffiliate);
3934                    sane = false;
3935                }
3936                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3937                break;
3938            } else {
3939                // Verify middle of the chain's prev points to a valid item.
3940                if (cur.mPrevAffiliate == null) {
3941                    Slog.wtf(TAG, "Bad chain @" + endIndex
3942                            + ": task " + cur + " has previous affiliate "
3943                            + cur.mPrevAffiliate + " but should be id "
3944                            + cur.mPrevAffiliate);
3945                    sane = false;
3946                    break;
3947                }
3948            }
3949            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3950                Slog.wtf(TAG, "Bad chain @" + endIndex
3951                        + ": task " + cur + " has affiliated id "
3952                        + cur.mAffiliatedTaskId + " but should be "
3953                        + task.mAffiliatedTaskId);
3954                sane = false;
3955                break;
3956            }
3957            prev = cur;
3958            endIndex++;
3959            if (endIndex >= N) {
3960                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3961                        + ": last task " + prev);
3962                sane = false;
3963                break;
3964            }
3965        }
3966        if (sane) {
3967            if (endIndex < taskIndex) {
3968                Slog.wtf(TAG, "Bad chain @" + endIndex
3969                        + ": did not extend to task " + task + " @" + taskIndex);
3970                sane = false;
3971            }
3972        }
3973        if (sane) {
3974            // All looks good, we can just move all of the affiliated tasks
3975            // to the top.
3976            for (int i=topIndex; i<=endIndex; i++) {
3977                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
3978                        + " from " + i + " to " + (i-topIndex));
3979                TaskRecord cur = mRecentTasks.remove(i);
3980                mRecentTasks.add(i-topIndex, cur);
3981            }
3982            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
3983                    + " to " + endIndex);
3984            return true;
3985        }
3986
3987        // Whoops, couldn't do it.
3988        return false;
3989    }
3990
3991    final void addRecentTaskLocked(TaskRecord task) {
3992        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
3993                || task.mNextAffiliateTaskId != INVALID_TASK_ID
3994                || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
3995
3996        int N = mRecentTasks.size();
3997        // Quick case: check if the top-most recent task is the same.
3998        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
3999            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4000            return;
4001        }
4002        // Another quick case: check if this is part of a set of affiliated
4003        // tasks that are at the top.
4004        if (isAffiliated && N > 0 && task.inRecents
4005                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4006            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4007                    + " at top when adding " + task);
4008            return;
4009        }
4010        // Another quick case: never add voice sessions.
4011        if (task.voiceSession != null) {
4012            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4013            return;
4014        }
4015
4016        boolean needAffiliationFix = false;
4017
4018        // Slightly less quick case: the task is already in recents, so all we need
4019        // to do is move it.
4020        if (task.inRecents) {
4021            int taskIndex = mRecentTasks.indexOf(task);
4022            if (taskIndex >= 0) {
4023                if (!isAffiliated) {
4024                    // Simple case: this is not an affiliated task, so we just move it to the front.
4025                    mRecentTasks.remove(taskIndex);
4026                    mRecentTasks.add(0, task);
4027                    notifyTaskPersisterLocked(task, false);
4028                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4029                            + " from " + taskIndex);
4030                    return;
4031                } else {
4032                    // More complicated: need to keep all affiliated tasks together.
4033                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4034                        // All went well.
4035                        return;
4036                    }
4037
4038                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4039                    // everything and then go through our general path of adding a new task.
4040                    needAffiliationFix = true;
4041                }
4042            } else {
4043                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4044                needAffiliationFix = true;
4045            }
4046        }
4047
4048        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4049        trimRecentsForTaskLocked(task, true);
4050
4051        N = mRecentTasks.size();
4052        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4053            final TaskRecord tr = mRecentTasks.remove(N - 1);
4054            tr.removedFromRecents();
4055            N--;
4056        }
4057        task.inRecents = true;
4058        if (!isAffiliated || needAffiliationFix) {
4059            // If this is a simple non-affiliated task, or we had some failure trying to
4060            // handle it as part of an affilated task, then just place it at the top.
4061            mRecentTasks.add(0, task);
4062        } else if (isAffiliated) {
4063            // If this is a new affiliated task, then move all of the affiliated tasks
4064            // to the front and insert this new one.
4065            TaskRecord other = task.mNextAffiliate;
4066            if (other == null) {
4067                other = task.mPrevAffiliate;
4068            }
4069            if (other != null) {
4070                int otherIndex = mRecentTasks.indexOf(other);
4071                if (otherIndex >= 0) {
4072                    // Insert new task at appropriate location.
4073                    int taskIndex;
4074                    if (other == task.mNextAffiliate) {
4075                        // We found the index of our next affiliation, which is who is
4076                        // before us in the list, so add after that point.
4077                        taskIndex = otherIndex+1;
4078                    } else {
4079                        // We found the index of our previous affiliation, which is who is
4080                        // after us in the list, so add at their position.
4081                        taskIndex = otherIndex;
4082                    }
4083                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4084                            + taskIndex + ": " + task);
4085                    mRecentTasks.add(taskIndex, task);
4086
4087                    // Now move everything to the front.
4088                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4089                        // All went well.
4090                        return;
4091                    }
4092
4093                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4094                    // everything and then go through our general path of adding a new task.
4095                    needAffiliationFix = true;
4096                } else {
4097                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4098                            + other);
4099                    needAffiliationFix = true;
4100                }
4101            } else {
4102                if (DEBUG_RECENTS) Slog.d(TAG,
4103                        "addRecent: adding affiliated task without next/prev:" + task);
4104                needAffiliationFix = true;
4105            }
4106        }
4107        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4108
4109        if (needAffiliationFix) {
4110            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4111            cleanupRecentTasksLocked(task.userId);
4112        }
4113    }
4114
4115    /**
4116     * If needed, remove oldest existing entries in recents that are for the same kind
4117     * of task as the given one.
4118     */
4119    int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4120        int N = mRecentTasks.size();
4121        final Intent intent = task.intent;
4122        final boolean document = intent != null && intent.isDocument();
4123
4124        int maxRecents = task.maxRecents - 1;
4125        for (int i=0; i<N; i++) {
4126            final TaskRecord tr = mRecentTasks.get(i);
4127            if (task != tr) {
4128                if (task.userId != tr.userId) {
4129                    continue;
4130                }
4131                if (i > MAX_RECENT_BITMAPS) {
4132                    tr.freeLastThumbnail();
4133                }
4134                final Intent trIntent = tr.intent;
4135                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4136                    (intent == null || !intent.filterEquals(trIntent))) {
4137                    continue;
4138                }
4139                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4140                if (document && trIsDocument) {
4141                    // These are the same document activity (not necessarily the same doc).
4142                    if (maxRecents > 0) {
4143                        --maxRecents;
4144                        continue;
4145                    }
4146                    // Hit the maximum number of documents for this task. Fall through
4147                    // and remove this document from recents.
4148                } else if (document || trIsDocument) {
4149                    // Only one of these is a document. Not the droid we're looking for.
4150                    continue;
4151                }
4152            }
4153
4154            if (!doTrim) {
4155                // If the caller is not actually asking for a trim, just tell them we reached
4156                // a point where the trim would happen.
4157                return i;
4158            }
4159
4160            // Either task and tr are the same or, their affinities match or their intents match
4161            // and neither of them is a document, or they are documents using the same activity
4162            // and their maxRecents has been reached.
4163            tr.disposeThumbnail();
4164            mRecentTasks.remove(i);
4165            if (task != tr) {
4166                tr.removedFromRecents();
4167            }
4168            i--;
4169            N--;
4170            if (task.intent == null) {
4171                // If the new recent task we are adding is not fully
4172                // specified, then replace it with the existing recent task.
4173                task = tr;
4174            }
4175            notifyTaskPersisterLocked(tr, false);
4176        }
4177
4178        return -1;
4179    }
4180
4181    @Override
4182    public void reportActivityFullyDrawn(IBinder token) {
4183        synchronized (this) {
4184            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4185            if (r == null) {
4186                return;
4187            }
4188            r.reportFullyDrawnLocked();
4189        }
4190    }
4191
4192    @Override
4193    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4194        synchronized (this) {
4195            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4196            if (r == null) {
4197                return;
4198            }
4199            final long origId = Binder.clearCallingIdentity();
4200            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4201            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4202                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4203            if (config != null) {
4204                r.frozenBeforeDestroy = true;
4205                if (!updateConfigurationLocked(config, r, false, false)) {
4206                    mStackSupervisor.resumeTopActivitiesLocked();
4207                }
4208            }
4209            Binder.restoreCallingIdentity(origId);
4210        }
4211    }
4212
4213    @Override
4214    public int getRequestedOrientation(IBinder token) {
4215        synchronized (this) {
4216            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4217            if (r == null) {
4218                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4219            }
4220            return mWindowManager.getAppOrientation(r.appToken);
4221        }
4222    }
4223
4224    /**
4225     * This is the internal entry point for handling Activity.finish().
4226     *
4227     * @param token The Binder token referencing the Activity we want to finish.
4228     * @param resultCode Result code, if any, from this Activity.
4229     * @param resultData Result data (Intent), if any, from this Activity.
4230     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4231     *            the root Activity in the task.
4232     *
4233     * @return Returns true if the activity successfully finished, or false if it is still running.
4234     */
4235    @Override
4236    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4237            boolean finishTask) {
4238        // Refuse possible leaked file descriptors
4239        if (resultData != null && resultData.hasFileDescriptors() == true) {
4240            throw new IllegalArgumentException("File descriptors passed in Intent");
4241        }
4242
4243        synchronized(this) {
4244            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4245            if (r == null) {
4246                return true;
4247            }
4248            // Keep track of the root activity of the task before we finish it
4249            TaskRecord tr = r.task;
4250            ActivityRecord rootR = tr.getRootActivity();
4251            if (rootR == null) {
4252                Slog.w(TAG, "Finishing task with all activities already finished");
4253            }
4254            // Do not allow task to finish in Lock Task mode.
4255            if (tr == mStackSupervisor.mLockTaskModeTask) {
4256                if (rootR == r) {
4257                    Slog.i(TAG, "Not finishing task in lock task mode");
4258                    mStackSupervisor.showLockTaskToast();
4259                    return false;
4260                }
4261            }
4262            if (mController != null) {
4263                // Find the first activity that is not finishing.
4264                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4265                if (next != null) {
4266                    // ask watcher if this is allowed
4267                    boolean resumeOK = true;
4268                    try {
4269                        resumeOK = mController.activityResuming(next.packageName);
4270                    } catch (RemoteException e) {
4271                        mController = null;
4272                        Watchdog.getInstance().setActivityController(null);
4273                    }
4274
4275                    if (!resumeOK) {
4276                        Slog.i(TAG, "Not finishing activity because controller resumed");
4277                        return false;
4278                    }
4279                }
4280            }
4281            final long origId = Binder.clearCallingIdentity();
4282            try {
4283                boolean res;
4284                if (finishTask && r == rootR) {
4285                    // If requested, remove the task that is associated to this activity only if it
4286                    // was the root activity in the task. The result code and data is ignored
4287                    // because we don't support returning them across task boundaries.
4288                    res = removeTaskByIdLocked(tr.taskId, false);
4289                    if (!res) {
4290                        Slog.i(TAG, "Removing task failed to finish activity");
4291                    }
4292                } else {
4293                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4294                            resultData, "app-request", true);
4295                    if (!res) {
4296                        Slog.i(TAG, "Failed to finish by app-request");
4297                    }
4298                }
4299                return res;
4300            } finally {
4301                Binder.restoreCallingIdentity(origId);
4302            }
4303        }
4304    }
4305
4306    @Override
4307    public final void finishHeavyWeightApp() {
4308        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4309                != PackageManager.PERMISSION_GRANTED) {
4310            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4311                    + Binder.getCallingPid()
4312                    + ", uid=" + Binder.getCallingUid()
4313                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4314            Slog.w(TAG, msg);
4315            throw new SecurityException(msg);
4316        }
4317
4318        synchronized(this) {
4319            if (mHeavyWeightProcess == null) {
4320                return;
4321            }
4322
4323            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4324                    mHeavyWeightProcess.activities);
4325            for (int i=0; i<activities.size(); i++) {
4326                ActivityRecord r = activities.get(i);
4327                if (!r.finishing) {
4328                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4329                            null, "finish-heavy", true);
4330                }
4331            }
4332
4333            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4334                    mHeavyWeightProcess.userId, 0));
4335            mHeavyWeightProcess = null;
4336        }
4337    }
4338
4339    @Override
4340    public void crashApplication(int uid, int initialPid, String packageName,
4341            String message) {
4342        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4343                != PackageManager.PERMISSION_GRANTED) {
4344            String msg = "Permission Denial: crashApplication() from pid="
4345                    + Binder.getCallingPid()
4346                    + ", uid=" + Binder.getCallingUid()
4347                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4348            Slog.w(TAG, msg);
4349            throw new SecurityException(msg);
4350        }
4351
4352        synchronized(this) {
4353            ProcessRecord proc = null;
4354
4355            // Figure out which process to kill.  We don't trust that initialPid
4356            // still has any relation to current pids, so must scan through the
4357            // list.
4358            synchronized (mPidsSelfLocked) {
4359                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4360                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4361                    if (p.uid != uid) {
4362                        continue;
4363                    }
4364                    if (p.pid == initialPid) {
4365                        proc = p;
4366                        break;
4367                    }
4368                    if (p.pkgList.containsKey(packageName)) {
4369                        proc = p;
4370                    }
4371                }
4372            }
4373
4374            if (proc == null) {
4375                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4376                        + " initialPid=" + initialPid
4377                        + " packageName=" + packageName);
4378                return;
4379            }
4380
4381            if (proc.thread != null) {
4382                if (proc.pid == Process.myPid()) {
4383                    Log.w(TAG, "crashApplication: trying to crash self!");
4384                    return;
4385                }
4386                long ident = Binder.clearCallingIdentity();
4387                try {
4388                    proc.thread.scheduleCrash(message);
4389                } catch (RemoteException e) {
4390                }
4391                Binder.restoreCallingIdentity(ident);
4392            }
4393        }
4394    }
4395
4396    @Override
4397    public final void finishSubActivity(IBinder token, String resultWho,
4398            int requestCode) {
4399        synchronized(this) {
4400            final long origId = Binder.clearCallingIdentity();
4401            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4402            if (r != null) {
4403                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4404            }
4405            Binder.restoreCallingIdentity(origId);
4406        }
4407    }
4408
4409    @Override
4410    public boolean finishActivityAffinity(IBinder token) {
4411        synchronized(this) {
4412            final long origId = Binder.clearCallingIdentity();
4413            try {
4414                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4415
4416                ActivityRecord rootR = r.task.getRootActivity();
4417                // Do not allow task to finish in Lock Task mode.
4418                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4419                    if (rootR == r) {
4420                        mStackSupervisor.showLockTaskToast();
4421                        return false;
4422                    }
4423                }
4424                boolean res = false;
4425                if (r != null) {
4426                    res = r.task.stack.finishActivityAffinityLocked(r);
4427                }
4428                return res;
4429            } finally {
4430                Binder.restoreCallingIdentity(origId);
4431            }
4432        }
4433    }
4434
4435    @Override
4436    public void finishVoiceTask(IVoiceInteractionSession session) {
4437        synchronized(this) {
4438            final long origId = Binder.clearCallingIdentity();
4439            try {
4440                mStackSupervisor.finishVoiceTask(session);
4441            } finally {
4442                Binder.restoreCallingIdentity(origId);
4443            }
4444        }
4445
4446    }
4447
4448    @Override
4449    public boolean releaseActivityInstance(IBinder token) {
4450        synchronized(this) {
4451            final long origId = Binder.clearCallingIdentity();
4452            try {
4453                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454                if (r.task == null || r.task.stack == null) {
4455                    return false;
4456                }
4457                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4458            } finally {
4459                Binder.restoreCallingIdentity(origId);
4460            }
4461        }
4462    }
4463
4464    @Override
4465    public void releaseSomeActivities(IApplicationThread appInt) {
4466        synchronized(this) {
4467            final long origId = Binder.clearCallingIdentity();
4468            try {
4469                ProcessRecord app = getRecordForAppLocked(appInt);
4470                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4471            } finally {
4472                Binder.restoreCallingIdentity(origId);
4473            }
4474        }
4475    }
4476
4477    @Override
4478    public boolean willActivityBeVisible(IBinder token) {
4479        synchronized(this) {
4480            ActivityStack stack = ActivityRecord.getStackLocked(token);
4481            if (stack != null) {
4482                return stack.willActivityBeVisibleLocked(token);
4483            }
4484            return false;
4485        }
4486    }
4487
4488    @Override
4489    public void overridePendingTransition(IBinder token, String packageName,
4490            int enterAnim, int exitAnim) {
4491        synchronized(this) {
4492            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4493            if (self == null) {
4494                return;
4495            }
4496
4497            final long origId = Binder.clearCallingIdentity();
4498
4499            if (self.state == ActivityState.RESUMED
4500                    || self.state == ActivityState.PAUSING) {
4501                mWindowManager.overridePendingAppTransition(packageName,
4502                        enterAnim, exitAnim, null);
4503            }
4504
4505            Binder.restoreCallingIdentity(origId);
4506        }
4507    }
4508
4509    /**
4510     * Main function for removing an existing process from the activity manager
4511     * as a result of that process going away.  Clears out all connections
4512     * to the process.
4513     */
4514    private final void handleAppDiedLocked(ProcessRecord app,
4515            boolean restarting, boolean allowRestart) {
4516        int pid = app.pid;
4517        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4518        if (!kept && !restarting) {
4519            removeLruProcessLocked(app);
4520            if (pid > 0) {
4521                ProcessList.remove(pid);
4522            }
4523        }
4524
4525        if (mProfileProc == app) {
4526            clearProfilerLocked();
4527        }
4528
4529        // Remove this application's activities from active lists.
4530        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4531
4532        app.activities.clear();
4533
4534        if (app.instrumentationClass != null) {
4535            Slog.w(TAG, "Crash of app " + app.processName
4536                  + " running instrumentation " + app.instrumentationClass);
4537            Bundle info = new Bundle();
4538            info.putString("shortMsg", "Process crashed.");
4539            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4540        }
4541
4542        if (!restarting) {
4543            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4544                // If there was nothing to resume, and we are not already
4545                // restarting this process, but there is a visible activity that
4546                // is hosted by the process...  then make sure all visible
4547                // activities are running, taking care of restarting this
4548                // process.
4549                if (hasVisibleActivities) {
4550                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4551                }
4552            }
4553        }
4554    }
4555
4556    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4557        IBinder threadBinder = thread.asBinder();
4558        // Find the application record.
4559        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4560            ProcessRecord rec = mLruProcesses.get(i);
4561            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4562                return i;
4563            }
4564        }
4565        return -1;
4566    }
4567
4568    final ProcessRecord getRecordForAppLocked(
4569            IApplicationThread thread) {
4570        if (thread == null) {
4571            return null;
4572        }
4573
4574        int appIndex = getLRURecordIndexForAppLocked(thread);
4575        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4576    }
4577
4578    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4579        // If there are no longer any background processes running,
4580        // and the app that died was not running instrumentation,
4581        // then tell everyone we are now low on memory.
4582        boolean haveBg = false;
4583        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4584            ProcessRecord rec = mLruProcesses.get(i);
4585            if (rec.thread != null
4586                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4587                haveBg = true;
4588                break;
4589            }
4590        }
4591
4592        if (!haveBg) {
4593            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4594            if (doReport) {
4595                long now = SystemClock.uptimeMillis();
4596                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4597                    doReport = false;
4598                } else {
4599                    mLastMemUsageReportTime = now;
4600                }
4601            }
4602            final ArrayList<ProcessMemInfo> memInfos
4603                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4604            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4605            long now = SystemClock.uptimeMillis();
4606            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4607                ProcessRecord rec = mLruProcesses.get(i);
4608                if (rec == dyingProc || rec.thread == null) {
4609                    continue;
4610                }
4611                if (doReport) {
4612                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4613                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4614                }
4615                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4616                    // The low memory report is overriding any current
4617                    // state for a GC request.  Make sure to do
4618                    // heavy/important/visible/foreground processes first.
4619                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4620                        rec.lastRequestedGc = 0;
4621                    } else {
4622                        rec.lastRequestedGc = rec.lastLowMemory;
4623                    }
4624                    rec.reportLowMemory = true;
4625                    rec.lastLowMemory = now;
4626                    mProcessesToGc.remove(rec);
4627                    addProcessToGcListLocked(rec);
4628                }
4629            }
4630            if (doReport) {
4631                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4632                mHandler.sendMessage(msg);
4633            }
4634            scheduleAppGcsLocked();
4635        }
4636    }
4637
4638    final void appDiedLocked(ProcessRecord app) {
4639       appDiedLocked(app, app.pid, app.thread);
4640    }
4641
4642    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4643        // First check if this ProcessRecord is actually active for the pid.
4644        synchronized (mPidsSelfLocked) {
4645            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4646            if (curProc != app) {
4647                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4648                return;
4649            }
4650        }
4651
4652        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4653        synchronized (stats) {
4654            stats.noteProcessDiedLocked(app.info.uid, pid);
4655        }
4656
4657        Process.killProcessQuiet(pid);
4658        Process.killProcessGroup(app.info.uid, pid);
4659        app.killed = true;
4660
4661        // Clean up already done if the process has been re-started.
4662        if (app.pid == pid && app.thread != null &&
4663                app.thread.asBinder() == thread.asBinder()) {
4664            boolean doLowMem = app.instrumentationClass == null;
4665            boolean doOomAdj = doLowMem;
4666            if (!app.killedByAm) {
4667                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4668                        + ") has died");
4669                mAllowLowerMemLevel = true;
4670            } else {
4671                // Note that we always want to do oom adj to update our state with the
4672                // new number of procs.
4673                mAllowLowerMemLevel = false;
4674                doLowMem = false;
4675            }
4676            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4677            if (DEBUG_CLEANUP) Slog.v(
4678                TAG, "Dying app: " + app + ", pid: " + pid
4679                + ", thread: " + thread.asBinder());
4680            handleAppDiedLocked(app, false, true);
4681
4682            if (doOomAdj) {
4683                updateOomAdjLocked();
4684            }
4685            if (doLowMem) {
4686                doLowMemReportIfNeededLocked(app);
4687            }
4688        } else if (app.pid != pid) {
4689            // A new process has already been started.
4690            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4691                    + ") has died and restarted (pid " + app.pid + ").");
4692            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4693        } else if (DEBUG_PROCESSES) {
4694            Slog.d(TAG, "Received spurious death notification for thread "
4695                    + thread.asBinder());
4696        }
4697    }
4698
4699    /**
4700     * If a stack trace dump file is configured, dump process stack traces.
4701     * @param clearTraces causes the dump file to be erased prior to the new
4702     *    traces being written, if true; when false, the new traces will be
4703     *    appended to any existing file content.
4704     * @param firstPids of dalvik VM processes to dump stack traces for first
4705     * @param lastPids of dalvik VM processes to dump stack traces for last
4706     * @param nativeProcs optional list of native process names to dump stack crawls
4707     * @return file containing stack traces, or null if no dump file is configured
4708     */
4709    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4710            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4711        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4712        if (tracesPath == null || tracesPath.length() == 0) {
4713            return null;
4714        }
4715
4716        File tracesFile = new File(tracesPath);
4717        try {
4718            File tracesDir = tracesFile.getParentFile();
4719            if (!tracesDir.exists()) {
4720                tracesDir.mkdirs();
4721                if (!SELinux.restorecon(tracesDir)) {
4722                    return null;
4723                }
4724            }
4725            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4726
4727            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4728            tracesFile.createNewFile();
4729            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4730        } catch (IOException e) {
4731            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4732            return null;
4733        }
4734
4735        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4736        return tracesFile;
4737    }
4738
4739    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4740            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4741        // Use a FileObserver to detect when traces finish writing.
4742        // The order of traces is considered important to maintain for legibility.
4743        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4744            @Override
4745            public synchronized void onEvent(int event, String path) { notify(); }
4746        };
4747
4748        try {
4749            observer.startWatching();
4750
4751            // First collect all of the stacks of the most important pids.
4752            if (firstPids != null) {
4753                try {
4754                    int num = firstPids.size();
4755                    for (int i = 0; i < num; i++) {
4756                        synchronized (observer) {
4757                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4758                            observer.wait(200);  // Wait for write-close, give up after 200msec
4759                        }
4760                    }
4761                } catch (InterruptedException e) {
4762                    Slog.wtf(TAG, e);
4763                }
4764            }
4765
4766            // Next collect the stacks of the native pids
4767            if (nativeProcs != null) {
4768                int[] pids = Process.getPidsForCommands(nativeProcs);
4769                if (pids != null) {
4770                    for (int pid : pids) {
4771                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4772                    }
4773                }
4774            }
4775
4776            // Lastly, measure CPU usage.
4777            if (processCpuTracker != null) {
4778                processCpuTracker.init();
4779                System.gc();
4780                processCpuTracker.update();
4781                try {
4782                    synchronized (processCpuTracker) {
4783                        processCpuTracker.wait(500); // measure over 1/2 second.
4784                    }
4785                } catch (InterruptedException e) {
4786                }
4787                processCpuTracker.update();
4788
4789                // We'll take the stack crawls of just the top apps using CPU.
4790                final int N = processCpuTracker.countWorkingStats();
4791                int numProcs = 0;
4792                for (int i=0; i<N && numProcs<5; i++) {
4793                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4794                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4795                        numProcs++;
4796                        try {
4797                            synchronized (observer) {
4798                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4799                                observer.wait(200);  // Wait for write-close, give up after 200msec
4800                            }
4801                        } catch (InterruptedException e) {
4802                            Slog.wtf(TAG, e);
4803                        }
4804
4805                    }
4806                }
4807            }
4808        } finally {
4809            observer.stopWatching();
4810        }
4811    }
4812
4813    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4814        if (true || IS_USER_BUILD) {
4815            return;
4816        }
4817        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4818        if (tracesPath == null || tracesPath.length() == 0) {
4819            return;
4820        }
4821
4822        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4823        StrictMode.allowThreadDiskWrites();
4824        try {
4825            final File tracesFile = new File(tracesPath);
4826            final File tracesDir = tracesFile.getParentFile();
4827            final File tracesTmp = new File(tracesDir, "__tmp__");
4828            try {
4829                if (!tracesDir.exists()) {
4830                    tracesDir.mkdirs();
4831                    if (!SELinux.restorecon(tracesDir.getPath())) {
4832                        return;
4833                    }
4834                }
4835                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4836
4837                if (tracesFile.exists()) {
4838                    tracesTmp.delete();
4839                    tracesFile.renameTo(tracesTmp);
4840                }
4841                StringBuilder sb = new StringBuilder();
4842                Time tobj = new Time();
4843                tobj.set(System.currentTimeMillis());
4844                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4845                sb.append(": ");
4846                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4847                sb.append(" since ");
4848                sb.append(msg);
4849                FileOutputStream fos = new FileOutputStream(tracesFile);
4850                fos.write(sb.toString().getBytes());
4851                if (app == null) {
4852                    fos.write("\n*** No application process!".getBytes());
4853                }
4854                fos.close();
4855                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4856            } catch (IOException e) {
4857                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4858                return;
4859            }
4860
4861            if (app != null) {
4862                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4863                firstPids.add(app.pid);
4864                dumpStackTraces(tracesPath, firstPids, null, null, null);
4865            }
4866
4867            File lastTracesFile = null;
4868            File curTracesFile = null;
4869            for (int i=9; i>=0; i--) {
4870                String name = String.format(Locale.US, "slow%02d.txt", i);
4871                curTracesFile = new File(tracesDir, name);
4872                if (curTracesFile.exists()) {
4873                    if (lastTracesFile != null) {
4874                        curTracesFile.renameTo(lastTracesFile);
4875                    } else {
4876                        curTracesFile.delete();
4877                    }
4878                }
4879                lastTracesFile = curTracesFile;
4880            }
4881            tracesFile.renameTo(curTracesFile);
4882            if (tracesTmp.exists()) {
4883                tracesTmp.renameTo(tracesFile);
4884            }
4885        } finally {
4886            StrictMode.setThreadPolicy(oldPolicy);
4887        }
4888    }
4889
4890    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4891            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4892        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4893        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4894
4895        if (mController != null) {
4896            try {
4897                // 0 == continue, -1 = kill process immediately
4898                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4899                if (res < 0 && app.pid != MY_PID) {
4900                    app.kill("anr", true);
4901                }
4902            } catch (RemoteException e) {
4903                mController = null;
4904                Watchdog.getInstance().setActivityController(null);
4905            }
4906        }
4907
4908        long anrTime = SystemClock.uptimeMillis();
4909        if (MONITOR_CPU_USAGE) {
4910            updateCpuStatsNow();
4911        }
4912
4913        synchronized (this) {
4914            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4915            if (mShuttingDown) {
4916                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4917                return;
4918            } else if (app.notResponding) {
4919                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4920                return;
4921            } else if (app.crashing) {
4922                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4923                return;
4924            }
4925
4926            // In case we come through here for the same app before completing
4927            // this one, mark as anring now so we will bail out.
4928            app.notResponding = true;
4929
4930            // Log the ANR to the event log.
4931            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4932                    app.processName, app.info.flags, annotation);
4933
4934            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4935            firstPids.add(app.pid);
4936
4937            int parentPid = app.pid;
4938            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4939            if (parentPid != app.pid) firstPids.add(parentPid);
4940
4941            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4942
4943            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4944                ProcessRecord r = mLruProcesses.get(i);
4945                if (r != null && r.thread != null) {
4946                    int pid = r.pid;
4947                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4948                        if (r.persistent) {
4949                            firstPids.add(pid);
4950                        } else {
4951                            lastPids.put(pid, Boolean.TRUE);
4952                        }
4953                    }
4954                }
4955            }
4956        }
4957
4958        // Log the ANR to the main log.
4959        StringBuilder info = new StringBuilder();
4960        info.setLength(0);
4961        info.append("ANR in ").append(app.processName);
4962        if (activity != null && activity.shortComponentName != null) {
4963            info.append(" (").append(activity.shortComponentName).append(")");
4964        }
4965        info.append("\n");
4966        info.append("PID: ").append(app.pid).append("\n");
4967        if (annotation != null) {
4968            info.append("Reason: ").append(annotation).append("\n");
4969        }
4970        if (parent != null && parent != activity) {
4971            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4972        }
4973
4974        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4975
4976        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4977                NATIVE_STACKS_OF_INTEREST);
4978
4979        String cpuInfo = null;
4980        if (MONITOR_CPU_USAGE) {
4981            updateCpuStatsNow();
4982            synchronized (mProcessCpuTracker) {
4983                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4984            }
4985            info.append(processCpuTracker.printCurrentLoad());
4986            info.append(cpuInfo);
4987        }
4988
4989        info.append(processCpuTracker.printCurrentState(anrTime));
4990
4991        Slog.e(TAG, info.toString());
4992        if (tracesFile == null) {
4993            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4994            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4995        }
4996
4997        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4998                cpuInfo, tracesFile, null);
4999
5000        if (mController != null) {
5001            try {
5002                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5003                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5004                if (res != 0) {
5005                    if (res < 0 && app.pid != MY_PID) {
5006                        app.kill("anr", true);
5007                    } else {
5008                        synchronized (this) {
5009                            mServices.scheduleServiceTimeoutLocked(app);
5010                        }
5011                    }
5012                    return;
5013                }
5014            } catch (RemoteException e) {
5015                mController = null;
5016                Watchdog.getInstance().setActivityController(null);
5017            }
5018        }
5019
5020        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5021        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5022                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5023
5024        synchronized (this) {
5025            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5026                app.kill("bg anr", true);
5027                return;
5028            }
5029
5030            // Set the app's notResponding state, and look up the errorReportReceiver
5031            makeAppNotRespondingLocked(app,
5032                    activity != null ? activity.shortComponentName : null,
5033                    annotation != null ? "ANR " + annotation : "ANR",
5034                    info.toString());
5035
5036            // Bring up the infamous App Not Responding dialog
5037            Message msg = Message.obtain();
5038            HashMap<String, Object> map = new HashMap<String, Object>();
5039            msg.what = SHOW_NOT_RESPONDING_MSG;
5040            msg.obj = map;
5041            msg.arg1 = aboveSystem ? 1 : 0;
5042            map.put("app", app);
5043            if (activity != null) {
5044                map.put("activity", activity);
5045            }
5046
5047            mHandler.sendMessage(msg);
5048        }
5049    }
5050
5051    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5052        if (!mLaunchWarningShown) {
5053            mLaunchWarningShown = true;
5054            mHandler.post(new Runnable() {
5055                @Override
5056                public void run() {
5057                    synchronized (ActivityManagerService.this) {
5058                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5059                        d.show();
5060                        mHandler.postDelayed(new Runnable() {
5061                            @Override
5062                            public void run() {
5063                                synchronized (ActivityManagerService.this) {
5064                                    d.dismiss();
5065                                    mLaunchWarningShown = false;
5066                                }
5067                            }
5068                        }, 4000);
5069                    }
5070                }
5071            });
5072        }
5073    }
5074
5075    @Override
5076    public boolean clearApplicationUserData(final String packageName,
5077            final IPackageDataObserver observer, int userId) {
5078        enforceNotIsolatedCaller("clearApplicationUserData");
5079        int uid = Binder.getCallingUid();
5080        int pid = Binder.getCallingPid();
5081        userId = handleIncomingUser(pid, uid,
5082                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5083        long callingId = Binder.clearCallingIdentity();
5084        try {
5085            IPackageManager pm = AppGlobals.getPackageManager();
5086            int pkgUid = -1;
5087            synchronized(this) {
5088                try {
5089                    pkgUid = pm.getPackageUid(packageName, userId);
5090                } catch (RemoteException e) {
5091                }
5092                if (pkgUid == -1) {
5093                    Slog.w(TAG, "Invalid packageName: " + packageName);
5094                    if (observer != null) {
5095                        try {
5096                            observer.onRemoveCompleted(packageName, false);
5097                        } catch (RemoteException e) {
5098                            Slog.i(TAG, "Observer no longer exists.");
5099                        }
5100                    }
5101                    return false;
5102                }
5103                if (uid == pkgUid || checkComponentPermission(
5104                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5105                        pid, uid, -1, true)
5106                        == PackageManager.PERMISSION_GRANTED) {
5107                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5108                } else {
5109                    throw new SecurityException("PID " + pid + " does not have permission "
5110                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5111                                    + " of package " + packageName);
5112                }
5113
5114                // Remove all tasks match the cleared application package and user
5115                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5116                    final TaskRecord tr = mRecentTasks.get(i);
5117                    final String taskPackageName =
5118                            tr.getBaseIntent().getComponent().getPackageName();
5119                    if (tr.userId != userId) continue;
5120                    if (!taskPackageName.equals(packageName)) continue;
5121                    removeTaskByIdLocked(tr.taskId, false);
5122                }
5123            }
5124
5125            try {
5126                // Clear application user data
5127                pm.clearApplicationUserData(packageName, observer, userId);
5128
5129                synchronized(this) {
5130                    // Remove all permissions granted from/to this package
5131                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5132                }
5133
5134                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5135                        Uri.fromParts("package", packageName, null));
5136                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5137                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5138                        null, null, 0, null, null, null, false, false, userId);
5139            } catch (RemoteException e) {
5140            }
5141        } finally {
5142            Binder.restoreCallingIdentity(callingId);
5143        }
5144        return true;
5145    }
5146
5147    @Override
5148    public void killBackgroundProcesses(final String packageName, int userId) {
5149        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5150                != PackageManager.PERMISSION_GRANTED &&
5151                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5152                        != PackageManager.PERMISSION_GRANTED) {
5153            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5154                    + Binder.getCallingPid()
5155                    + ", uid=" + Binder.getCallingUid()
5156                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5157            Slog.w(TAG, msg);
5158            throw new SecurityException(msg);
5159        }
5160
5161        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5162                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5163        long callingId = Binder.clearCallingIdentity();
5164        try {
5165            IPackageManager pm = AppGlobals.getPackageManager();
5166            synchronized(this) {
5167                int appId = -1;
5168                try {
5169                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5170                } catch (RemoteException e) {
5171                }
5172                if (appId == -1) {
5173                    Slog.w(TAG, "Invalid packageName: " + packageName);
5174                    return;
5175                }
5176                killPackageProcessesLocked(packageName, appId, userId,
5177                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5178            }
5179        } finally {
5180            Binder.restoreCallingIdentity(callingId);
5181        }
5182    }
5183
5184    @Override
5185    public void killAllBackgroundProcesses() {
5186        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5187                != PackageManager.PERMISSION_GRANTED) {
5188            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5189                    + Binder.getCallingPid()
5190                    + ", uid=" + Binder.getCallingUid()
5191                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5192            Slog.w(TAG, msg);
5193            throw new SecurityException(msg);
5194        }
5195
5196        long callingId = Binder.clearCallingIdentity();
5197        try {
5198            synchronized(this) {
5199                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5200                final int NP = mProcessNames.getMap().size();
5201                for (int ip=0; ip<NP; ip++) {
5202                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5203                    final int NA = apps.size();
5204                    for (int ia=0; ia<NA; ia++) {
5205                        ProcessRecord app = apps.valueAt(ia);
5206                        if (app.persistent) {
5207                            // we don't kill persistent processes
5208                            continue;
5209                        }
5210                        if (app.removed) {
5211                            procs.add(app);
5212                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5213                            app.removed = true;
5214                            procs.add(app);
5215                        }
5216                    }
5217                }
5218
5219                int N = procs.size();
5220                for (int i=0; i<N; i++) {
5221                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5222                }
5223                mAllowLowerMemLevel = true;
5224                updateOomAdjLocked();
5225                doLowMemReportIfNeededLocked(null);
5226            }
5227        } finally {
5228            Binder.restoreCallingIdentity(callingId);
5229        }
5230    }
5231
5232    @Override
5233    public void forceStopPackage(final String packageName, int userId) {
5234        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5235                != PackageManager.PERMISSION_GRANTED) {
5236            String msg = "Permission Denial: forceStopPackage() from pid="
5237                    + Binder.getCallingPid()
5238                    + ", uid=" + Binder.getCallingUid()
5239                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5240            Slog.w(TAG, msg);
5241            throw new SecurityException(msg);
5242        }
5243        final int callingPid = Binder.getCallingPid();
5244        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5245                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5246        long callingId = Binder.clearCallingIdentity();
5247        try {
5248            IPackageManager pm = AppGlobals.getPackageManager();
5249            synchronized(this) {
5250                int[] users = userId == UserHandle.USER_ALL
5251                        ? getUsersLocked() : new int[] { userId };
5252                for (int user : users) {
5253                    int pkgUid = -1;
5254                    try {
5255                        pkgUid = pm.getPackageUid(packageName, user);
5256                    } catch (RemoteException e) {
5257                    }
5258                    if (pkgUid == -1) {
5259                        Slog.w(TAG, "Invalid packageName: " + packageName);
5260                        continue;
5261                    }
5262                    try {
5263                        pm.setPackageStoppedState(packageName, true, user);
5264                    } catch (RemoteException e) {
5265                    } catch (IllegalArgumentException e) {
5266                        Slog.w(TAG, "Failed trying to unstop package "
5267                                + packageName + ": " + e);
5268                    }
5269                    if (isUserRunningLocked(user, false)) {
5270                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5271                    }
5272                }
5273            }
5274        } finally {
5275            Binder.restoreCallingIdentity(callingId);
5276        }
5277    }
5278
5279    @Override
5280    public void addPackageDependency(String packageName) {
5281        synchronized (this) {
5282            int callingPid = Binder.getCallingPid();
5283            if (callingPid == Process.myPid()) {
5284                //  Yeah, um, no.
5285                Slog.w(TAG, "Can't addPackageDependency on system process");
5286                return;
5287            }
5288            ProcessRecord proc;
5289            synchronized (mPidsSelfLocked) {
5290                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5291            }
5292            if (proc != null) {
5293                if (proc.pkgDeps == null) {
5294                    proc.pkgDeps = new ArraySet<String>(1);
5295                }
5296                proc.pkgDeps.add(packageName);
5297            }
5298        }
5299    }
5300
5301    /*
5302     * The pkg name and app id have to be specified.
5303     */
5304    @Override
5305    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5306        if (pkg == null) {
5307            return;
5308        }
5309        // Make sure the uid is valid.
5310        if (appid < 0) {
5311            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5312            return;
5313        }
5314        int callerUid = Binder.getCallingUid();
5315        // Only the system server can kill an application
5316        if (callerUid == Process.SYSTEM_UID) {
5317            // Post an aysnc message to kill the application
5318            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5319            msg.arg1 = appid;
5320            msg.arg2 = 0;
5321            Bundle bundle = new Bundle();
5322            bundle.putString("pkg", pkg);
5323            bundle.putString("reason", reason);
5324            msg.obj = bundle;
5325            mHandler.sendMessage(msg);
5326        } else {
5327            throw new SecurityException(callerUid + " cannot kill pkg: " +
5328                    pkg);
5329        }
5330    }
5331
5332    @Override
5333    public void closeSystemDialogs(String reason) {
5334        enforceNotIsolatedCaller("closeSystemDialogs");
5335
5336        final int pid = Binder.getCallingPid();
5337        final int uid = Binder.getCallingUid();
5338        final long origId = Binder.clearCallingIdentity();
5339        try {
5340            synchronized (this) {
5341                // Only allow this from foreground processes, so that background
5342                // applications can't abuse it to prevent system UI from being shown.
5343                if (uid >= Process.FIRST_APPLICATION_UID) {
5344                    ProcessRecord proc;
5345                    synchronized (mPidsSelfLocked) {
5346                        proc = mPidsSelfLocked.get(pid);
5347                    }
5348                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5349                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5350                                + " from background process " + proc);
5351                        return;
5352                    }
5353                }
5354                closeSystemDialogsLocked(reason);
5355            }
5356        } finally {
5357            Binder.restoreCallingIdentity(origId);
5358        }
5359    }
5360
5361    void closeSystemDialogsLocked(String reason) {
5362        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5363        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5364                | Intent.FLAG_RECEIVER_FOREGROUND);
5365        if (reason != null) {
5366            intent.putExtra("reason", reason);
5367        }
5368        mWindowManager.closeSystemDialogs(reason);
5369
5370        mStackSupervisor.closeSystemDialogsLocked();
5371
5372        broadcastIntentLocked(null, null, intent, null,
5373                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5374                Process.SYSTEM_UID, UserHandle.USER_ALL);
5375    }
5376
5377    @Override
5378    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5379        enforceNotIsolatedCaller("getProcessMemoryInfo");
5380        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5381        for (int i=pids.length-1; i>=0; i--) {
5382            ProcessRecord proc;
5383            int oomAdj;
5384            synchronized (this) {
5385                synchronized (mPidsSelfLocked) {
5386                    proc = mPidsSelfLocked.get(pids[i]);
5387                    oomAdj = proc != null ? proc.setAdj : 0;
5388                }
5389            }
5390            infos[i] = new Debug.MemoryInfo();
5391            Debug.getMemoryInfo(pids[i], infos[i]);
5392            if (proc != null) {
5393                synchronized (this) {
5394                    if (proc.thread != null && proc.setAdj == oomAdj) {
5395                        // Record this for posterity if the process has been stable.
5396                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5397                                infos[i].getTotalUss(), false, proc.pkgList);
5398                    }
5399                }
5400            }
5401        }
5402        return infos;
5403    }
5404
5405    @Override
5406    public long[] getProcessPss(int[] pids) {
5407        enforceNotIsolatedCaller("getProcessPss");
5408        long[] pss = new long[pids.length];
5409        for (int i=pids.length-1; i>=0; i--) {
5410            ProcessRecord proc;
5411            int oomAdj;
5412            synchronized (this) {
5413                synchronized (mPidsSelfLocked) {
5414                    proc = mPidsSelfLocked.get(pids[i]);
5415                    oomAdj = proc != null ? proc.setAdj : 0;
5416                }
5417            }
5418            long[] tmpUss = new long[1];
5419            pss[i] = Debug.getPss(pids[i], tmpUss);
5420            if (proc != null) {
5421                synchronized (this) {
5422                    if (proc.thread != null && proc.setAdj == oomAdj) {
5423                        // Record this for posterity if the process has been stable.
5424                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5425                    }
5426                }
5427            }
5428        }
5429        return pss;
5430    }
5431
5432    @Override
5433    public void killApplicationProcess(String processName, int uid) {
5434        if (processName == null) {
5435            return;
5436        }
5437
5438        int callerUid = Binder.getCallingUid();
5439        // Only the system server can kill an application
5440        if (callerUid == Process.SYSTEM_UID) {
5441            synchronized (this) {
5442                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5443                if (app != null && app.thread != null) {
5444                    try {
5445                        app.thread.scheduleSuicide();
5446                    } catch (RemoteException e) {
5447                        // If the other end already died, then our work here is done.
5448                    }
5449                } else {
5450                    Slog.w(TAG, "Process/uid not found attempting kill of "
5451                            + processName + " / " + uid);
5452                }
5453            }
5454        } else {
5455            throw new SecurityException(callerUid + " cannot kill app process: " +
5456                    processName);
5457        }
5458    }
5459
5460    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5461        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5462                false, true, false, false, UserHandle.getUserId(uid), reason);
5463        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5464                Uri.fromParts("package", packageName, null));
5465        if (!mProcessesReady) {
5466            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5467                    | Intent.FLAG_RECEIVER_FOREGROUND);
5468        }
5469        intent.putExtra(Intent.EXTRA_UID, uid);
5470        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5471        broadcastIntentLocked(null, null, intent,
5472                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5473                false, false,
5474                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5475    }
5476
5477    private void forceStopUserLocked(int userId, String reason) {
5478        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5479        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5480        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5481                | Intent.FLAG_RECEIVER_FOREGROUND);
5482        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5483        broadcastIntentLocked(null, null, intent,
5484                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5485                false, false,
5486                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5487    }
5488
5489    private final boolean killPackageProcessesLocked(String packageName, int appId,
5490            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5491            boolean doit, boolean evenPersistent, String reason) {
5492        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5493
5494        // Remove all processes this package may have touched: all with the
5495        // same UID (except for the system or root user), and all whose name
5496        // matches the package name.
5497        final int NP = mProcessNames.getMap().size();
5498        for (int ip=0; ip<NP; ip++) {
5499            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5500            final int NA = apps.size();
5501            for (int ia=0; ia<NA; ia++) {
5502                ProcessRecord app = apps.valueAt(ia);
5503                if (app.persistent && !evenPersistent) {
5504                    // we don't kill persistent processes
5505                    continue;
5506                }
5507                if (app.removed) {
5508                    if (doit) {
5509                        procs.add(app);
5510                    }
5511                    continue;
5512                }
5513
5514                // Skip process if it doesn't meet our oom adj requirement.
5515                if (app.setAdj < minOomAdj) {
5516                    continue;
5517                }
5518
5519                // If no package is specified, we call all processes under the
5520                // give user id.
5521                if (packageName == null) {
5522                    if (app.userId != userId) {
5523                        continue;
5524                    }
5525                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5526                        continue;
5527                    }
5528                // Package has been specified, we want to hit all processes
5529                // that match it.  We need to qualify this by the processes
5530                // that are running under the specified app and user ID.
5531                } else {
5532                    final boolean isDep = app.pkgDeps != null
5533                            && app.pkgDeps.contains(packageName);
5534                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5535                        continue;
5536                    }
5537                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5538                        continue;
5539                    }
5540                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5541                        continue;
5542                    }
5543                }
5544
5545                // Process has passed all conditions, kill it!
5546                if (!doit) {
5547                    return true;
5548                }
5549                app.removed = true;
5550                procs.add(app);
5551            }
5552        }
5553
5554        int N = procs.size();
5555        for (int i=0; i<N; i++) {
5556            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5557        }
5558        updateOomAdjLocked();
5559        return N > 0;
5560    }
5561
5562    private final boolean forceStopPackageLocked(String name, int appId,
5563            boolean callerWillRestart, boolean purgeCache, boolean doit,
5564            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5565        int i;
5566        int N;
5567
5568        if (userId == UserHandle.USER_ALL && name == null) {
5569            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5570        }
5571
5572        if (appId < 0 && name != null) {
5573            try {
5574                appId = UserHandle.getAppId(
5575                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5576            } catch (RemoteException e) {
5577            }
5578        }
5579
5580        if (doit) {
5581            if (name != null) {
5582                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5583                        + " user=" + userId + ": " + reason);
5584            } else {
5585                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5586            }
5587
5588            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5589            for (int ip=pmap.size()-1; ip>=0; ip--) {
5590                SparseArray<Long> ba = pmap.valueAt(ip);
5591                for (i=ba.size()-1; i>=0; i--) {
5592                    boolean remove = false;
5593                    final int entUid = ba.keyAt(i);
5594                    if (name != null) {
5595                        if (userId == UserHandle.USER_ALL) {
5596                            if (UserHandle.getAppId(entUid) == appId) {
5597                                remove = true;
5598                            }
5599                        } else {
5600                            if (entUid == UserHandle.getUid(userId, appId)) {
5601                                remove = true;
5602                            }
5603                        }
5604                    } else if (UserHandle.getUserId(entUid) == userId) {
5605                        remove = true;
5606                    }
5607                    if (remove) {
5608                        ba.removeAt(i);
5609                    }
5610                }
5611                if (ba.size() == 0) {
5612                    pmap.removeAt(ip);
5613                }
5614            }
5615        }
5616
5617        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5618                -100, callerWillRestart, true, doit, evenPersistent,
5619                name == null ? ("stop user " + userId) : ("stop " + name));
5620
5621        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5622            if (!doit) {
5623                return true;
5624            }
5625            didSomething = true;
5626        }
5627
5628        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5629            if (!doit) {
5630                return true;
5631            }
5632            didSomething = true;
5633        }
5634
5635        if (name == null) {
5636            // Remove all sticky broadcasts from this user.
5637            mStickyBroadcasts.remove(userId);
5638        }
5639
5640        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5641        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5642                userId, providers)) {
5643            if (!doit) {
5644                return true;
5645            }
5646            didSomething = true;
5647        }
5648        N = providers.size();
5649        for (i=0; i<N; i++) {
5650            removeDyingProviderLocked(null, providers.get(i), true);
5651        }
5652
5653        // Remove transient permissions granted from/to this package/user
5654        removeUriPermissionsForPackageLocked(name, userId, false);
5655
5656        if (name == null || uninstalling) {
5657            // Remove pending intents.  For now we only do this when force
5658            // stopping users, because we have some problems when doing this
5659            // for packages -- app widgets are not currently cleaned up for
5660            // such packages, so they can be left with bad pending intents.
5661            if (mIntentSenderRecords.size() > 0) {
5662                Iterator<WeakReference<PendingIntentRecord>> it
5663                        = mIntentSenderRecords.values().iterator();
5664                while (it.hasNext()) {
5665                    WeakReference<PendingIntentRecord> wpir = it.next();
5666                    if (wpir == null) {
5667                        it.remove();
5668                        continue;
5669                    }
5670                    PendingIntentRecord pir = wpir.get();
5671                    if (pir == null) {
5672                        it.remove();
5673                        continue;
5674                    }
5675                    if (name == null) {
5676                        // Stopping user, remove all objects for the user.
5677                        if (pir.key.userId != userId) {
5678                            // Not the same user, skip it.
5679                            continue;
5680                        }
5681                    } else {
5682                        if (UserHandle.getAppId(pir.uid) != appId) {
5683                            // Different app id, skip it.
5684                            continue;
5685                        }
5686                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5687                            // Different user, skip it.
5688                            continue;
5689                        }
5690                        if (!pir.key.packageName.equals(name)) {
5691                            // Different package, skip it.
5692                            continue;
5693                        }
5694                    }
5695                    if (!doit) {
5696                        return true;
5697                    }
5698                    didSomething = true;
5699                    it.remove();
5700                    pir.canceled = true;
5701                    if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5702                        pir.key.activity.pendingResults.remove(pir.ref);
5703                    }
5704                }
5705            }
5706        }
5707
5708        if (doit) {
5709            if (purgeCache && name != null) {
5710                AttributeCache ac = AttributeCache.instance();
5711                if (ac != null) {
5712                    ac.removePackage(name);
5713                }
5714            }
5715            if (mBooted) {
5716                mStackSupervisor.resumeTopActivitiesLocked();
5717                mStackSupervisor.scheduleIdleLocked();
5718            }
5719        }
5720
5721        return didSomething;
5722    }
5723
5724    private final boolean removeProcessLocked(ProcessRecord app,
5725            boolean callerWillRestart, boolean allowRestart, String reason) {
5726        final String name = app.processName;
5727        final int uid = app.uid;
5728        if (DEBUG_PROCESSES) Slog.d(
5729            TAG, "Force removing proc " + app.toShortString() + " (" + name
5730            + "/" + uid + ")");
5731
5732        mProcessNames.remove(name, uid);
5733        mIsolatedProcesses.remove(app.uid);
5734        if (mHeavyWeightProcess == app) {
5735            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5736                    mHeavyWeightProcess.userId, 0));
5737            mHeavyWeightProcess = null;
5738        }
5739        boolean needRestart = false;
5740        if (app.pid > 0 && app.pid != MY_PID) {
5741            int pid = app.pid;
5742            synchronized (mPidsSelfLocked) {
5743                mPidsSelfLocked.remove(pid);
5744                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5745            }
5746            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5747            if (app.isolated) {
5748                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5749            }
5750            app.kill(reason, true);
5751            handleAppDiedLocked(app, true, allowRestart);
5752            removeLruProcessLocked(app);
5753
5754            if (app.persistent && !app.isolated) {
5755                if (!callerWillRestart) {
5756                    addAppLocked(app.info, false, null /* ABI override */);
5757                } else {
5758                    needRestart = true;
5759                }
5760            }
5761        } else {
5762            mRemovedProcesses.add(app);
5763        }
5764
5765        return needRestart;
5766    }
5767
5768    private final void processStartTimedOutLocked(ProcessRecord app) {
5769        final int pid = app.pid;
5770        boolean gone = false;
5771        synchronized (mPidsSelfLocked) {
5772            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5773            if (knownApp != null && knownApp.thread == null) {
5774                mPidsSelfLocked.remove(pid);
5775                gone = true;
5776            }
5777        }
5778
5779        if (gone) {
5780            Slog.w(TAG, "Process " + app + " failed to attach");
5781            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5782                    pid, app.uid, app.processName);
5783            mProcessNames.remove(app.processName, app.uid);
5784            mIsolatedProcesses.remove(app.uid);
5785            if (mHeavyWeightProcess == app) {
5786                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5787                        mHeavyWeightProcess.userId, 0));
5788                mHeavyWeightProcess = null;
5789            }
5790            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5791            if (app.isolated) {
5792                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5793            }
5794            // Take care of any launching providers waiting for this process.
5795            checkAppInLaunchingProvidersLocked(app, true);
5796            // Take care of any services that are waiting for the process.
5797            mServices.processStartTimedOutLocked(app);
5798            app.kill("start timeout", true);
5799            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5800                Slog.w(TAG, "Unattached app died before backup, skipping");
5801                try {
5802                    IBackupManager bm = IBackupManager.Stub.asInterface(
5803                            ServiceManager.getService(Context.BACKUP_SERVICE));
5804                    bm.agentDisconnected(app.info.packageName);
5805                } catch (RemoteException e) {
5806                    // Can't happen; the backup manager is local
5807                }
5808            }
5809            if (isPendingBroadcastProcessLocked(pid)) {
5810                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5811                skipPendingBroadcastLocked(pid);
5812            }
5813        } else {
5814            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5815        }
5816    }
5817
5818    private final boolean attachApplicationLocked(IApplicationThread thread,
5819            int pid) {
5820
5821        // Find the application record that is being attached...  either via
5822        // the pid if we are running in multiple processes, or just pull the
5823        // next app record if we are emulating process with anonymous threads.
5824        ProcessRecord app;
5825        if (pid != MY_PID && pid >= 0) {
5826            synchronized (mPidsSelfLocked) {
5827                app = mPidsSelfLocked.get(pid);
5828            }
5829        } else {
5830            app = null;
5831        }
5832
5833        if (app == null) {
5834            Slog.w(TAG, "No pending application record for pid " + pid
5835                    + " (IApplicationThread " + thread + "); dropping process");
5836            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5837            if (pid > 0 && pid != MY_PID) {
5838                Process.killProcessQuiet(pid);
5839                //TODO: Process.killProcessGroup(app.info.uid, pid);
5840            } else {
5841                try {
5842                    thread.scheduleExit();
5843                } catch (Exception e) {
5844                    // Ignore exceptions.
5845                }
5846            }
5847            return false;
5848        }
5849
5850        // If this application record is still attached to a previous
5851        // process, clean it up now.
5852        if (app.thread != null) {
5853            handleAppDiedLocked(app, true, true);
5854        }
5855
5856        // Tell the process all about itself.
5857
5858        if (localLOGV) Slog.v(
5859                TAG, "Binding process pid " + pid + " to record " + app);
5860
5861        final String processName = app.processName;
5862        try {
5863            AppDeathRecipient adr = new AppDeathRecipient(
5864                    app, pid, thread);
5865            thread.asBinder().linkToDeath(adr, 0);
5866            app.deathRecipient = adr;
5867        } catch (RemoteException e) {
5868            app.resetPackageList(mProcessStats);
5869            startProcessLocked(app, "link fail", processName);
5870            return false;
5871        }
5872
5873        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5874
5875        app.makeActive(thread, mProcessStats);
5876        app.curAdj = app.setAdj = -100;
5877        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5878        app.forcingToForeground = null;
5879        updateProcessForegroundLocked(app, false, false);
5880        app.hasShownUi = false;
5881        app.debugging = false;
5882        app.cached = false;
5883
5884        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5885
5886        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5887        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5888
5889        if (!normalMode) {
5890            Slog.i(TAG, "Launching preboot mode app: " + app);
5891        }
5892
5893        if (localLOGV) Slog.v(
5894            TAG, "New app record " + app
5895            + " thread=" + thread.asBinder() + " pid=" + pid);
5896        try {
5897            int testMode = IApplicationThread.DEBUG_OFF;
5898            if (mDebugApp != null && mDebugApp.equals(processName)) {
5899                testMode = mWaitForDebugger
5900                    ? IApplicationThread.DEBUG_WAIT
5901                    : IApplicationThread.DEBUG_ON;
5902                app.debugging = true;
5903                if (mDebugTransient) {
5904                    mDebugApp = mOrigDebugApp;
5905                    mWaitForDebugger = mOrigWaitForDebugger;
5906                }
5907            }
5908            String profileFile = app.instrumentationProfileFile;
5909            ParcelFileDescriptor profileFd = null;
5910            int samplingInterval = 0;
5911            boolean profileAutoStop = false;
5912            if (mProfileApp != null && mProfileApp.equals(processName)) {
5913                mProfileProc = app;
5914                profileFile = mProfileFile;
5915                profileFd = mProfileFd;
5916                samplingInterval = mSamplingInterval;
5917                profileAutoStop = mAutoStopProfiler;
5918            }
5919            boolean enableOpenGlTrace = false;
5920            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5921                enableOpenGlTrace = true;
5922                mOpenGlTraceApp = null;
5923            }
5924
5925            // If the app is being launched for restore or full backup, set it up specially
5926            boolean isRestrictedBackupMode = false;
5927            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5928                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5929                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5930                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5931            }
5932
5933            ensurePackageDexOpt(app.instrumentationInfo != null
5934                    ? app.instrumentationInfo.packageName
5935                    : app.info.packageName);
5936            if (app.instrumentationClass != null) {
5937                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5938            }
5939            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5940                    + processName + " with config " + mConfiguration);
5941            ApplicationInfo appInfo = app.instrumentationInfo != null
5942                    ? app.instrumentationInfo : app.info;
5943            app.compat = compatibilityInfoForPackageLocked(appInfo);
5944            if (profileFd != null) {
5945                profileFd = profileFd.dup();
5946            }
5947            ProfilerInfo profilerInfo = profileFile == null ? null
5948                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5949            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5950                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5951                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5952                    isRestrictedBackupMode || !normalMode, app.persistent,
5953                    new Configuration(mConfiguration), app.compat,
5954                    getCommonServicesLocked(app.isolated),
5955                    mCoreSettingsObserver.getCoreSettingsLocked());
5956            updateLruProcessLocked(app, false, null);
5957            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5958        } catch (Exception e) {
5959            // todo: Yikes!  What should we do?  For now we will try to
5960            // start another process, but that could easily get us in
5961            // an infinite loop of restarting processes...
5962            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5963
5964            app.resetPackageList(mProcessStats);
5965            app.unlinkDeathRecipient();
5966            startProcessLocked(app, "bind fail", processName);
5967            return false;
5968        }
5969
5970        // Remove this record from the list of starting applications.
5971        mPersistentStartingProcesses.remove(app);
5972        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5973                "Attach application locked removing on hold: " + app);
5974        mProcessesOnHold.remove(app);
5975
5976        boolean badApp = false;
5977        boolean didSomething = false;
5978
5979        // See if the top visible activity is waiting to run in this process...
5980        if (normalMode) {
5981            try {
5982                if (mStackSupervisor.attachApplicationLocked(app)) {
5983                    didSomething = true;
5984                }
5985            } catch (Exception e) {
5986                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
5987                badApp = true;
5988            }
5989        }
5990
5991        // Find any services that should be running in this process...
5992        if (!badApp) {
5993            try {
5994                didSomething |= mServices.attachApplicationLocked(app, processName);
5995            } catch (Exception e) {
5996                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
5997                badApp = true;
5998            }
5999        }
6000
6001        // Check if a next-broadcast receiver is in this process...
6002        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6003            try {
6004                didSomething |= sendPendingBroadcastsLocked(app);
6005            } catch (Exception e) {
6006                // If the app died trying to launch the receiver we declare it 'bad'
6007                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6008                badApp = true;
6009            }
6010        }
6011
6012        // Check whether the next backup agent is in this process...
6013        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6014            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6015            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6016            try {
6017                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6018                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6019                        mBackupTarget.backupMode);
6020            } catch (Exception e) {
6021                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6022                badApp = true;
6023            }
6024        }
6025
6026        if (badApp) {
6027            app.kill("error during init", true);
6028            handleAppDiedLocked(app, false, true);
6029            return false;
6030        }
6031
6032        if (!didSomething) {
6033            updateOomAdjLocked();
6034        }
6035
6036        return true;
6037    }
6038
6039    @Override
6040    public final void attachApplication(IApplicationThread thread) {
6041        synchronized (this) {
6042            int callingPid = Binder.getCallingPid();
6043            final long origId = Binder.clearCallingIdentity();
6044            attachApplicationLocked(thread, callingPid);
6045            Binder.restoreCallingIdentity(origId);
6046        }
6047    }
6048
6049    @Override
6050    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6051        final long origId = Binder.clearCallingIdentity();
6052        synchronized (this) {
6053            ActivityStack stack = ActivityRecord.getStackLocked(token);
6054            if (stack != null) {
6055                ActivityRecord r =
6056                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6057                if (stopProfiling) {
6058                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6059                        try {
6060                            mProfileFd.close();
6061                        } catch (IOException e) {
6062                        }
6063                        clearProfilerLocked();
6064                    }
6065                }
6066            }
6067        }
6068        Binder.restoreCallingIdentity(origId);
6069    }
6070
6071    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6072        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6073                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6074    }
6075
6076    void enableScreenAfterBoot() {
6077        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6078                SystemClock.uptimeMillis());
6079        mWindowManager.enableScreenAfterBoot();
6080
6081        synchronized (this) {
6082            updateEventDispatchingLocked();
6083        }
6084    }
6085
6086    @Override
6087    public void showBootMessage(final CharSequence msg, final boolean always) {
6088        enforceNotIsolatedCaller("showBootMessage");
6089        mWindowManager.showBootMessage(msg, always);
6090    }
6091
6092    @Override
6093    public void keyguardWaitingForActivityDrawn() {
6094        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6095        final long token = Binder.clearCallingIdentity();
6096        try {
6097            synchronized (this) {
6098                if (DEBUG_LOCKSCREEN) logLockScreen("");
6099                mWindowManager.keyguardWaitingForActivityDrawn();
6100                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6101                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6102                    updateSleepIfNeededLocked();
6103                }
6104            }
6105        } finally {
6106            Binder.restoreCallingIdentity(token);
6107        }
6108    }
6109
6110    final void finishBooting() {
6111        synchronized (this) {
6112            if (!mBootAnimationComplete) {
6113                mCallFinishBooting = true;
6114                return;
6115            }
6116            mCallFinishBooting = false;
6117        }
6118
6119        ArraySet<String> completedIsas = new ArraySet<String>();
6120        for (String abi : Build.SUPPORTED_ABIS) {
6121            Process.establishZygoteConnectionForAbi(abi);
6122            final String instructionSet = VMRuntime.getInstructionSet(abi);
6123            if (!completedIsas.contains(instructionSet)) {
6124                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6125                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6126                }
6127                completedIsas.add(instructionSet);
6128            }
6129        }
6130
6131        IntentFilter pkgFilter = new IntentFilter();
6132        pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6133        pkgFilter.addDataScheme("package");
6134        mContext.registerReceiver(new BroadcastReceiver() {
6135            @Override
6136            public void onReceive(Context context, Intent intent) {
6137                String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6138                if (pkgs != null) {
6139                    for (String pkg : pkgs) {
6140                        synchronized (ActivityManagerService.this) {
6141                            if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6142                                    0, "finished booting")) {
6143                                setResultCode(Activity.RESULT_OK);
6144                                return;
6145                            }
6146                        }
6147                    }
6148                }
6149            }
6150        }, pkgFilter);
6151
6152        // Let system services know.
6153        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6154
6155        synchronized (this) {
6156            // Ensure that any processes we had put on hold are now started
6157            // up.
6158            final int NP = mProcessesOnHold.size();
6159            if (NP > 0) {
6160                ArrayList<ProcessRecord> procs =
6161                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6162                for (int ip=0; ip<NP; ip++) {
6163                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6164                            + procs.get(ip));
6165                    startProcessLocked(procs.get(ip), "on-hold", null);
6166                }
6167            }
6168
6169            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6170                // Start looking for apps that are abusing wake locks.
6171                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6172                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6173                // Tell anyone interested that we are done booting!
6174                SystemProperties.set("sys.boot_completed", "1");
6175
6176                // And trigger dev.bootcomplete if we are not showing encryption progress
6177                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6178                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6179                    SystemProperties.set("dev.bootcomplete", "1");
6180                }
6181                for (int i=0; i<mStartedUsers.size(); i++) {
6182                    UserStartedState uss = mStartedUsers.valueAt(i);
6183                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6184                        uss.mState = UserStartedState.STATE_RUNNING;
6185                        final int userId = mStartedUsers.keyAt(i);
6186                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6187                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6188                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6189                        broadcastIntentLocked(null, null, intent, null,
6190                                new IIntentReceiver.Stub() {
6191                                    @Override
6192                                    public void performReceive(Intent intent, int resultCode,
6193                                            String data, Bundle extras, boolean ordered,
6194                                            boolean sticky, int sendingUser) {
6195                                        synchronized (ActivityManagerService.this) {
6196                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6197                                                    true, false);
6198                                        }
6199                                    }
6200                                },
6201                                0, null, null,
6202                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6203                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6204                                userId);
6205                    }
6206                }
6207                scheduleStartProfilesLocked();
6208            }
6209        }
6210    }
6211
6212    @Override
6213    public void bootAnimationComplete() {
6214        final boolean callFinishBooting;
6215        synchronized (this) {
6216            callFinishBooting = mCallFinishBooting;
6217            mBootAnimationComplete = true;
6218        }
6219        if (callFinishBooting) {
6220            finishBooting();
6221        }
6222    }
6223
6224    @Override
6225    public void systemBackupRestored() {
6226        synchronized (this) {
6227            if (mSystemReady) {
6228                mTaskPersister.restoreTasksFromOtherDeviceLocked();
6229            } else {
6230                Slog.w(TAG, "System backup restored before system is ready");
6231            }
6232        }
6233    }
6234
6235    final void ensureBootCompleted() {
6236        boolean booting;
6237        boolean enableScreen;
6238        synchronized (this) {
6239            booting = mBooting;
6240            mBooting = false;
6241            enableScreen = !mBooted;
6242            mBooted = true;
6243        }
6244
6245        if (booting) {
6246            finishBooting();
6247        }
6248
6249        if (enableScreen) {
6250            enableScreenAfterBoot();
6251        }
6252    }
6253
6254    @Override
6255    public final void activityResumed(IBinder token) {
6256        final long origId = Binder.clearCallingIdentity();
6257        synchronized(this) {
6258            ActivityStack stack = ActivityRecord.getStackLocked(token);
6259            if (stack != null) {
6260                ActivityRecord.activityResumedLocked(token);
6261            }
6262        }
6263        Binder.restoreCallingIdentity(origId);
6264    }
6265
6266    @Override
6267    public final void activityPaused(IBinder token) {
6268        final long origId = Binder.clearCallingIdentity();
6269        synchronized(this) {
6270            ActivityStack stack = ActivityRecord.getStackLocked(token);
6271            if (stack != null) {
6272                stack.activityPausedLocked(token, false);
6273            }
6274        }
6275        Binder.restoreCallingIdentity(origId);
6276    }
6277
6278    @Override
6279    public final void activityStopped(IBinder token, Bundle icicle,
6280            PersistableBundle persistentState, CharSequence description) {
6281        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6282
6283        // Refuse possible leaked file descriptors
6284        if (icicle != null && icicle.hasFileDescriptors()) {
6285            throw new IllegalArgumentException("File descriptors passed in Bundle");
6286        }
6287
6288        final long origId = Binder.clearCallingIdentity();
6289
6290        synchronized (this) {
6291            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6292            if (r != null) {
6293                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6294            }
6295        }
6296
6297        trimApplications();
6298
6299        Binder.restoreCallingIdentity(origId);
6300    }
6301
6302    @Override
6303    public final void activityDestroyed(IBinder token) {
6304        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6305        synchronized (this) {
6306            ActivityStack stack = ActivityRecord.getStackLocked(token);
6307            if (stack != null) {
6308                stack.activityDestroyedLocked(token);
6309            }
6310        }
6311    }
6312
6313    @Override
6314    public final void backgroundResourcesReleased(IBinder token) {
6315        final long origId = Binder.clearCallingIdentity();
6316        try {
6317            synchronized (this) {
6318                ActivityStack stack = ActivityRecord.getStackLocked(token);
6319                if (stack != null) {
6320                    stack.backgroundResourcesReleased();
6321                }
6322            }
6323        } finally {
6324            Binder.restoreCallingIdentity(origId);
6325        }
6326    }
6327
6328    @Override
6329    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6330        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6331    }
6332
6333    @Override
6334    public final void notifyEnterAnimationComplete(IBinder token) {
6335        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6336    }
6337
6338    @Override
6339    public String getCallingPackage(IBinder token) {
6340        synchronized (this) {
6341            ActivityRecord r = getCallingRecordLocked(token);
6342            return r != null ? r.info.packageName : null;
6343        }
6344    }
6345
6346    @Override
6347    public ComponentName getCallingActivity(IBinder token) {
6348        synchronized (this) {
6349            ActivityRecord r = getCallingRecordLocked(token);
6350            return r != null ? r.intent.getComponent() : null;
6351        }
6352    }
6353
6354    private ActivityRecord getCallingRecordLocked(IBinder token) {
6355        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6356        if (r == null) {
6357            return null;
6358        }
6359        return r.resultTo;
6360    }
6361
6362    @Override
6363    public ComponentName getActivityClassForToken(IBinder token) {
6364        synchronized(this) {
6365            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6366            if (r == null) {
6367                return null;
6368            }
6369            return r.intent.getComponent();
6370        }
6371    }
6372
6373    @Override
6374    public String getPackageForToken(IBinder token) {
6375        synchronized(this) {
6376            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6377            if (r == null) {
6378                return null;
6379            }
6380            return r.packageName;
6381        }
6382    }
6383
6384    @Override
6385    public IIntentSender getIntentSender(int type,
6386            String packageName, IBinder token, String resultWho,
6387            int requestCode, Intent[] intents, String[] resolvedTypes,
6388            int flags, Bundle options, int userId) {
6389        enforceNotIsolatedCaller("getIntentSender");
6390        // Refuse possible leaked file descriptors
6391        if (intents != null) {
6392            if (intents.length < 1) {
6393                throw new IllegalArgumentException("Intents array length must be >= 1");
6394            }
6395            for (int i=0; i<intents.length; i++) {
6396                Intent intent = intents[i];
6397                if (intent != null) {
6398                    if (intent.hasFileDescriptors()) {
6399                        throw new IllegalArgumentException("File descriptors passed in Intent");
6400                    }
6401                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6402                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6403                        throw new IllegalArgumentException(
6404                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6405                    }
6406                    intents[i] = new Intent(intent);
6407                }
6408            }
6409            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6410                throw new IllegalArgumentException(
6411                        "Intent array length does not match resolvedTypes length");
6412            }
6413        }
6414        if (options != null) {
6415            if (options.hasFileDescriptors()) {
6416                throw new IllegalArgumentException("File descriptors passed in options");
6417            }
6418        }
6419
6420        synchronized(this) {
6421            int callingUid = Binder.getCallingUid();
6422            int origUserId = userId;
6423            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6424                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6425                    ALLOW_NON_FULL, "getIntentSender", null);
6426            if (origUserId == UserHandle.USER_CURRENT) {
6427                // We don't want to evaluate this until the pending intent is
6428                // actually executed.  However, we do want to always do the
6429                // security checking for it above.
6430                userId = UserHandle.USER_CURRENT;
6431            }
6432            try {
6433                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6434                    int uid = AppGlobals.getPackageManager()
6435                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6436                    if (!UserHandle.isSameApp(callingUid, uid)) {
6437                        String msg = "Permission Denial: getIntentSender() from pid="
6438                            + Binder.getCallingPid()
6439                            + ", uid=" + Binder.getCallingUid()
6440                            + ", (need uid=" + uid + ")"
6441                            + " is not allowed to send as package " + packageName;
6442                        Slog.w(TAG, msg);
6443                        throw new SecurityException(msg);
6444                    }
6445                }
6446
6447                return getIntentSenderLocked(type, packageName, callingUid, userId,
6448                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6449
6450            } catch (RemoteException e) {
6451                throw new SecurityException(e);
6452            }
6453        }
6454    }
6455
6456    IIntentSender getIntentSenderLocked(int type, String packageName,
6457            int callingUid, int userId, IBinder token, String resultWho,
6458            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6459            Bundle options) {
6460        if (DEBUG_MU)
6461            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6462        ActivityRecord activity = null;
6463        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6464            activity = ActivityRecord.isInStackLocked(token);
6465            if (activity == null) {
6466                return null;
6467            }
6468            if (activity.finishing) {
6469                return null;
6470            }
6471        }
6472
6473        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6474        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6475        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6476        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6477                |PendingIntent.FLAG_UPDATE_CURRENT);
6478
6479        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6480                type, packageName, activity, resultWho,
6481                requestCode, intents, resolvedTypes, flags, options, userId);
6482        WeakReference<PendingIntentRecord> ref;
6483        ref = mIntentSenderRecords.get(key);
6484        PendingIntentRecord rec = ref != null ? ref.get() : null;
6485        if (rec != null) {
6486            if (!cancelCurrent) {
6487                if (updateCurrent) {
6488                    if (rec.key.requestIntent != null) {
6489                        rec.key.requestIntent.replaceExtras(intents != null ?
6490                                intents[intents.length - 1] : null);
6491                    }
6492                    if (intents != null) {
6493                        intents[intents.length-1] = rec.key.requestIntent;
6494                        rec.key.allIntents = intents;
6495                        rec.key.allResolvedTypes = resolvedTypes;
6496                    } else {
6497                        rec.key.allIntents = null;
6498                        rec.key.allResolvedTypes = null;
6499                    }
6500                }
6501                return rec;
6502            }
6503            rec.canceled = true;
6504            mIntentSenderRecords.remove(key);
6505        }
6506        if (noCreate) {
6507            return rec;
6508        }
6509        rec = new PendingIntentRecord(this, key, callingUid);
6510        mIntentSenderRecords.put(key, rec.ref);
6511        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6512            if (activity.pendingResults == null) {
6513                activity.pendingResults
6514                        = new HashSet<WeakReference<PendingIntentRecord>>();
6515            }
6516            activity.pendingResults.add(rec.ref);
6517        }
6518        return rec;
6519    }
6520
6521    @Override
6522    public void cancelIntentSender(IIntentSender sender) {
6523        if (!(sender instanceof PendingIntentRecord)) {
6524            return;
6525        }
6526        synchronized(this) {
6527            PendingIntentRecord rec = (PendingIntentRecord)sender;
6528            try {
6529                int uid = AppGlobals.getPackageManager()
6530                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6531                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6532                    String msg = "Permission Denial: cancelIntentSender() from pid="
6533                        + Binder.getCallingPid()
6534                        + ", uid=" + Binder.getCallingUid()
6535                        + " is not allowed to cancel packges "
6536                        + rec.key.packageName;
6537                    Slog.w(TAG, msg);
6538                    throw new SecurityException(msg);
6539                }
6540            } catch (RemoteException e) {
6541                throw new SecurityException(e);
6542            }
6543            cancelIntentSenderLocked(rec, true);
6544        }
6545    }
6546
6547    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6548        rec.canceled = true;
6549        mIntentSenderRecords.remove(rec.key);
6550        if (cleanActivity && rec.key.activity != null) {
6551            rec.key.activity.pendingResults.remove(rec.ref);
6552        }
6553    }
6554
6555    @Override
6556    public String getPackageForIntentSender(IIntentSender pendingResult) {
6557        if (!(pendingResult instanceof PendingIntentRecord)) {
6558            return null;
6559        }
6560        try {
6561            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6562            return res.key.packageName;
6563        } catch (ClassCastException e) {
6564        }
6565        return null;
6566    }
6567
6568    @Override
6569    public int getUidForIntentSender(IIntentSender sender) {
6570        if (sender instanceof PendingIntentRecord) {
6571            try {
6572                PendingIntentRecord res = (PendingIntentRecord)sender;
6573                return res.uid;
6574            } catch (ClassCastException e) {
6575            }
6576        }
6577        return -1;
6578    }
6579
6580    @Override
6581    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6582        if (!(pendingResult instanceof PendingIntentRecord)) {
6583            return false;
6584        }
6585        try {
6586            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6587            if (res.key.allIntents == null) {
6588                return false;
6589            }
6590            for (int i=0; i<res.key.allIntents.length; i++) {
6591                Intent intent = res.key.allIntents[i];
6592                if (intent.getPackage() != null && intent.getComponent() != null) {
6593                    return false;
6594                }
6595            }
6596            return true;
6597        } catch (ClassCastException e) {
6598        }
6599        return false;
6600    }
6601
6602    @Override
6603    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6604        if (!(pendingResult instanceof PendingIntentRecord)) {
6605            return false;
6606        }
6607        try {
6608            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6609            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6610                return true;
6611            }
6612            return false;
6613        } catch (ClassCastException e) {
6614        }
6615        return false;
6616    }
6617
6618    @Override
6619    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6620        if (!(pendingResult instanceof PendingIntentRecord)) {
6621            return null;
6622        }
6623        try {
6624            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6625            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6626        } catch (ClassCastException e) {
6627        }
6628        return null;
6629    }
6630
6631    @Override
6632    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6633        if (!(pendingResult instanceof PendingIntentRecord)) {
6634            return null;
6635        }
6636        try {
6637            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6638            Intent intent = res.key.requestIntent;
6639            if (intent != null) {
6640                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6641                        || res.lastTagPrefix.equals(prefix))) {
6642                    return res.lastTag;
6643                }
6644                res.lastTagPrefix = prefix;
6645                StringBuilder sb = new StringBuilder(128);
6646                if (prefix != null) {
6647                    sb.append(prefix);
6648                }
6649                if (intent.getAction() != null) {
6650                    sb.append(intent.getAction());
6651                } else if (intent.getComponent() != null) {
6652                    intent.getComponent().appendShortString(sb);
6653                } else {
6654                    sb.append("?");
6655                }
6656                return res.lastTag = sb.toString();
6657            }
6658        } catch (ClassCastException e) {
6659        }
6660        return null;
6661    }
6662
6663    @Override
6664    public void setProcessLimit(int max) {
6665        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6666                "setProcessLimit()");
6667        synchronized (this) {
6668            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6669            mProcessLimitOverride = max;
6670        }
6671        trimApplications();
6672    }
6673
6674    @Override
6675    public int getProcessLimit() {
6676        synchronized (this) {
6677            return mProcessLimitOverride;
6678        }
6679    }
6680
6681    void foregroundTokenDied(ForegroundToken token) {
6682        synchronized (ActivityManagerService.this) {
6683            synchronized (mPidsSelfLocked) {
6684                ForegroundToken cur
6685                    = mForegroundProcesses.get(token.pid);
6686                if (cur != token) {
6687                    return;
6688                }
6689                mForegroundProcesses.remove(token.pid);
6690                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6691                if (pr == null) {
6692                    return;
6693                }
6694                pr.forcingToForeground = null;
6695                updateProcessForegroundLocked(pr, false, false);
6696            }
6697            updateOomAdjLocked();
6698        }
6699    }
6700
6701    @Override
6702    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6703        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6704                "setProcessForeground()");
6705        synchronized(this) {
6706            boolean changed = false;
6707
6708            synchronized (mPidsSelfLocked) {
6709                ProcessRecord pr = mPidsSelfLocked.get(pid);
6710                if (pr == null && isForeground) {
6711                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6712                    return;
6713                }
6714                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6715                if (oldToken != null) {
6716                    oldToken.token.unlinkToDeath(oldToken, 0);
6717                    mForegroundProcesses.remove(pid);
6718                    if (pr != null) {
6719                        pr.forcingToForeground = null;
6720                    }
6721                    changed = true;
6722                }
6723                if (isForeground && token != null) {
6724                    ForegroundToken newToken = new ForegroundToken() {
6725                        @Override
6726                        public void binderDied() {
6727                            foregroundTokenDied(this);
6728                        }
6729                    };
6730                    newToken.pid = pid;
6731                    newToken.token = token;
6732                    try {
6733                        token.linkToDeath(newToken, 0);
6734                        mForegroundProcesses.put(pid, newToken);
6735                        pr.forcingToForeground = token;
6736                        changed = true;
6737                    } catch (RemoteException e) {
6738                        // If the process died while doing this, we will later
6739                        // do the cleanup with the process death link.
6740                    }
6741                }
6742            }
6743
6744            if (changed) {
6745                updateOomAdjLocked();
6746            }
6747        }
6748    }
6749
6750    // =========================================================
6751    // PERMISSIONS
6752    // =========================================================
6753
6754    static class PermissionController extends IPermissionController.Stub {
6755        ActivityManagerService mActivityManagerService;
6756        PermissionController(ActivityManagerService activityManagerService) {
6757            mActivityManagerService = activityManagerService;
6758        }
6759
6760        @Override
6761        public boolean checkPermission(String permission, int pid, int uid) {
6762            return mActivityManagerService.checkPermission(permission, pid,
6763                    uid) == PackageManager.PERMISSION_GRANTED;
6764        }
6765    }
6766
6767    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6768        @Override
6769        public int checkComponentPermission(String permission, int pid, int uid,
6770                int owningUid, boolean exported) {
6771            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6772                    owningUid, exported);
6773        }
6774
6775        @Override
6776        public Object getAMSLock() {
6777            return ActivityManagerService.this;
6778        }
6779    }
6780
6781    /**
6782     * This can be called with or without the global lock held.
6783     */
6784    int checkComponentPermission(String permission, int pid, int uid,
6785            int owningUid, boolean exported) {
6786        if (pid == MY_PID) {
6787            return PackageManager.PERMISSION_GRANTED;
6788        }
6789        return ActivityManager.checkComponentPermission(permission, uid,
6790                owningUid, exported);
6791    }
6792
6793    /**
6794     * As the only public entry point for permissions checking, this method
6795     * can enforce the semantic that requesting a check on a null global
6796     * permission is automatically denied.  (Internally a null permission
6797     * string is used when calling {@link #checkComponentPermission} in cases
6798     * when only uid-based security is needed.)
6799     *
6800     * This can be called with or without the global lock held.
6801     */
6802    @Override
6803    public int checkPermission(String permission, int pid, int uid) {
6804        if (permission == null) {
6805            return PackageManager.PERMISSION_DENIED;
6806        }
6807        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6808    }
6809
6810    @Override
6811    public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6812        if (permission == null) {
6813            return PackageManager.PERMISSION_DENIED;
6814        }
6815
6816        // We might be performing an operation on behalf of an indirect binder
6817        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6818        // client identity accordingly before proceeding.
6819        Identity tlsIdentity = sCallerIdentity.get();
6820        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6821            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6822                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6823            uid = tlsIdentity.uid;
6824            pid = tlsIdentity.pid;
6825        }
6826
6827        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6828    }
6829
6830    /**
6831     * Binder IPC calls go through the public entry point.
6832     * This can be called with or without the global lock held.
6833     */
6834    int checkCallingPermission(String permission) {
6835        return checkPermission(permission,
6836                Binder.getCallingPid(),
6837                UserHandle.getAppId(Binder.getCallingUid()));
6838    }
6839
6840    /**
6841     * This can be called with or without the global lock held.
6842     */
6843    void enforceCallingPermission(String permission, String func) {
6844        if (checkCallingPermission(permission)
6845                == PackageManager.PERMISSION_GRANTED) {
6846            return;
6847        }
6848
6849        String msg = "Permission Denial: " + func + " from pid="
6850                + Binder.getCallingPid()
6851                + ", uid=" + Binder.getCallingUid()
6852                + " requires " + permission;
6853        Slog.w(TAG, msg);
6854        throw new SecurityException(msg);
6855    }
6856
6857    /**
6858     * Determine if UID is holding permissions required to access {@link Uri} in
6859     * the given {@link ProviderInfo}. Final permission checking is always done
6860     * in {@link ContentProvider}.
6861     */
6862    private final boolean checkHoldingPermissionsLocked(
6863            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6864        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6865                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6866        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6867            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6868                    != PERMISSION_GRANTED) {
6869                return false;
6870            }
6871        }
6872        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6873    }
6874
6875    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6876            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6877        if (pi.applicationInfo.uid == uid) {
6878            return true;
6879        } else if (!pi.exported) {
6880            return false;
6881        }
6882
6883        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6884        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6885        try {
6886            // check if target holds top-level <provider> permissions
6887            if (!readMet && pi.readPermission != null && considerUidPermissions
6888                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6889                readMet = true;
6890            }
6891            if (!writeMet && pi.writePermission != null && considerUidPermissions
6892                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6893                writeMet = true;
6894            }
6895
6896            // track if unprotected read/write is allowed; any denied
6897            // <path-permission> below removes this ability
6898            boolean allowDefaultRead = pi.readPermission == null;
6899            boolean allowDefaultWrite = pi.writePermission == null;
6900
6901            // check if target holds any <path-permission> that match uri
6902            final PathPermission[] pps = pi.pathPermissions;
6903            if (pps != null) {
6904                final String path = grantUri.uri.getPath();
6905                int i = pps.length;
6906                while (i > 0 && (!readMet || !writeMet)) {
6907                    i--;
6908                    PathPermission pp = pps[i];
6909                    if (pp.match(path)) {
6910                        if (!readMet) {
6911                            final String pprperm = pp.getReadPermission();
6912                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6913                                    + pprperm + " for " + pp.getPath()
6914                                    + ": match=" + pp.match(path)
6915                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6916                            if (pprperm != null) {
6917                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6918                                        == PERMISSION_GRANTED) {
6919                                    readMet = true;
6920                                } else {
6921                                    allowDefaultRead = false;
6922                                }
6923                            }
6924                        }
6925                        if (!writeMet) {
6926                            final String ppwperm = pp.getWritePermission();
6927                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6928                                    + ppwperm + " for " + pp.getPath()
6929                                    + ": match=" + pp.match(path)
6930                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6931                            if (ppwperm != null) {
6932                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6933                                        == PERMISSION_GRANTED) {
6934                                    writeMet = true;
6935                                } else {
6936                                    allowDefaultWrite = false;
6937                                }
6938                            }
6939                        }
6940                    }
6941                }
6942            }
6943
6944            // grant unprotected <provider> read/write, if not blocked by
6945            // <path-permission> above
6946            if (allowDefaultRead) readMet = true;
6947            if (allowDefaultWrite) writeMet = true;
6948
6949        } catch (RemoteException e) {
6950            return false;
6951        }
6952
6953        return readMet && writeMet;
6954    }
6955
6956    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6957        ProviderInfo pi = null;
6958        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6959        if (cpr != null) {
6960            pi = cpr.info;
6961        } else {
6962            try {
6963                pi = AppGlobals.getPackageManager().resolveContentProvider(
6964                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6965            } catch (RemoteException ex) {
6966            }
6967        }
6968        return pi;
6969    }
6970
6971    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6972        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6973        if (targetUris != null) {
6974            return targetUris.get(grantUri);
6975        }
6976        return null;
6977    }
6978
6979    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6980            String targetPkg, int targetUid, GrantUri grantUri) {
6981        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6982        if (targetUris == null) {
6983            targetUris = Maps.newArrayMap();
6984            mGrantedUriPermissions.put(targetUid, targetUris);
6985        }
6986
6987        UriPermission perm = targetUris.get(grantUri);
6988        if (perm == null) {
6989            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6990            targetUris.put(grantUri, perm);
6991        }
6992
6993        return perm;
6994    }
6995
6996    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6997            final int modeFlags) {
6998        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6999        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7000                : UriPermission.STRENGTH_OWNED;
7001
7002        // Root gets to do everything.
7003        if (uid == 0) {
7004            return true;
7005        }
7006
7007        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7008        if (perms == null) return false;
7009
7010        // First look for exact match
7011        final UriPermission exactPerm = perms.get(grantUri);
7012        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7013            return true;
7014        }
7015
7016        // No exact match, look for prefixes
7017        final int N = perms.size();
7018        for (int i = 0; i < N; i++) {
7019            final UriPermission perm = perms.valueAt(i);
7020            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7021                    && perm.getStrength(modeFlags) >= minStrength) {
7022                return true;
7023            }
7024        }
7025
7026        return false;
7027    }
7028
7029    /**
7030     * @param uri This uri must NOT contain an embedded userId.
7031     * @param userId The userId in which the uri is to be resolved.
7032     */
7033    @Override
7034    public int checkUriPermission(Uri uri, int pid, int uid,
7035            final int modeFlags, int userId, IBinder callerToken) {
7036        enforceNotIsolatedCaller("checkUriPermission");
7037
7038        // Another redirected-binder-call permissions check as in
7039        // {@link checkPermissionWithToken}.
7040        Identity tlsIdentity = sCallerIdentity.get();
7041        if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7042            uid = tlsIdentity.uid;
7043            pid = tlsIdentity.pid;
7044        }
7045
7046        // Our own process gets to do everything.
7047        if (pid == MY_PID) {
7048            return PackageManager.PERMISSION_GRANTED;
7049        }
7050        synchronized (this) {
7051            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7052                    ? PackageManager.PERMISSION_GRANTED
7053                    : PackageManager.PERMISSION_DENIED;
7054        }
7055    }
7056
7057    /**
7058     * Check if the targetPkg can be granted permission to access uri by
7059     * the callingUid using the given modeFlags.  Throws a security exception
7060     * if callingUid is not allowed to do this.  Returns the uid of the target
7061     * if the URI permission grant should be performed; returns -1 if it is not
7062     * needed (for example targetPkg already has permission to access the URI).
7063     * If you already know the uid of the target, you can supply it in
7064     * lastTargetUid else set that to -1.
7065     */
7066    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7067            final int modeFlags, int lastTargetUid) {
7068        if (!Intent.isAccessUriMode(modeFlags)) {
7069            return -1;
7070        }
7071
7072        if (targetPkg != null) {
7073            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7074                    "Checking grant " + targetPkg + " permission to " + grantUri);
7075        }
7076
7077        final IPackageManager pm = AppGlobals.getPackageManager();
7078
7079        // If this is not a content: uri, we can't do anything with it.
7080        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7081            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7082                    "Can't grant URI permission for non-content URI: " + grantUri);
7083            return -1;
7084        }
7085
7086        final String authority = grantUri.uri.getAuthority();
7087        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7088        if (pi == null) {
7089            Slog.w(TAG, "No content provider found for permission check: " +
7090                    grantUri.uri.toSafeString());
7091            return -1;
7092        }
7093
7094        int targetUid = lastTargetUid;
7095        if (targetUid < 0 && targetPkg != null) {
7096            try {
7097                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7098                if (targetUid < 0) {
7099                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7100                            "Can't grant URI permission no uid for: " + targetPkg);
7101                    return -1;
7102                }
7103            } catch (RemoteException ex) {
7104                return -1;
7105            }
7106        }
7107
7108        if (targetUid >= 0) {
7109            // First...  does the target actually need this permission?
7110            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7111                // No need to grant the target this permission.
7112                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7113                        "Target " + targetPkg + " already has full permission to " + grantUri);
7114                return -1;
7115            }
7116        } else {
7117            // First...  there is no target package, so can anyone access it?
7118            boolean allowed = pi.exported;
7119            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7120                if (pi.readPermission != null) {
7121                    allowed = false;
7122                }
7123            }
7124            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7125                if (pi.writePermission != null) {
7126                    allowed = false;
7127                }
7128            }
7129            if (allowed) {
7130                return -1;
7131            }
7132        }
7133
7134        /* There is a special cross user grant if:
7135         * - The target is on another user.
7136         * - Apps on the current user can access the uri without any uid permissions.
7137         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7138         * grant uri permissions.
7139         */
7140        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7141                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7142                modeFlags, false /*without considering the uid permissions*/);
7143
7144        // Second...  is the provider allowing granting of URI permissions?
7145        if (!specialCrossUserGrant) {
7146            if (!pi.grantUriPermissions) {
7147                throw new SecurityException("Provider " + pi.packageName
7148                        + "/" + pi.name
7149                        + " does not allow granting of Uri permissions (uri "
7150                        + grantUri + ")");
7151            }
7152            if (pi.uriPermissionPatterns != null) {
7153                final int N = pi.uriPermissionPatterns.length;
7154                boolean allowed = false;
7155                for (int i=0; i<N; i++) {
7156                    if (pi.uriPermissionPatterns[i] != null
7157                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7158                        allowed = true;
7159                        break;
7160                    }
7161                }
7162                if (!allowed) {
7163                    throw new SecurityException("Provider " + pi.packageName
7164                            + "/" + pi.name
7165                            + " does not allow granting of permission to path of Uri "
7166                            + grantUri);
7167                }
7168            }
7169        }
7170
7171        // Third...  does the caller itself have permission to access
7172        // this uri?
7173        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7174            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7175                // Require they hold a strong enough Uri permission
7176                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7177                    throw new SecurityException("Uid " + callingUid
7178                            + " does not have permission to uri " + grantUri);
7179                }
7180            }
7181        }
7182        return targetUid;
7183    }
7184
7185    /**
7186     * @param uri This uri must NOT contain an embedded userId.
7187     * @param userId The userId in which the uri is to be resolved.
7188     */
7189    @Override
7190    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7191            final int modeFlags, int userId) {
7192        enforceNotIsolatedCaller("checkGrantUriPermission");
7193        synchronized(this) {
7194            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7195                    new GrantUri(userId, uri, false), modeFlags, -1);
7196        }
7197    }
7198
7199    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7200            final int modeFlags, UriPermissionOwner owner) {
7201        if (!Intent.isAccessUriMode(modeFlags)) {
7202            return;
7203        }
7204
7205        // So here we are: the caller has the assumed permission
7206        // to the uri, and the target doesn't.  Let's now give this to
7207        // the target.
7208
7209        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7210                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7211
7212        final String authority = grantUri.uri.getAuthority();
7213        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7214        if (pi == null) {
7215            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7216            return;
7217        }
7218
7219        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7220            grantUri.prefix = true;
7221        }
7222        final UriPermission perm = findOrCreateUriPermissionLocked(
7223                pi.packageName, targetPkg, targetUid, grantUri);
7224        perm.grantModes(modeFlags, owner);
7225    }
7226
7227    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7228            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7229        if (targetPkg == null) {
7230            throw new NullPointerException("targetPkg");
7231        }
7232        int targetUid;
7233        final IPackageManager pm = AppGlobals.getPackageManager();
7234        try {
7235            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7236        } catch (RemoteException ex) {
7237            return;
7238        }
7239
7240        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7241                targetUid);
7242        if (targetUid < 0) {
7243            return;
7244        }
7245
7246        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7247                owner);
7248    }
7249
7250    static class NeededUriGrants extends ArrayList<GrantUri> {
7251        final String targetPkg;
7252        final int targetUid;
7253        final int flags;
7254
7255        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7256            this.targetPkg = targetPkg;
7257            this.targetUid = targetUid;
7258            this.flags = flags;
7259        }
7260    }
7261
7262    /**
7263     * Like checkGrantUriPermissionLocked, but takes an Intent.
7264     */
7265    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7266            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7267        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7268                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7269                + " clip=" + (intent != null ? intent.getClipData() : null)
7270                + " from " + intent + "; flags=0x"
7271                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7272
7273        if (targetPkg == null) {
7274            throw new NullPointerException("targetPkg");
7275        }
7276
7277        if (intent == null) {
7278            return null;
7279        }
7280        Uri data = intent.getData();
7281        ClipData clip = intent.getClipData();
7282        if (data == null && clip == null) {
7283            return null;
7284        }
7285        // Default userId for uris in the intent (if they don't specify it themselves)
7286        int contentUserHint = intent.getContentUserHint();
7287        if (contentUserHint == UserHandle.USER_CURRENT) {
7288            contentUserHint = UserHandle.getUserId(callingUid);
7289        }
7290        final IPackageManager pm = AppGlobals.getPackageManager();
7291        int targetUid;
7292        if (needed != null) {
7293            targetUid = needed.targetUid;
7294        } else {
7295            try {
7296                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7297            } catch (RemoteException ex) {
7298                return null;
7299            }
7300            if (targetUid < 0) {
7301                if (DEBUG_URI_PERMISSION) {
7302                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7303                            + " on user " + targetUserId);
7304                }
7305                return null;
7306            }
7307        }
7308        if (data != null) {
7309            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7310            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7311                    targetUid);
7312            if (targetUid > 0) {
7313                if (needed == null) {
7314                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7315                }
7316                needed.add(grantUri);
7317            }
7318        }
7319        if (clip != null) {
7320            for (int i=0; i<clip.getItemCount(); i++) {
7321                Uri uri = clip.getItemAt(i).getUri();
7322                if (uri != null) {
7323                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7324                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7325                            targetUid);
7326                    if (targetUid > 0) {
7327                        if (needed == null) {
7328                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7329                        }
7330                        needed.add(grantUri);
7331                    }
7332                } else {
7333                    Intent clipIntent = clip.getItemAt(i).getIntent();
7334                    if (clipIntent != null) {
7335                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7336                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7337                        if (newNeeded != null) {
7338                            needed = newNeeded;
7339                        }
7340                    }
7341                }
7342            }
7343        }
7344
7345        return needed;
7346    }
7347
7348    /**
7349     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7350     */
7351    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7352            UriPermissionOwner owner) {
7353        if (needed != null) {
7354            for (int i=0; i<needed.size(); i++) {
7355                GrantUri grantUri = needed.get(i);
7356                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7357                        grantUri, needed.flags, owner);
7358            }
7359        }
7360    }
7361
7362    void grantUriPermissionFromIntentLocked(int callingUid,
7363            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7364        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7365                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7366        if (needed == null) {
7367            return;
7368        }
7369
7370        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7371    }
7372
7373    /**
7374     * @param uri This uri must NOT contain an embedded userId.
7375     * @param userId The userId in which the uri is to be resolved.
7376     */
7377    @Override
7378    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7379            final int modeFlags, int userId) {
7380        enforceNotIsolatedCaller("grantUriPermission");
7381        GrantUri grantUri = new GrantUri(userId, uri, false);
7382        synchronized(this) {
7383            final ProcessRecord r = getRecordForAppLocked(caller);
7384            if (r == null) {
7385                throw new SecurityException("Unable to find app for caller "
7386                        + caller
7387                        + " when granting permission to uri " + grantUri);
7388            }
7389            if (targetPkg == null) {
7390                throw new IllegalArgumentException("null target");
7391            }
7392            if (grantUri == null) {
7393                throw new IllegalArgumentException("null uri");
7394            }
7395
7396            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7397                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7398                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7399                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7400
7401            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7402                    UserHandle.getUserId(r.uid));
7403        }
7404    }
7405
7406    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7407        if (perm.modeFlags == 0) {
7408            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7409                    perm.targetUid);
7410            if (perms != null) {
7411                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7412                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7413
7414                perms.remove(perm.uri);
7415                if (perms.isEmpty()) {
7416                    mGrantedUriPermissions.remove(perm.targetUid);
7417                }
7418            }
7419        }
7420    }
7421
7422    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7423        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7424
7425        final IPackageManager pm = AppGlobals.getPackageManager();
7426        final String authority = grantUri.uri.getAuthority();
7427        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7428        if (pi == null) {
7429            Slog.w(TAG, "No content provider found for permission revoke: "
7430                    + grantUri.toSafeString());
7431            return;
7432        }
7433
7434        // Does the caller have this permission on the URI?
7435        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7436            // If they don't have direct access to the URI, then revoke any
7437            // ownerless URI permissions that have been granted to them.
7438            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7439            if (perms != null) {
7440                boolean persistChanged = false;
7441                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7442                    final UriPermission perm = it.next();
7443                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7444                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7445                        if (DEBUG_URI_PERMISSION)
7446                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7447                                    " permission to " + perm.uri);
7448                        persistChanged |= perm.revokeModes(
7449                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7450                        if (perm.modeFlags == 0) {
7451                            it.remove();
7452                        }
7453                    }
7454                }
7455                if (perms.isEmpty()) {
7456                    mGrantedUriPermissions.remove(callingUid);
7457                }
7458                if (persistChanged) {
7459                    schedulePersistUriGrants();
7460                }
7461            }
7462            return;
7463        }
7464
7465        boolean persistChanged = false;
7466
7467        // Go through all of the permissions and remove any that match.
7468        int N = mGrantedUriPermissions.size();
7469        for (int i = 0; i < N; i++) {
7470            final int targetUid = mGrantedUriPermissions.keyAt(i);
7471            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7472
7473            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7474                final UriPermission perm = it.next();
7475                if (perm.uri.sourceUserId == grantUri.sourceUserId
7476                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7477                    if (DEBUG_URI_PERMISSION)
7478                        Slog.v(TAG,
7479                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7480                    persistChanged |= perm.revokeModes(
7481                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7482                    if (perm.modeFlags == 0) {
7483                        it.remove();
7484                    }
7485                }
7486            }
7487
7488            if (perms.isEmpty()) {
7489                mGrantedUriPermissions.remove(targetUid);
7490                N--;
7491                i--;
7492            }
7493        }
7494
7495        if (persistChanged) {
7496            schedulePersistUriGrants();
7497        }
7498    }
7499
7500    /**
7501     * @param uri This uri must NOT contain an embedded userId.
7502     * @param userId The userId in which the uri is to be resolved.
7503     */
7504    @Override
7505    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7506            int userId) {
7507        enforceNotIsolatedCaller("revokeUriPermission");
7508        synchronized(this) {
7509            final ProcessRecord r = getRecordForAppLocked(caller);
7510            if (r == null) {
7511                throw new SecurityException("Unable to find app for caller "
7512                        + caller
7513                        + " when revoking permission to uri " + uri);
7514            }
7515            if (uri == null) {
7516                Slog.w(TAG, "revokeUriPermission: null uri");
7517                return;
7518            }
7519
7520            if (!Intent.isAccessUriMode(modeFlags)) {
7521                return;
7522            }
7523
7524            final IPackageManager pm = AppGlobals.getPackageManager();
7525            final String authority = uri.getAuthority();
7526            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7527            if (pi == null) {
7528                Slog.w(TAG, "No content provider found for permission revoke: "
7529                        + uri.toSafeString());
7530                return;
7531            }
7532
7533            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7534        }
7535    }
7536
7537    /**
7538     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7539     * given package.
7540     *
7541     * @param packageName Package name to match, or {@code null} to apply to all
7542     *            packages.
7543     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7544     *            to all users.
7545     * @param persistable If persistable grants should be removed.
7546     */
7547    private void removeUriPermissionsForPackageLocked(
7548            String packageName, int userHandle, boolean persistable) {
7549        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7550            throw new IllegalArgumentException("Must narrow by either package or user");
7551        }
7552
7553        boolean persistChanged = false;
7554
7555        int N = mGrantedUriPermissions.size();
7556        for (int i = 0; i < N; i++) {
7557            final int targetUid = mGrantedUriPermissions.keyAt(i);
7558            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7559
7560            // Only inspect grants matching user
7561            if (userHandle == UserHandle.USER_ALL
7562                    || userHandle == UserHandle.getUserId(targetUid)) {
7563                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7564                    final UriPermission perm = it.next();
7565
7566                    // Only inspect grants matching package
7567                    if (packageName == null || perm.sourcePkg.equals(packageName)
7568                            || perm.targetPkg.equals(packageName)) {
7569                        persistChanged |= perm.revokeModes(persistable
7570                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7571
7572                        // Only remove when no modes remain; any persisted grants
7573                        // will keep this alive.
7574                        if (perm.modeFlags == 0) {
7575                            it.remove();
7576                        }
7577                    }
7578                }
7579
7580                if (perms.isEmpty()) {
7581                    mGrantedUriPermissions.remove(targetUid);
7582                    N--;
7583                    i--;
7584                }
7585            }
7586        }
7587
7588        if (persistChanged) {
7589            schedulePersistUriGrants();
7590        }
7591    }
7592
7593    @Override
7594    public IBinder newUriPermissionOwner(String name) {
7595        enforceNotIsolatedCaller("newUriPermissionOwner");
7596        synchronized(this) {
7597            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7598            return owner.getExternalTokenLocked();
7599        }
7600    }
7601
7602    /**
7603     * @param uri This uri must NOT contain an embedded userId.
7604     * @param sourceUserId The userId in which the uri is to be resolved.
7605     * @param targetUserId The userId of the app that receives the grant.
7606     */
7607    @Override
7608    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7609            final int modeFlags, int sourceUserId, int targetUserId) {
7610        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7611                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7612        synchronized(this) {
7613            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7614            if (owner == null) {
7615                throw new IllegalArgumentException("Unknown owner: " + token);
7616            }
7617            if (fromUid != Binder.getCallingUid()) {
7618                if (Binder.getCallingUid() != Process.myUid()) {
7619                    // Only system code can grant URI permissions on behalf
7620                    // of other users.
7621                    throw new SecurityException("nice try");
7622                }
7623            }
7624            if (targetPkg == null) {
7625                throw new IllegalArgumentException("null target");
7626            }
7627            if (uri == null) {
7628                throw new IllegalArgumentException("null uri");
7629            }
7630
7631            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7632                    modeFlags, owner, targetUserId);
7633        }
7634    }
7635
7636    /**
7637     * @param uri This uri must NOT contain an embedded userId.
7638     * @param userId The userId in which the uri is to be resolved.
7639     */
7640    @Override
7641    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7642        synchronized(this) {
7643            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7644            if (owner == null) {
7645                throw new IllegalArgumentException("Unknown owner: " + token);
7646            }
7647
7648            if (uri == null) {
7649                owner.removeUriPermissionsLocked(mode);
7650            } else {
7651                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7652            }
7653        }
7654    }
7655
7656    private void schedulePersistUriGrants() {
7657        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7658            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7659                    10 * DateUtils.SECOND_IN_MILLIS);
7660        }
7661    }
7662
7663    private void writeGrantedUriPermissions() {
7664        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7665
7666        // Snapshot permissions so we can persist without lock
7667        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7668        synchronized (this) {
7669            final int size = mGrantedUriPermissions.size();
7670            for (int i = 0; i < size; i++) {
7671                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7672                for (UriPermission perm : perms.values()) {
7673                    if (perm.persistedModeFlags != 0) {
7674                        persist.add(perm.snapshot());
7675                    }
7676                }
7677            }
7678        }
7679
7680        FileOutputStream fos = null;
7681        try {
7682            fos = mGrantFile.startWrite();
7683
7684            XmlSerializer out = new FastXmlSerializer();
7685            out.setOutput(fos, "utf-8");
7686            out.startDocument(null, true);
7687            out.startTag(null, TAG_URI_GRANTS);
7688            for (UriPermission.Snapshot perm : persist) {
7689                out.startTag(null, TAG_URI_GRANT);
7690                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7691                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7692                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7693                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7694                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7695                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7696                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7697                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7698                out.endTag(null, TAG_URI_GRANT);
7699            }
7700            out.endTag(null, TAG_URI_GRANTS);
7701            out.endDocument();
7702
7703            mGrantFile.finishWrite(fos);
7704        } catch (IOException e) {
7705            if (fos != null) {
7706                mGrantFile.failWrite(fos);
7707            }
7708        }
7709    }
7710
7711    private void readGrantedUriPermissionsLocked() {
7712        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7713
7714        final long now = System.currentTimeMillis();
7715
7716        FileInputStream fis = null;
7717        try {
7718            fis = mGrantFile.openRead();
7719            final XmlPullParser in = Xml.newPullParser();
7720            in.setInput(fis, null);
7721
7722            int type;
7723            while ((type = in.next()) != END_DOCUMENT) {
7724                final String tag = in.getName();
7725                if (type == START_TAG) {
7726                    if (TAG_URI_GRANT.equals(tag)) {
7727                        final int sourceUserId;
7728                        final int targetUserId;
7729                        final int userHandle = readIntAttribute(in,
7730                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7731                        if (userHandle != UserHandle.USER_NULL) {
7732                            // For backwards compatibility.
7733                            sourceUserId = userHandle;
7734                            targetUserId = userHandle;
7735                        } else {
7736                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7737                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7738                        }
7739                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7740                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7741                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7742                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7743                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7744                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7745
7746                        // Sanity check that provider still belongs to source package
7747                        final ProviderInfo pi = getProviderInfoLocked(
7748                                uri.getAuthority(), sourceUserId);
7749                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7750                            int targetUid = -1;
7751                            try {
7752                                targetUid = AppGlobals.getPackageManager()
7753                                        .getPackageUid(targetPkg, targetUserId);
7754                            } catch (RemoteException e) {
7755                            }
7756                            if (targetUid != -1) {
7757                                final UriPermission perm = findOrCreateUriPermissionLocked(
7758                                        sourcePkg, targetPkg, targetUid,
7759                                        new GrantUri(sourceUserId, uri, prefix));
7760                                perm.initPersistedModes(modeFlags, createdTime);
7761                            }
7762                        } else {
7763                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7764                                    + " but instead found " + pi);
7765                        }
7766                    }
7767                }
7768            }
7769        } catch (FileNotFoundException e) {
7770            // Missing grants is okay
7771        } catch (IOException e) {
7772            Slog.wtf(TAG, "Failed reading Uri grants", e);
7773        } catch (XmlPullParserException e) {
7774            Slog.wtf(TAG, "Failed reading Uri grants", e);
7775        } finally {
7776            IoUtils.closeQuietly(fis);
7777        }
7778    }
7779
7780    /**
7781     * @param uri This uri must NOT contain an embedded userId.
7782     * @param userId The userId in which the uri is to be resolved.
7783     */
7784    @Override
7785    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7786        enforceNotIsolatedCaller("takePersistableUriPermission");
7787
7788        Preconditions.checkFlagsArgument(modeFlags,
7789                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7790
7791        synchronized (this) {
7792            final int callingUid = Binder.getCallingUid();
7793            boolean persistChanged = false;
7794            GrantUri grantUri = new GrantUri(userId, uri, false);
7795
7796            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7797                    new GrantUri(userId, uri, false));
7798            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7799                    new GrantUri(userId, uri, true));
7800
7801            final boolean exactValid = (exactPerm != null)
7802                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7803            final boolean prefixValid = (prefixPerm != null)
7804                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7805
7806            if (!(exactValid || prefixValid)) {
7807                throw new SecurityException("No persistable permission grants found for UID "
7808                        + callingUid + " and Uri " + grantUri.toSafeString());
7809            }
7810
7811            if (exactValid) {
7812                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7813            }
7814            if (prefixValid) {
7815                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7816            }
7817
7818            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7819
7820            if (persistChanged) {
7821                schedulePersistUriGrants();
7822            }
7823        }
7824    }
7825
7826    /**
7827     * @param uri This uri must NOT contain an embedded userId.
7828     * @param userId The userId in which the uri is to be resolved.
7829     */
7830    @Override
7831    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7832        enforceNotIsolatedCaller("releasePersistableUriPermission");
7833
7834        Preconditions.checkFlagsArgument(modeFlags,
7835                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7836
7837        synchronized (this) {
7838            final int callingUid = Binder.getCallingUid();
7839            boolean persistChanged = false;
7840
7841            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7842                    new GrantUri(userId, uri, false));
7843            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7844                    new GrantUri(userId, uri, true));
7845            if (exactPerm == null && prefixPerm == null) {
7846                throw new SecurityException("No permission grants found for UID " + callingUid
7847                        + " and Uri " + uri.toSafeString());
7848            }
7849
7850            if (exactPerm != null) {
7851                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7852                removeUriPermissionIfNeededLocked(exactPerm);
7853            }
7854            if (prefixPerm != null) {
7855                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7856                removeUriPermissionIfNeededLocked(prefixPerm);
7857            }
7858
7859            if (persistChanged) {
7860                schedulePersistUriGrants();
7861            }
7862        }
7863    }
7864
7865    /**
7866     * Prune any older {@link UriPermission} for the given UID until outstanding
7867     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7868     *
7869     * @return if any mutations occured that require persisting.
7870     */
7871    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7872        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7873        if (perms == null) return false;
7874        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7875
7876        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7877        for (UriPermission perm : perms.values()) {
7878            if (perm.persistedModeFlags != 0) {
7879                persisted.add(perm);
7880            }
7881        }
7882
7883        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7884        if (trimCount <= 0) return false;
7885
7886        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7887        for (int i = 0; i < trimCount; i++) {
7888            final UriPermission perm = persisted.get(i);
7889
7890            if (DEBUG_URI_PERMISSION) {
7891                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7892            }
7893
7894            perm.releasePersistableModes(~0);
7895            removeUriPermissionIfNeededLocked(perm);
7896        }
7897
7898        return true;
7899    }
7900
7901    @Override
7902    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7903            String packageName, boolean incoming) {
7904        enforceNotIsolatedCaller("getPersistedUriPermissions");
7905        Preconditions.checkNotNull(packageName, "packageName");
7906
7907        final int callingUid = Binder.getCallingUid();
7908        final IPackageManager pm = AppGlobals.getPackageManager();
7909        try {
7910            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7911            if (packageUid != callingUid) {
7912                throw new SecurityException(
7913                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7914            }
7915        } catch (RemoteException e) {
7916            throw new SecurityException("Failed to verify package name ownership");
7917        }
7918
7919        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7920        synchronized (this) {
7921            if (incoming) {
7922                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7923                        callingUid);
7924                if (perms == null) {
7925                    Slog.w(TAG, "No permission grants found for " + packageName);
7926                } else {
7927                    for (UriPermission perm : perms.values()) {
7928                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7929                            result.add(perm.buildPersistedPublicApiObject());
7930                        }
7931                    }
7932                }
7933            } else {
7934                final int size = mGrantedUriPermissions.size();
7935                for (int i = 0; i < size; i++) {
7936                    final ArrayMap<GrantUri, UriPermission> perms =
7937                            mGrantedUriPermissions.valueAt(i);
7938                    for (UriPermission perm : perms.values()) {
7939                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7940                            result.add(perm.buildPersistedPublicApiObject());
7941                        }
7942                    }
7943                }
7944            }
7945        }
7946        return new ParceledListSlice<android.content.UriPermission>(result);
7947    }
7948
7949    @Override
7950    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7951        synchronized (this) {
7952            ProcessRecord app =
7953                who != null ? getRecordForAppLocked(who) : null;
7954            if (app == null) return;
7955
7956            Message msg = Message.obtain();
7957            msg.what = WAIT_FOR_DEBUGGER_MSG;
7958            msg.obj = app;
7959            msg.arg1 = waiting ? 1 : 0;
7960            mHandler.sendMessage(msg);
7961        }
7962    }
7963
7964    @Override
7965    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7966        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7967        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7968        outInfo.availMem = Process.getFreeMemory();
7969        outInfo.totalMem = Process.getTotalMemory();
7970        outInfo.threshold = homeAppMem;
7971        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7972        outInfo.hiddenAppThreshold = cachedAppMem;
7973        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7974                ProcessList.SERVICE_ADJ);
7975        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7976                ProcessList.VISIBLE_APP_ADJ);
7977        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7978                ProcessList.FOREGROUND_APP_ADJ);
7979    }
7980
7981    // =========================================================
7982    // TASK MANAGEMENT
7983    // =========================================================
7984
7985    @Override
7986    public List<IAppTask> getAppTasks(String callingPackage) {
7987        int callingUid = Binder.getCallingUid();
7988        long ident = Binder.clearCallingIdentity();
7989
7990        synchronized(this) {
7991            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7992            try {
7993                if (localLOGV) Slog.v(TAG, "getAppTasks");
7994
7995                final int N = mRecentTasks.size();
7996                for (int i = 0; i < N; i++) {
7997                    TaskRecord tr = mRecentTasks.get(i);
7998                    // Skip tasks that do not match the caller.  We don't need to verify
7999                    // callingPackage, because we are also limiting to callingUid and know
8000                    // that will limit to the correct security sandbox.
8001                    if (tr.effectiveUid != callingUid) {
8002                        continue;
8003                    }
8004                    Intent intent = tr.getBaseIntent();
8005                    if (intent == null ||
8006                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8007                        continue;
8008                    }
8009                    ActivityManager.RecentTaskInfo taskInfo =
8010                            createRecentTaskInfoFromTaskRecord(tr);
8011                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8012                    list.add(taskImpl);
8013                }
8014            } finally {
8015                Binder.restoreCallingIdentity(ident);
8016            }
8017            return list;
8018        }
8019    }
8020
8021    @Override
8022    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8023        final int callingUid = Binder.getCallingUid();
8024        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8025
8026        synchronized(this) {
8027            if (localLOGV) Slog.v(
8028                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8029
8030            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8031                    callingUid);
8032
8033            // TODO: Improve with MRU list from all ActivityStacks.
8034            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8035        }
8036
8037        return list;
8038    }
8039
8040    /**
8041     * Creates a new RecentTaskInfo from a TaskRecord.
8042     */
8043    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8044        // Update the task description to reflect any changes in the task stack
8045        tr.updateTaskDescription();
8046
8047        // Compose the recent task info
8048        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8049        rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8050        rti.persistentId = tr.taskId;
8051        rti.baseIntent = new Intent(tr.getBaseIntent());
8052        rti.origActivity = tr.origActivity;
8053        rti.description = tr.lastDescription;
8054        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8055        rti.userId = tr.userId;
8056        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8057        rti.firstActiveTime = tr.firstActiveTime;
8058        rti.lastActiveTime = tr.lastActiveTime;
8059        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8060        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8061        return rti;
8062    }
8063
8064    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8065        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8066                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8067        if (!allowed) {
8068            if (checkPermission(android.Manifest.permission.GET_TASKS,
8069                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8070                // Temporary compatibility: some existing apps on the system image may
8071                // still be requesting the old permission and not switched to the new
8072                // one; if so, we'll still allow them full access.  This means we need
8073                // to see if they are holding the old permission and are a system app.
8074                try {
8075                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8076                        allowed = true;
8077                        Slog.w(TAG, caller + ": caller " + callingUid
8078                                + " is using old GET_TASKS but privileged; allowing");
8079                    }
8080                } catch (RemoteException e) {
8081                }
8082            }
8083        }
8084        if (!allowed) {
8085            Slog.w(TAG, caller + ": caller " + callingUid
8086                    + " does not hold GET_TASKS; limiting output");
8087        }
8088        return allowed;
8089    }
8090
8091    @Override
8092    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8093        final int callingUid = Binder.getCallingUid();
8094        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8095                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8096
8097        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8098        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8099        synchronized (this) {
8100            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8101                    callingUid);
8102            final boolean detailed = checkCallingPermission(
8103                    android.Manifest.permission.GET_DETAILED_TASKS)
8104                    == PackageManager.PERMISSION_GRANTED;
8105
8106            final int N = mRecentTasks.size();
8107            ArrayList<ActivityManager.RecentTaskInfo> res
8108                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8109                            maxNum < N ? maxNum : N);
8110
8111            final Set<Integer> includedUsers;
8112            if (includeProfiles) {
8113                includedUsers = getProfileIdsLocked(userId);
8114            } else {
8115                includedUsers = new HashSet<Integer>();
8116            }
8117            includedUsers.add(Integer.valueOf(userId));
8118
8119            for (int i=0; i<N && maxNum > 0; i++) {
8120                TaskRecord tr = mRecentTasks.get(i);
8121                // Only add calling user or related users recent tasks
8122                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8123                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8124                    continue;
8125                }
8126
8127                // Return the entry if desired by the caller.  We always return
8128                // the first entry, because callers always expect this to be the
8129                // foreground app.  We may filter others if the caller has
8130                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8131                // we should exclude the entry.
8132
8133                if (i == 0
8134                        || withExcluded
8135                        || (tr.intent == null)
8136                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8137                                == 0)) {
8138                    if (!allowed) {
8139                        // If the caller doesn't have the GET_TASKS permission, then only
8140                        // allow them to see a small subset of tasks -- their own and home.
8141                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8142                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8143                            continue;
8144                        }
8145                    }
8146                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8147                        if (tr.stack != null && tr.stack.isHomeStack()) {
8148                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8149                            continue;
8150                        }
8151                    }
8152                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8153                        // Don't include auto remove tasks that are finished or finishing.
8154                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8155                                + tr);
8156                        continue;
8157                    }
8158                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8159                            && !tr.isAvailable) {
8160                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8161                        continue;
8162                    }
8163
8164                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8165                    if (!detailed) {
8166                        rti.baseIntent.replaceExtras((Bundle)null);
8167                    }
8168
8169                    res.add(rti);
8170                    maxNum--;
8171                }
8172            }
8173            return res;
8174        }
8175    }
8176
8177    private TaskRecord taskForIdLocked(int id) {
8178        final TaskRecord task = recentTaskForIdLocked(id);
8179        if (task != null) {
8180            return task;
8181        }
8182
8183        // Don't give up. Sometimes it just hasn't made it to recents yet.
8184        return mStackSupervisor.anyTaskForIdLocked(id);
8185    }
8186
8187    private TaskRecord recentTaskForIdLocked(int id) {
8188        final int N = mRecentTasks.size();
8189            for (int i=0; i<N; i++) {
8190                TaskRecord tr = mRecentTasks.get(i);
8191                if (tr.taskId == id) {
8192                    return tr;
8193                }
8194            }
8195            return null;
8196    }
8197
8198    @Override
8199    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8200        synchronized (this) {
8201            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8202                    "getTaskThumbnail()");
8203            TaskRecord tr = recentTaskForIdLocked(id);
8204            if (tr != null) {
8205                return tr.getTaskThumbnailLocked();
8206            }
8207        }
8208        return null;
8209    }
8210
8211    @Override
8212    public int addAppTask(IBinder activityToken, Intent intent,
8213            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8214        final int callingUid = Binder.getCallingUid();
8215        final long callingIdent = Binder.clearCallingIdentity();
8216
8217        try {
8218            synchronized (this) {
8219                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8220                if (r == null) {
8221                    throw new IllegalArgumentException("Activity does not exist; token="
8222                            + activityToken);
8223                }
8224                ComponentName comp = intent.getComponent();
8225                if (comp == null) {
8226                    throw new IllegalArgumentException("Intent " + intent
8227                            + " must specify explicit component");
8228                }
8229                if (thumbnail.getWidth() != mThumbnailWidth
8230                        || thumbnail.getHeight() != mThumbnailHeight) {
8231                    throw new IllegalArgumentException("Bad thumbnail size: got "
8232                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8233                            + mThumbnailWidth + "x" + mThumbnailHeight);
8234                }
8235                if (intent.getSelector() != null) {
8236                    intent.setSelector(null);
8237                }
8238                if (intent.getSourceBounds() != null) {
8239                    intent.setSourceBounds(null);
8240                }
8241                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8242                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8243                        // The caller has added this as an auto-remove task...  that makes no
8244                        // sense, so turn off auto-remove.
8245                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8246                    }
8247                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8248                    // Must be a new task.
8249                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8250                }
8251                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8252                    mLastAddedTaskActivity = null;
8253                }
8254                ActivityInfo ainfo = mLastAddedTaskActivity;
8255                if (ainfo == null) {
8256                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8257                            comp, 0, UserHandle.getUserId(callingUid));
8258                    if (ainfo.applicationInfo.uid != callingUid) {
8259                        throw new SecurityException(
8260                                "Can't add task for another application: target uid="
8261                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8262                    }
8263                }
8264
8265                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8266                        intent, description);
8267
8268                int trimIdx = trimRecentsForTaskLocked(task, false);
8269                if (trimIdx >= 0) {
8270                    // If this would have caused a trim, then we'll abort because that
8271                    // means it would be added at the end of the list but then just removed.
8272                    return INVALID_TASK_ID;
8273                }
8274
8275                final int N = mRecentTasks.size();
8276                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8277                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8278                    tr.removedFromRecents();
8279                }
8280
8281                task.inRecents = true;
8282                mRecentTasks.add(task);
8283                r.task.stack.addTask(task, false, false);
8284
8285                task.setLastThumbnail(thumbnail);
8286                task.freeLastThumbnail();
8287
8288                return task.taskId;
8289            }
8290        } finally {
8291            Binder.restoreCallingIdentity(callingIdent);
8292        }
8293    }
8294
8295    @Override
8296    public Point getAppTaskThumbnailSize() {
8297        synchronized (this) {
8298            return new Point(mThumbnailWidth,  mThumbnailHeight);
8299        }
8300    }
8301
8302    @Override
8303    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8304        synchronized (this) {
8305            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8306            if (r != null) {
8307                r.setTaskDescription(td);
8308                r.task.updateTaskDescription();
8309            }
8310        }
8311    }
8312
8313    @Override
8314    public Bitmap getTaskDescriptionIcon(String filename) {
8315        if (!FileUtils.isValidExtFilename(filename)
8316                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8317            throw new IllegalArgumentException("Bad filename: " + filename);
8318        }
8319        return mTaskPersister.getTaskDescriptionIcon(filename);
8320    }
8321
8322    @Override
8323    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8324            throws RemoteException {
8325        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8326                opts.getCustomInPlaceResId() == 0) {
8327            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8328                    "with valid animation");
8329        }
8330        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8331        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8332                opts.getCustomInPlaceResId());
8333        mWindowManager.executeAppTransition();
8334    }
8335
8336    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8337        mRecentTasks.remove(tr);
8338        tr.removedFromRecents();
8339        ComponentName component = tr.getBaseIntent().getComponent();
8340        if (component == null) {
8341            Slog.w(TAG, "No component for base intent of task: " + tr);
8342            return;
8343        }
8344
8345        if (!killProcess) {
8346            return;
8347        }
8348
8349        // Determine if the process(es) for this task should be killed.
8350        final String pkg = component.getPackageName();
8351        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8352        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8353        for (int i = 0; i < pmap.size(); i++) {
8354
8355            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8356            for (int j = 0; j < uids.size(); j++) {
8357                ProcessRecord proc = uids.valueAt(j);
8358                if (proc.userId != tr.userId) {
8359                    // Don't kill process for a different user.
8360                    continue;
8361                }
8362                if (proc == mHomeProcess) {
8363                    // Don't kill the home process along with tasks from the same package.
8364                    continue;
8365                }
8366                if (!proc.pkgList.containsKey(pkg)) {
8367                    // Don't kill process that is not associated with this task.
8368                    continue;
8369                }
8370
8371                for (int k = 0; k < proc.activities.size(); k++) {
8372                    TaskRecord otherTask = proc.activities.get(k).task;
8373                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8374                        // Don't kill process(es) that has an activity in a different task that is
8375                        // also in recents.
8376                        return;
8377                    }
8378                }
8379
8380                // Add process to kill list.
8381                procsToKill.add(proc);
8382            }
8383        }
8384
8385        // Find any running services associated with this app and stop if needed.
8386        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8387
8388        // Kill the running processes.
8389        for (int i = 0; i < procsToKill.size(); i++) {
8390            ProcessRecord pr = procsToKill.get(i);
8391            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8392                pr.kill("remove task", true);
8393            } else {
8394                pr.waitingToKill = "remove task";
8395            }
8396        }
8397    }
8398
8399    private void removeTasksByPackageNameLocked(String packageName, int userId) {
8400        // Remove all tasks with activities in the specified package from the list of recent tasks
8401        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8402            TaskRecord tr = mRecentTasks.get(i);
8403            if (tr.userId != userId) continue;
8404
8405            ComponentName cn = tr.intent.getComponent();
8406            if (cn != null && cn.getPackageName().equals(packageName)) {
8407                // If the package name matches, remove the task.
8408                removeTaskByIdLocked(tr.taskId, true);
8409            }
8410        }
8411    }
8412
8413    private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8414        final IPackageManager pm = AppGlobals.getPackageManager();
8415        final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8416
8417        for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8418            TaskRecord tr = mRecentTasks.get(i);
8419            if (tr.userId != userId) continue;
8420
8421            ComponentName cn = tr.intent.getComponent();
8422            if (cn != null && cn.getPackageName().equals(packageName)) {
8423                // Skip if component still exists in the package.
8424                if (componentsKnownToExist.contains(cn)) continue;
8425
8426                try {
8427                    ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8428                    if (info != null) {
8429                        componentsKnownToExist.add(cn);
8430                    } else {
8431                        removeTaskByIdLocked(tr.taskId, false);
8432                    }
8433                } catch (RemoteException e) {
8434                    Log.e(TAG, "Activity info query failed. component=" + cn, e);
8435                }
8436            }
8437        }
8438    }
8439
8440    /**
8441     * Removes the task with the specified task id.
8442     *
8443     * @param taskId Identifier of the task to be removed.
8444     * @param killProcess Kill any process associated with the task if possible.
8445     * @return Returns true if the given task was found and removed.
8446     */
8447    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8448        TaskRecord tr = taskForIdLocked(taskId);
8449        if (tr != null) {
8450            tr.removeTaskActivitiesLocked();
8451            cleanUpRemovedTaskLocked(tr, killProcess);
8452            if (tr.isPersistable) {
8453                notifyTaskPersisterLocked(null, true);
8454            }
8455            return true;
8456        }
8457        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8458        return false;
8459    }
8460
8461    @Override
8462    public boolean removeTask(int taskId) {
8463        synchronized (this) {
8464            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8465                    "removeTask()");
8466            long ident = Binder.clearCallingIdentity();
8467            try {
8468                return removeTaskByIdLocked(taskId, true);
8469            } finally {
8470                Binder.restoreCallingIdentity(ident);
8471            }
8472        }
8473    }
8474
8475    /**
8476     * TODO: Add mController hook
8477     */
8478    @Override
8479    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8480        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8481                "moveTaskToFront()");
8482
8483        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8484        synchronized(this) {
8485            moveTaskToFrontLocked(taskId, flags, options);
8486        }
8487    }
8488
8489    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8490        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8491                Binder.getCallingUid(), -1, -1, "Task to front")) {
8492            ActivityOptions.abort(options);
8493            return;
8494        }
8495        final long origId = Binder.clearCallingIdentity();
8496        try {
8497            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8498            if (task == null) {
8499                Slog.d(TAG, "Could not find task for id: "+ taskId);
8500                return;
8501            }
8502            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8503                mStackSupervisor.showLockTaskToast();
8504                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8505                return;
8506            }
8507            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8508            if (prev != null && prev.isRecentsActivity()) {
8509                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8510            }
8511            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8512        } finally {
8513            Binder.restoreCallingIdentity(origId);
8514        }
8515        ActivityOptions.abort(options);
8516    }
8517
8518    @Override
8519    public void moveTaskToBack(int taskId) {
8520        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8521                "moveTaskToBack()");
8522
8523        synchronized(this) {
8524            TaskRecord tr = taskForIdLocked(taskId);
8525            if (tr != null) {
8526                if (tr == mStackSupervisor.mLockTaskModeTask) {
8527                    mStackSupervisor.showLockTaskToast();
8528                    return;
8529                }
8530                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8531                ActivityStack stack = tr.stack;
8532                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8533                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8534                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8535                        return;
8536                    }
8537                }
8538                final long origId = Binder.clearCallingIdentity();
8539                try {
8540                    stack.moveTaskToBackLocked(taskId, null);
8541                } finally {
8542                    Binder.restoreCallingIdentity(origId);
8543                }
8544            }
8545        }
8546    }
8547
8548    /**
8549     * Moves an activity, and all of the other activities within the same task, to the bottom
8550     * of the history stack.  The activity's order within the task is unchanged.
8551     *
8552     * @param token A reference to the activity we wish to move
8553     * @param nonRoot If false then this only works if the activity is the root
8554     *                of a task; if true it will work for any activity in a task.
8555     * @return Returns true if the move completed, false if not.
8556     */
8557    @Override
8558    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8559        enforceNotIsolatedCaller("moveActivityTaskToBack");
8560        synchronized(this) {
8561            final long origId = Binder.clearCallingIdentity();
8562            try {
8563                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8564                if (taskId >= 0) {
8565                    if ((mStackSupervisor.mLockTaskModeTask != null)
8566                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8567                        mStackSupervisor.showLockTaskToast();
8568                        return false;
8569                    }
8570                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8571                }
8572            } finally {
8573                Binder.restoreCallingIdentity(origId);
8574            }
8575        }
8576        return false;
8577    }
8578
8579    @Override
8580    public void moveTaskBackwards(int task) {
8581        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8582                "moveTaskBackwards()");
8583
8584        synchronized(this) {
8585            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8586                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8587                return;
8588            }
8589            final long origId = Binder.clearCallingIdentity();
8590            moveTaskBackwardsLocked(task);
8591            Binder.restoreCallingIdentity(origId);
8592        }
8593    }
8594
8595    private final void moveTaskBackwardsLocked(int task) {
8596        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8597    }
8598
8599    @Override
8600    public IBinder getHomeActivityToken() throws RemoteException {
8601        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8602                "getHomeActivityToken()");
8603        synchronized (this) {
8604            return mStackSupervisor.getHomeActivityToken();
8605        }
8606    }
8607
8608    @Override
8609    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8610            IActivityContainerCallback callback) throws RemoteException {
8611        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8612                "createActivityContainer()");
8613        synchronized (this) {
8614            if (parentActivityToken == null) {
8615                throw new IllegalArgumentException("parent token must not be null");
8616            }
8617            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8618            if (r == null) {
8619                return null;
8620            }
8621            if (callback == null) {
8622                throw new IllegalArgumentException("callback must not be null");
8623            }
8624            return mStackSupervisor.createActivityContainer(r, callback);
8625        }
8626    }
8627
8628    @Override
8629    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8630        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8631                "deleteActivityContainer()");
8632        synchronized (this) {
8633            mStackSupervisor.deleteActivityContainer(container);
8634        }
8635    }
8636
8637    @Override
8638    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8639            throws RemoteException {
8640        synchronized (this) {
8641            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8642            if (stack != null) {
8643                return stack.mActivityContainer;
8644            }
8645            return null;
8646        }
8647    }
8648
8649    @Override
8650    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8651        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8652                "moveTaskToStack()");
8653        if (stackId == HOME_STACK_ID) {
8654            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8655                    new RuntimeException("here").fillInStackTrace());
8656        }
8657        synchronized (this) {
8658            long ident = Binder.clearCallingIdentity();
8659            try {
8660                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8661                        + stackId + " toTop=" + toTop);
8662                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8663            } finally {
8664                Binder.restoreCallingIdentity(ident);
8665            }
8666        }
8667    }
8668
8669    @Override
8670    public void resizeStack(int stackBoxId, Rect bounds) {
8671        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8672                "resizeStackBox()");
8673        long ident = Binder.clearCallingIdentity();
8674        try {
8675            mWindowManager.resizeStack(stackBoxId, bounds);
8676        } finally {
8677            Binder.restoreCallingIdentity(ident);
8678        }
8679    }
8680
8681    @Override
8682    public List<StackInfo> getAllStackInfos() {
8683        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8684                "getAllStackInfos()");
8685        long ident = Binder.clearCallingIdentity();
8686        try {
8687            synchronized (this) {
8688                return mStackSupervisor.getAllStackInfosLocked();
8689            }
8690        } finally {
8691            Binder.restoreCallingIdentity(ident);
8692        }
8693    }
8694
8695    @Override
8696    public StackInfo getStackInfo(int stackId) {
8697        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8698                "getStackInfo()");
8699        long ident = Binder.clearCallingIdentity();
8700        try {
8701            synchronized (this) {
8702                return mStackSupervisor.getStackInfoLocked(stackId);
8703            }
8704        } finally {
8705            Binder.restoreCallingIdentity(ident);
8706        }
8707    }
8708
8709    @Override
8710    public boolean isInHomeStack(int taskId) {
8711        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8712                "getStackInfo()");
8713        long ident = Binder.clearCallingIdentity();
8714        try {
8715            synchronized (this) {
8716                TaskRecord tr = taskForIdLocked(taskId);
8717                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8718            }
8719        } finally {
8720            Binder.restoreCallingIdentity(ident);
8721        }
8722    }
8723
8724    @Override
8725    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8726        synchronized(this) {
8727            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8728        }
8729    }
8730
8731    private boolean isLockTaskAuthorized(String pkg) {
8732        final DevicePolicyManager dpm = (DevicePolicyManager)
8733                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8734        try {
8735            int uid = mContext.getPackageManager().getPackageUid(pkg,
8736                    Binder.getCallingUserHandle().getIdentifier());
8737            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8738        } catch (NameNotFoundException e) {
8739            return false;
8740        }
8741    }
8742
8743    void startLockTaskMode(TaskRecord task) {
8744        final String pkg;
8745        synchronized (this) {
8746            pkg = task.intent.getComponent().getPackageName();
8747        }
8748        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8749        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8750            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8751                    StatusBarManagerInternal.class);
8752            if (statusBarManager != null) {
8753                statusBarManager.showScreenPinningRequest();
8754            }
8755            return;
8756        }
8757        long ident = Binder.clearCallingIdentity();
8758        try {
8759            synchronized (this) {
8760                // Since we lost lock on task, make sure it is still there.
8761                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8762                if (task != null) {
8763                    if (!isSystemInitiated
8764                            && ((mStackSupervisor.getFocusedStack() == null)
8765                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8766                        throw new IllegalArgumentException("Invalid task, not in foreground");
8767                    }
8768                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8769                }
8770            }
8771        } finally {
8772            Binder.restoreCallingIdentity(ident);
8773        }
8774    }
8775
8776    @Override
8777    public void startLockTaskMode(int taskId) {
8778        final TaskRecord task;
8779        long ident = Binder.clearCallingIdentity();
8780        try {
8781            synchronized (this) {
8782                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8783            }
8784        } finally {
8785            Binder.restoreCallingIdentity(ident);
8786        }
8787        if (task != null) {
8788            startLockTaskMode(task);
8789        }
8790    }
8791
8792    @Override
8793    public void startLockTaskMode(IBinder token) {
8794        final TaskRecord task;
8795        long ident = Binder.clearCallingIdentity();
8796        try {
8797            synchronized (this) {
8798                final ActivityRecord r = ActivityRecord.forToken(token);
8799                if (r == null) {
8800                    return;
8801                }
8802                task = r.task;
8803            }
8804        } finally {
8805            Binder.restoreCallingIdentity(ident);
8806        }
8807        if (task != null) {
8808            startLockTaskMode(task);
8809        }
8810    }
8811
8812    @Override
8813    public void startLockTaskModeOnCurrent() throws RemoteException {
8814        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8815                "startLockTaskModeOnCurrent");
8816        long ident = Binder.clearCallingIdentity();
8817        try {
8818            ActivityRecord r = null;
8819            synchronized (this) {
8820                r = mStackSupervisor.topRunningActivityLocked();
8821            }
8822            startLockTaskMode(r.task);
8823        } finally {
8824            Binder.restoreCallingIdentity(ident);
8825        }
8826    }
8827
8828    @Override
8829    public void stopLockTaskMode() {
8830        // Verify that the user matches the package of the intent for the TaskRecord
8831        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8832        // and stopLockTaskMode.
8833        final int callingUid = Binder.getCallingUid();
8834        if (callingUid != Process.SYSTEM_UID) {
8835            try {
8836                String pkg =
8837                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8838                int uid = mContext.getPackageManager().getPackageUid(pkg,
8839                        Binder.getCallingUserHandle().getIdentifier());
8840                if (uid != callingUid) {
8841                    throw new SecurityException("Invalid uid, expected " + uid);
8842                }
8843            } catch (NameNotFoundException e) {
8844                Log.d(TAG, "stopLockTaskMode " + e);
8845                return;
8846            }
8847        }
8848        long ident = Binder.clearCallingIdentity();
8849        try {
8850            Log.d(TAG, "stopLockTaskMode");
8851            // Stop lock task
8852            synchronized (this) {
8853                mStackSupervisor.setLockTaskModeLocked(null, false);
8854            }
8855        } finally {
8856            Binder.restoreCallingIdentity(ident);
8857        }
8858    }
8859
8860    @Override
8861    public void stopLockTaskModeOnCurrent() throws RemoteException {
8862        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8863                "stopLockTaskModeOnCurrent");
8864        long ident = Binder.clearCallingIdentity();
8865        try {
8866            stopLockTaskMode();
8867        } finally {
8868            Binder.restoreCallingIdentity(ident);
8869        }
8870    }
8871
8872    @Override
8873    public boolean isInLockTaskMode() {
8874        synchronized (this) {
8875            return mStackSupervisor.isInLockTaskMode();
8876        }
8877    }
8878
8879    // =========================================================
8880    // CONTENT PROVIDERS
8881    // =========================================================
8882
8883    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8884        List<ProviderInfo> providers = null;
8885        try {
8886            providers = AppGlobals.getPackageManager().
8887                queryContentProviders(app.processName, app.uid,
8888                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8889        } catch (RemoteException ex) {
8890        }
8891        if (DEBUG_MU)
8892            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8893        int userId = app.userId;
8894        if (providers != null) {
8895            int N = providers.size();
8896            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8897            for (int i=0; i<N; i++) {
8898                ProviderInfo cpi =
8899                    (ProviderInfo)providers.get(i);
8900                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8901                        cpi.name, cpi.flags);
8902                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8903                    // This is a singleton provider, but a user besides the
8904                    // default user is asking to initialize a process it runs
8905                    // in...  well, no, it doesn't actually run in this process,
8906                    // it runs in the process of the default user.  Get rid of it.
8907                    providers.remove(i);
8908                    N--;
8909                    i--;
8910                    continue;
8911                }
8912
8913                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8914                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8915                if (cpr == null) {
8916                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8917                    mProviderMap.putProviderByClass(comp, cpr);
8918                }
8919                if (DEBUG_MU)
8920                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8921                app.pubProviders.put(cpi.name, cpr);
8922                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8923                    // Don't add this if it is a platform component that is marked
8924                    // to run in multiple processes, because this is actually
8925                    // part of the framework so doesn't make sense to track as a
8926                    // separate apk in the process.
8927                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8928                            mProcessStats);
8929                }
8930                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8931            }
8932        }
8933        return providers;
8934    }
8935
8936    /**
8937     * Check if {@link ProcessRecord} has a possible chance at accessing the
8938     * given {@link ProviderInfo}. Final permission checking is always done
8939     * in {@link ContentProvider}.
8940     */
8941    private final String checkContentProviderPermissionLocked(
8942            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8943        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8944        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8945        boolean checkedGrants = false;
8946        if (checkUser) {
8947            // Looking for cross-user grants before enforcing the typical cross-users permissions
8948            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8949            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8950                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8951                    return null;
8952                }
8953                checkedGrants = true;
8954            }
8955            userId = handleIncomingUser(callingPid, callingUid, userId,
8956                    false, ALLOW_NON_FULL,
8957                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8958            if (userId != tmpTargetUserId) {
8959                // When we actually went to determine the final targer user ID, this ended
8960                // up different than our initial check for the authority.  This is because
8961                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8962                // SELF.  So we need to re-check the grants again.
8963                checkedGrants = false;
8964            }
8965        }
8966        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8967                cpi.applicationInfo.uid, cpi.exported)
8968                == PackageManager.PERMISSION_GRANTED) {
8969            return null;
8970        }
8971        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8972                cpi.applicationInfo.uid, cpi.exported)
8973                == PackageManager.PERMISSION_GRANTED) {
8974            return null;
8975        }
8976
8977        PathPermission[] pps = cpi.pathPermissions;
8978        if (pps != null) {
8979            int i = pps.length;
8980            while (i > 0) {
8981                i--;
8982                PathPermission pp = pps[i];
8983                String pprperm = pp.getReadPermission();
8984                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8985                        cpi.applicationInfo.uid, cpi.exported)
8986                        == PackageManager.PERMISSION_GRANTED) {
8987                    return null;
8988                }
8989                String ppwperm = pp.getWritePermission();
8990                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8991                        cpi.applicationInfo.uid, cpi.exported)
8992                        == PackageManager.PERMISSION_GRANTED) {
8993                    return null;
8994                }
8995            }
8996        }
8997        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8998            return null;
8999        }
9000
9001        String msg;
9002        if (!cpi.exported) {
9003            msg = "Permission Denial: opening provider " + cpi.name
9004                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9005                    + ", uid=" + callingUid + ") that is not exported from uid "
9006                    + cpi.applicationInfo.uid;
9007        } else {
9008            msg = "Permission Denial: opening provider " + cpi.name
9009                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9010                    + ", uid=" + callingUid + ") requires "
9011                    + cpi.readPermission + " or " + cpi.writePermission;
9012        }
9013        Slog.w(TAG, msg);
9014        return msg;
9015    }
9016
9017    /**
9018     * Returns if the ContentProvider has granted a uri to callingUid
9019     */
9020    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9021        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9022        if (perms != null) {
9023            for (int i=perms.size()-1; i>=0; i--) {
9024                GrantUri grantUri = perms.keyAt(i);
9025                if (grantUri.sourceUserId == userId || !checkUser) {
9026                    if (matchesProvider(grantUri.uri, cpi)) {
9027                        return true;
9028                    }
9029                }
9030            }
9031        }
9032        return false;
9033    }
9034
9035    /**
9036     * Returns true if the uri authority is one of the authorities specified in the provider.
9037     */
9038    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9039        String uriAuth = uri.getAuthority();
9040        String cpiAuth = cpi.authority;
9041        if (cpiAuth.indexOf(';') == -1) {
9042            return cpiAuth.equals(uriAuth);
9043        }
9044        String[] cpiAuths = cpiAuth.split(";");
9045        int length = cpiAuths.length;
9046        for (int i = 0; i < length; i++) {
9047            if (cpiAuths[i].equals(uriAuth)) return true;
9048        }
9049        return false;
9050    }
9051
9052    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9053            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9054        if (r != null) {
9055            for (int i=0; i<r.conProviders.size(); i++) {
9056                ContentProviderConnection conn = r.conProviders.get(i);
9057                if (conn.provider == cpr) {
9058                    if (DEBUG_PROVIDER) Slog.v(TAG,
9059                            "Adding provider requested by "
9060                            + r.processName + " from process "
9061                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9062                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9063                    if (stable) {
9064                        conn.stableCount++;
9065                        conn.numStableIncs++;
9066                    } else {
9067                        conn.unstableCount++;
9068                        conn.numUnstableIncs++;
9069                    }
9070                    return conn;
9071                }
9072            }
9073            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9074            if (stable) {
9075                conn.stableCount = 1;
9076                conn.numStableIncs = 1;
9077            } else {
9078                conn.unstableCount = 1;
9079                conn.numUnstableIncs = 1;
9080            }
9081            cpr.connections.add(conn);
9082            r.conProviders.add(conn);
9083            return conn;
9084        }
9085        cpr.addExternalProcessHandleLocked(externalProcessToken);
9086        return null;
9087    }
9088
9089    boolean decProviderCountLocked(ContentProviderConnection conn,
9090            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9091        if (conn != null) {
9092            cpr = conn.provider;
9093            if (DEBUG_PROVIDER) Slog.v(TAG,
9094                    "Removing provider requested by "
9095                    + conn.client.processName + " from process "
9096                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9097                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9098            if (stable) {
9099                conn.stableCount--;
9100            } else {
9101                conn.unstableCount--;
9102            }
9103            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9104                cpr.connections.remove(conn);
9105                conn.client.conProviders.remove(conn);
9106                return true;
9107            }
9108            return false;
9109        }
9110        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9111        return false;
9112    }
9113
9114    private void checkTime(long startTime, String where) {
9115        long now = SystemClock.elapsedRealtime();
9116        if ((now-startTime) > 1000) {
9117            // If we are taking more than a second, log about it.
9118            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9119        }
9120    }
9121
9122    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9123            String name, IBinder token, boolean stable, int userId) {
9124        ContentProviderRecord cpr;
9125        ContentProviderConnection conn = null;
9126        ProviderInfo cpi = null;
9127
9128        synchronized(this) {
9129            long startTime = SystemClock.elapsedRealtime();
9130
9131            ProcessRecord r = null;
9132            if (caller != null) {
9133                r = getRecordForAppLocked(caller);
9134                if (r == null) {
9135                    throw new SecurityException(
9136                            "Unable to find app for caller " + caller
9137                          + " (pid=" + Binder.getCallingPid()
9138                          + ") when getting content provider " + name);
9139                }
9140            }
9141
9142            boolean checkCrossUser = true;
9143
9144            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9145
9146            // First check if this content provider has been published...
9147            cpr = mProviderMap.getProviderByName(name, userId);
9148            // If that didn't work, check if it exists for user 0 and then
9149            // verify that it's a singleton provider before using it.
9150            if (cpr == null && userId != UserHandle.USER_OWNER) {
9151                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9152                if (cpr != null) {
9153                    cpi = cpr.info;
9154                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9155                            cpi.name, cpi.flags)
9156                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9157                        userId = UserHandle.USER_OWNER;
9158                        checkCrossUser = false;
9159                    } else {
9160                        cpr = null;
9161                        cpi = null;
9162                    }
9163                }
9164            }
9165
9166            boolean providerRunning = cpr != null;
9167            if (providerRunning) {
9168                cpi = cpr.info;
9169                String msg;
9170                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9171                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9172                        != null) {
9173                    throw new SecurityException(msg);
9174                }
9175                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9176
9177                if (r != null && cpr.canRunHere(r)) {
9178                    // This provider has been published or is in the process
9179                    // of being published...  but it is also allowed to run
9180                    // in the caller's process, so don't make a connection
9181                    // and just let the caller instantiate its own instance.
9182                    ContentProviderHolder holder = cpr.newHolder(null);
9183                    // don't give caller the provider object, it needs
9184                    // to make its own.
9185                    holder.provider = null;
9186                    return holder;
9187                }
9188
9189                final long origId = Binder.clearCallingIdentity();
9190
9191                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9192
9193                // In this case the provider instance already exists, so we can
9194                // return it right away.
9195                conn = incProviderCountLocked(r, cpr, token, stable);
9196                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9197                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9198                        // If this is a perceptible app accessing the provider,
9199                        // make sure to count it as being accessed and thus
9200                        // back up on the LRU list.  This is good because
9201                        // content providers are often expensive to start.
9202                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9203                        updateLruProcessLocked(cpr.proc, false, null);
9204                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9205                    }
9206                }
9207
9208                if (cpr.proc != null) {
9209                    if (false) {
9210                        if (cpr.name.flattenToShortString().equals(
9211                                "com.android.providers.calendar/.CalendarProvider2")) {
9212                            Slog.v(TAG, "****************** KILLING "
9213                                + cpr.name.flattenToShortString());
9214                            Process.killProcess(cpr.proc.pid);
9215                        }
9216                    }
9217                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9218                    boolean success = updateOomAdjLocked(cpr.proc);
9219                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9220                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9221                    // NOTE: there is still a race here where a signal could be
9222                    // pending on the process even though we managed to update its
9223                    // adj level.  Not sure what to do about this, but at least
9224                    // the race is now smaller.
9225                    if (!success) {
9226                        // Uh oh...  it looks like the provider's process
9227                        // has been killed on us.  We need to wait for a new
9228                        // process to be started, and make sure its death
9229                        // doesn't kill our process.
9230                        Slog.i(TAG,
9231                                "Existing provider " + cpr.name.flattenToShortString()
9232                                + " is crashing; detaching " + r);
9233                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9234                        checkTime(startTime, "getContentProviderImpl: before appDied");
9235                        appDiedLocked(cpr.proc);
9236                        checkTime(startTime, "getContentProviderImpl: after appDied");
9237                        if (!lastRef) {
9238                            // This wasn't the last ref our process had on
9239                            // the provider...  we have now been killed, bail.
9240                            return null;
9241                        }
9242                        providerRunning = false;
9243                        conn = null;
9244                    }
9245                }
9246
9247                Binder.restoreCallingIdentity(origId);
9248            }
9249
9250            boolean singleton;
9251            if (!providerRunning) {
9252                try {
9253                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9254                    cpi = AppGlobals.getPackageManager().
9255                        resolveContentProvider(name,
9256                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9257                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9258                } catch (RemoteException ex) {
9259                }
9260                if (cpi == null) {
9261                    return null;
9262                }
9263                // If the provider is a singleton AND
9264                // (it's a call within the same user || the provider is a
9265                // privileged app)
9266                // Then allow connecting to the singleton provider
9267                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9268                        cpi.name, cpi.flags)
9269                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9270                if (singleton) {
9271                    userId = UserHandle.USER_OWNER;
9272                }
9273                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9274                checkTime(startTime, "getContentProviderImpl: got app info for user");
9275
9276                String msg;
9277                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9278                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9279                        != null) {
9280                    throw new SecurityException(msg);
9281                }
9282                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9283
9284                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9285                        && !cpi.processName.equals("system")) {
9286                    // If this content provider does not run in the system
9287                    // process, and the system is not yet ready to run other
9288                    // processes, then fail fast instead of hanging.
9289                    throw new IllegalArgumentException(
9290                            "Attempt to launch content provider before system ready");
9291                }
9292
9293                // Make sure that the user who owns this provider is started.  If not,
9294                // we don't want to allow it to run.
9295                if (mStartedUsers.get(userId) == null) {
9296                    Slog.w(TAG, "Unable to launch app "
9297                            + cpi.applicationInfo.packageName + "/"
9298                            + cpi.applicationInfo.uid + " for provider "
9299                            + name + ": user " + userId + " is stopped");
9300                    return null;
9301                }
9302
9303                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9304                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9305                cpr = mProviderMap.getProviderByClass(comp, userId);
9306                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9307                final boolean firstClass = cpr == null;
9308                if (firstClass) {
9309                    final long ident = Binder.clearCallingIdentity();
9310                    try {
9311                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9312                        ApplicationInfo ai =
9313                            AppGlobals.getPackageManager().
9314                                getApplicationInfo(
9315                                        cpi.applicationInfo.packageName,
9316                                        STOCK_PM_FLAGS, userId);
9317                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9318                        if (ai == null) {
9319                            Slog.w(TAG, "No package info for content provider "
9320                                    + cpi.name);
9321                            return null;
9322                        }
9323                        ai = getAppInfoForUser(ai, userId);
9324                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9325                    } catch (RemoteException ex) {
9326                        // pm is in same process, this will never happen.
9327                    } finally {
9328                        Binder.restoreCallingIdentity(ident);
9329                    }
9330                }
9331
9332                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9333
9334                if (r != null && cpr.canRunHere(r)) {
9335                    // If this is a multiprocess provider, then just return its
9336                    // info and allow the caller to instantiate it.  Only do
9337                    // this if the provider is the same user as the caller's
9338                    // process, or can run as root (so can be in any process).
9339                    return cpr.newHolder(null);
9340                }
9341
9342                if (DEBUG_PROVIDER) {
9343                    RuntimeException e = new RuntimeException("here");
9344                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9345                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9346                }
9347
9348                // This is single process, and our app is now connecting to it.
9349                // See if we are already in the process of launching this
9350                // provider.
9351                final int N = mLaunchingProviders.size();
9352                int i;
9353                for (i=0; i<N; i++) {
9354                    if (mLaunchingProviders.get(i) == cpr) {
9355                        break;
9356                    }
9357                }
9358
9359                // If the provider is not already being launched, then get it
9360                // started.
9361                if (i >= N) {
9362                    final long origId = Binder.clearCallingIdentity();
9363
9364                    try {
9365                        // Content provider is now in use, its package can't be stopped.
9366                        try {
9367                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9368                            AppGlobals.getPackageManager().setPackageStoppedState(
9369                                    cpr.appInfo.packageName, false, userId);
9370                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9371                        } catch (RemoteException e) {
9372                        } catch (IllegalArgumentException e) {
9373                            Slog.w(TAG, "Failed trying to unstop package "
9374                                    + cpr.appInfo.packageName + ": " + e);
9375                        }
9376
9377                        // Use existing process if already started
9378                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9379                        ProcessRecord proc = getProcessRecordLocked(
9380                                cpi.processName, cpr.appInfo.uid, false);
9381                        if (proc != null && proc.thread != null) {
9382                            if (DEBUG_PROVIDER) {
9383                                Slog.d(TAG, "Installing in existing process " + proc);
9384                            }
9385                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9386                            proc.pubProviders.put(cpi.name, cpr);
9387                            try {
9388                                proc.thread.scheduleInstallProvider(cpi);
9389                            } catch (RemoteException e) {
9390                            }
9391                        } else {
9392                            checkTime(startTime, "getContentProviderImpl: before start process");
9393                            proc = startProcessLocked(cpi.processName,
9394                                    cpr.appInfo, false, 0, "content provider",
9395                                    new ComponentName(cpi.applicationInfo.packageName,
9396                                            cpi.name), false, false, false);
9397                            checkTime(startTime, "getContentProviderImpl: after start process");
9398                            if (proc == null) {
9399                                Slog.w(TAG, "Unable to launch app "
9400                                        + cpi.applicationInfo.packageName + "/"
9401                                        + cpi.applicationInfo.uid + " for provider "
9402                                        + name + ": process is bad");
9403                                return null;
9404                            }
9405                        }
9406                        cpr.launchingApp = proc;
9407                        mLaunchingProviders.add(cpr);
9408                    } finally {
9409                        Binder.restoreCallingIdentity(origId);
9410                    }
9411                }
9412
9413                checkTime(startTime, "getContentProviderImpl: updating data structures");
9414
9415                // Make sure the provider is published (the same provider class
9416                // may be published under multiple names).
9417                if (firstClass) {
9418                    mProviderMap.putProviderByClass(comp, cpr);
9419                }
9420
9421                mProviderMap.putProviderByName(name, cpr);
9422                conn = incProviderCountLocked(r, cpr, token, stable);
9423                if (conn != null) {
9424                    conn.waiting = true;
9425                }
9426            }
9427            checkTime(startTime, "getContentProviderImpl: done!");
9428        }
9429
9430        // Wait for the provider to be published...
9431        synchronized (cpr) {
9432            while (cpr.provider == null) {
9433                if (cpr.launchingApp == null) {
9434                    Slog.w(TAG, "Unable to launch app "
9435                            + cpi.applicationInfo.packageName + "/"
9436                            + cpi.applicationInfo.uid + " for provider "
9437                            + name + ": launching app became null");
9438                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9439                            UserHandle.getUserId(cpi.applicationInfo.uid),
9440                            cpi.applicationInfo.packageName,
9441                            cpi.applicationInfo.uid, name);
9442                    return null;
9443                }
9444                try {
9445                    if (DEBUG_MU) {
9446                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9447                                + cpr.launchingApp);
9448                    }
9449                    if (conn != null) {
9450                        conn.waiting = true;
9451                    }
9452                    cpr.wait();
9453                } catch (InterruptedException ex) {
9454                } finally {
9455                    if (conn != null) {
9456                        conn.waiting = false;
9457                    }
9458                }
9459            }
9460        }
9461        return cpr != null ? cpr.newHolder(conn) : null;
9462    }
9463
9464    @Override
9465    public final ContentProviderHolder getContentProvider(
9466            IApplicationThread caller, String name, int userId, boolean stable) {
9467        enforceNotIsolatedCaller("getContentProvider");
9468        if (caller == null) {
9469            String msg = "null IApplicationThread when getting content provider "
9470                    + name;
9471            Slog.w(TAG, msg);
9472            throw new SecurityException(msg);
9473        }
9474        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9475        // with cross-user grant.
9476        return getContentProviderImpl(caller, name, null, stable, userId);
9477    }
9478
9479    public ContentProviderHolder getContentProviderExternal(
9480            String name, int userId, IBinder token) {
9481        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9482            "Do not have permission in call getContentProviderExternal()");
9483        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9484                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9485        return getContentProviderExternalUnchecked(name, token, userId);
9486    }
9487
9488    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9489            IBinder token, int userId) {
9490        return getContentProviderImpl(null, name, token, true, userId);
9491    }
9492
9493    /**
9494     * Drop a content provider from a ProcessRecord's bookkeeping
9495     */
9496    public void removeContentProvider(IBinder connection, boolean stable) {
9497        enforceNotIsolatedCaller("removeContentProvider");
9498        long ident = Binder.clearCallingIdentity();
9499        try {
9500            synchronized (this) {
9501                ContentProviderConnection conn;
9502                try {
9503                    conn = (ContentProviderConnection)connection;
9504                } catch (ClassCastException e) {
9505                    String msg ="removeContentProvider: " + connection
9506                            + " not a ContentProviderConnection";
9507                    Slog.w(TAG, msg);
9508                    throw new IllegalArgumentException(msg);
9509                }
9510                if (conn == null) {
9511                    throw new NullPointerException("connection is null");
9512                }
9513                if (decProviderCountLocked(conn, null, null, stable)) {
9514                    updateOomAdjLocked();
9515                }
9516            }
9517        } finally {
9518            Binder.restoreCallingIdentity(ident);
9519        }
9520    }
9521
9522    public void removeContentProviderExternal(String name, IBinder token) {
9523        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9524            "Do not have permission in call removeContentProviderExternal()");
9525        int userId = UserHandle.getCallingUserId();
9526        long ident = Binder.clearCallingIdentity();
9527        try {
9528            removeContentProviderExternalUnchecked(name, token, userId);
9529        } finally {
9530            Binder.restoreCallingIdentity(ident);
9531        }
9532    }
9533
9534    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9535        synchronized (this) {
9536            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9537            if(cpr == null) {
9538                //remove from mProvidersByClass
9539                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9540                return;
9541            }
9542
9543            //update content provider record entry info
9544            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9545            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9546            if (localCpr.hasExternalProcessHandles()) {
9547                if (localCpr.removeExternalProcessHandleLocked(token)) {
9548                    updateOomAdjLocked();
9549                } else {
9550                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9551                            + " with no external reference for token: "
9552                            + token + ".");
9553                }
9554            } else {
9555                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9556                        + " with no external references.");
9557            }
9558        }
9559    }
9560
9561    public final void publishContentProviders(IApplicationThread caller,
9562            List<ContentProviderHolder> providers) {
9563        if (providers == null) {
9564            return;
9565        }
9566
9567        enforceNotIsolatedCaller("publishContentProviders");
9568        synchronized (this) {
9569            final ProcessRecord r = getRecordForAppLocked(caller);
9570            if (DEBUG_MU)
9571                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9572            if (r == null) {
9573                throw new SecurityException(
9574                        "Unable to find app for caller " + caller
9575                      + " (pid=" + Binder.getCallingPid()
9576                      + ") when publishing content providers");
9577            }
9578
9579            final long origId = Binder.clearCallingIdentity();
9580
9581            final int N = providers.size();
9582            for (int i=0; i<N; i++) {
9583                ContentProviderHolder src = providers.get(i);
9584                if (src == null || src.info == null || src.provider == null) {
9585                    continue;
9586                }
9587                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9588                if (DEBUG_MU)
9589                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9590                if (dst != null) {
9591                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9592                    mProviderMap.putProviderByClass(comp, dst);
9593                    String names[] = dst.info.authority.split(";");
9594                    for (int j = 0; j < names.length; j++) {
9595                        mProviderMap.putProviderByName(names[j], dst);
9596                    }
9597
9598                    int NL = mLaunchingProviders.size();
9599                    int j;
9600                    for (j=0; j<NL; j++) {
9601                        if (mLaunchingProviders.get(j) == dst) {
9602                            mLaunchingProviders.remove(j);
9603                            j--;
9604                            NL--;
9605                        }
9606                    }
9607                    synchronized (dst) {
9608                        dst.provider = src.provider;
9609                        dst.proc = r;
9610                        dst.notifyAll();
9611                    }
9612                    updateOomAdjLocked(r);
9613                }
9614            }
9615
9616            Binder.restoreCallingIdentity(origId);
9617        }
9618    }
9619
9620    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9621        ContentProviderConnection conn;
9622        try {
9623            conn = (ContentProviderConnection)connection;
9624        } catch (ClassCastException e) {
9625            String msg ="refContentProvider: " + connection
9626                    + " not a ContentProviderConnection";
9627            Slog.w(TAG, msg);
9628            throw new IllegalArgumentException(msg);
9629        }
9630        if (conn == null) {
9631            throw new NullPointerException("connection is null");
9632        }
9633
9634        synchronized (this) {
9635            if (stable > 0) {
9636                conn.numStableIncs += stable;
9637            }
9638            stable = conn.stableCount + stable;
9639            if (stable < 0) {
9640                throw new IllegalStateException("stableCount < 0: " + stable);
9641            }
9642
9643            if (unstable > 0) {
9644                conn.numUnstableIncs += unstable;
9645            }
9646            unstable = conn.unstableCount + unstable;
9647            if (unstable < 0) {
9648                throw new IllegalStateException("unstableCount < 0: " + unstable);
9649            }
9650
9651            if ((stable+unstable) <= 0) {
9652                throw new IllegalStateException("ref counts can't go to zero here: stable="
9653                        + stable + " unstable=" + unstable);
9654            }
9655            conn.stableCount = stable;
9656            conn.unstableCount = unstable;
9657            return !conn.dead;
9658        }
9659    }
9660
9661    public void unstableProviderDied(IBinder connection) {
9662        ContentProviderConnection conn;
9663        try {
9664            conn = (ContentProviderConnection)connection;
9665        } catch (ClassCastException e) {
9666            String msg ="refContentProvider: " + connection
9667                    + " not a ContentProviderConnection";
9668            Slog.w(TAG, msg);
9669            throw new IllegalArgumentException(msg);
9670        }
9671        if (conn == null) {
9672            throw new NullPointerException("connection is null");
9673        }
9674
9675        // Safely retrieve the content provider associated with the connection.
9676        IContentProvider provider;
9677        synchronized (this) {
9678            provider = conn.provider.provider;
9679        }
9680
9681        if (provider == null) {
9682            // Um, yeah, we're way ahead of you.
9683            return;
9684        }
9685
9686        // Make sure the caller is being honest with us.
9687        if (provider.asBinder().pingBinder()) {
9688            // Er, no, still looks good to us.
9689            synchronized (this) {
9690                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9691                        + " says " + conn + " died, but we don't agree");
9692                return;
9693            }
9694        }
9695
9696        // Well look at that!  It's dead!
9697        synchronized (this) {
9698            if (conn.provider.provider != provider) {
9699                // But something changed...  good enough.
9700                return;
9701            }
9702
9703            ProcessRecord proc = conn.provider.proc;
9704            if (proc == null || proc.thread == null) {
9705                // Seems like the process is already cleaned up.
9706                return;
9707            }
9708
9709            // As far as we're concerned, this is just like receiving a
9710            // death notification...  just a bit prematurely.
9711            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9712                    + ") early provider death");
9713            final long ident = Binder.clearCallingIdentity();
9714            try {
9715                appDiedLocked(proc);
9716            } finally {
9717                Binder.restoreCallingIdentity(ident);
9718            }
9719        }
9720    }
9721
9722    @Override
9723    public void appNotRespondingViaProvider(IBinder connection) {
9724        enforceCallingPermission(
9725                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9726
9727        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9728        if (conn == null) {
9729            Slog.w(TAG, "ContentProviderConnection is null");
9730            return;
9731        }
9732
9733        final ProcessRecord host = conn.provider.proc;
9734        if (host == null) {
9735            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9736            return;
9737        }
9738
9739        final long token = Binder.clearCallingIdentity();
9740        try {
9741            appNotResponding(host, null, null, false, "ContentProvider not responding");
9742        } finally {
9743            Binder.restoreCallingIdentity(token);
9744        }
9745    }
9746
9747    public final void installSystemProviders() {
9748        List<ProviderInfo> providers;
9749        synchronized (this) {
9750            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9751            providers = generateApplicationProvidersLocked(app);
9752            if (providers != null) {
9753                for (int i=providers.size()-1; i>=0; i--) {
9754                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9755                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9756                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9757                                + ": not system .apk");
9758                        providers.remove(i);
9759                    }
9760                }
9761            }
9762        }
9763        if (providers != null) {
9764            mSystemThread.installSystemProviders(providers);
9765        }
9766
9767        mCoreSettingsObserver = new CoreSettingsObserver(this);
9768
9769        //mUsageStatsService.monitorPackages();
9770    }
9771
9772    /**
9773     * Allows apps to retrieve the MIME type of a URI.
9774     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9775     * users, then it does not need permission to access the ContentProvider.
9776     * Either, it needs cross-user uri grants.
9777     *
9778     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9779     *
9780     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9781     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9782     */
9783    public String getProviderMimeType(Uri uri, int userId) {
9784        enforceNotIsolatedCaller("getProviderMimeType");
9785        final String name = uri.getAuthority();
9786        int callingUid = Binder.getCallingUid();
9787        int callingPid = Binder.getCallingPid();
9788        long ident = 0;
9789        boolean clearedIdentity = false;
9790        userId = unsafeConvertIncomingUser(userId);
9791        if (canClearIdentity(callingPid, callingUid, userId)) {
9792            clearedIdentity = true;
9793            ident = Binder.clearCallingIdentity();
9794        }
9795        ContentProviderHolder holder = null;
9796        try {
9797            holder = getContentProviderExternalUnchecked(name, null, userId);
9798            if (holder != null) {
9799                return holder.provider.getType(uri);
9800            }
9801        } catch (RemoteException e) {
9802            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9803            return null;
9804        } finally {
9805            // We need to clear the identity to call removeContentProviderExternalUnchecked
9806            if (!clearedIdentity) {
9807                ident = Binder.clearCallingIdentity();
9808            }
9809            try {
9810                if (holder != null) {
9811                    removeContentProviderExternalUnchecked(name, null, userId);
9812                }
9813            } finally {
9814                Binder.restoreCallingIdentity(ident);
9815            }
9816        }
9817
9818        return null;
9819    }
9820
9821    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9822        if (UserHandle.getUserId(callingUid) == userId) {
9823            return true;
9824        }
9825        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9826                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9827                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9828                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9829                return true;
9830        }
9831        return false;
9832    }
9833
9834    // =========================================================
9835    // GLOBAL MANAGEMENT
9836    // =========================================================
9837
9838    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9839            boolean isolated, int isolatedUid) {
9840        String proc = customProcess != null ? customProcess : info.processName;
9841        BatteryStatsImpl.Uid.Proc ps = null;
9842        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9843        int uid = info.uid;
9844        if (isolated) {
9845            if (isolatedUid == 0) {
9846                int userId = UserHandle.getUserId(uid);
9847                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9848                while (true) {
9849                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9850                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9851                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9852                    }
9853                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9854                    mNextIsolatedProcessUid++;
9855                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9856                        // No process for this uid, use it.
9857                        break;
9858                    }
9859                    stepsLeft--;
9860                    if (stepsLeft <= 0) {
9861                        return null;
9862                    }
9863                }
9864            } else {
9865                // Special case for startIsolatedProcess (internal only), where
9866                // the uid of the isolated process is specified by the caller.
9867                uid = isolatedUid;
9868            }
9869        }
9870        return new ProcessRecord(stats, info, proc, uid);
9871    }
9872
9873    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9874            String abiOverride) {
9875        ProcessRecord app;
9876        if (!isolated) {
9877            app = getProcessRecordLocked(info.processName, info.uid, true);
9878        } else {
9879            app = null;
9880        }
9881
9882        if (app == null) {
9883            app = newProcessRecordLocked(info, null, isolated, 0);
9884            mProcessNames.put(info.processName, app.uid, app);
9885            if (isolated) {
9886                mIsolatedProcesses.put(app.uid, app);
9887            }
9888            updateLruProcessLocked(app, false, null);
9889            updateOomAdjLocked();
9890        }
9891
9892        // This package really, really can not be stopped.
9893        try {
9894            AppGlobals.getPackageManager().setPackageStoppedState(
9895                    info.packageName, false, UserHandle.getUserId(app.uid));
9896        } catch (RemoteException e) {
9897        } catch (IllegalArgumentException e) {
9898            Slog.w(TAG, "Failed trying to unstop package "
9899                    + info.packageName + ": " + e);
9900        }
9901
9902        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9903                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9904            app.persistent = true;
9905            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9906        }
9907        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9908            mPersistentStartingProcesses.add(app);
9909            startProcessLocked(app, "added application", app.processName, abiOverride,
9910                    null /* entryPoint */, null /* entryPointArgs */);
9911        }
9912
9913        return app;
9914    }
9915
9916    public void unhandledBack() {
9917        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9918                "unhandledBack()");
9919
9920        synchronized(this) {
9921            final long origId = Binder.clearCallingIdentity();
9922            try {
9923                getFocusedStack().unhandledBackLocked();
9924            } finally {
9925                Binder.restoreCallingIdentity(origId);
9926            }
9927        }
9928    }
9929
9930    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9931        enforceNotIsolatedCaller("openContentUri");
9932        final int userId = UserHandle.getCallingUserId();
9933        String name = uri.getAuthority();
9934        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9935        ParcelFileDescriptor pfd = null;
9936        if (cph != null) {
9937            // We record the binder invoker's uid in thread-local storage before
9938            // going to the content provider to open the file.  Later, in the code
9939            // that handles all permissions checks, we look for this uid and use
9940            // that rather than the Activity Manager's own uid.  The effect is that
9941            // we do the check against the caller's permissions even though it looks
9942            // to the content provider like the Activity Manager itself is making
9943            // the request.
9944            Binder token = new Binder();
9945            sCallerIdentity.set(new Identity(
9946                    token, Binder.getCallingPid(), Binder.getCallingUid()));
9947            try {
9948                pfd = cph.provider.openFile(null, uri, "r", null, token);
9949            } catch (FileNotFoundException e) {
9950                // do nothing; pfd will be returned null
9951            } finally {
9952                // Ensure that whatever happens, we clean up the identity state
9953                sCallerIdentity.remove();
9954            }
9955
9956            // We've got the fd now, so we're done with the provider.
9957            removeContentProviderExternalUnchecked(name, null, userId);
9958        } else {
9959            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9960        }
9961        return pfd;
9962    }
9963
9964    // Actually is sleeping or shutting down or whatever else in the future
9965    // is an inactive state.
9966    public boolean isSleepingOrShuttingDown() {
9967        return isSleeping() || mShuttingDown;
9968    }
9969
9970    public boolean isSleeping() {
9971        return mSleeping;
9972    }
9973
9974    void onWakefulnessChanged(int wakefulness) {
9975        synchronized(this) {
9976            mWakefulness = wakefulness;
9977            updateSleepIfNeededLocked();
9978        }
9979    }
9980
9981    void finishRunningVoiceLocked() {
9982        if (mRunningVoice) {
9983            mRunningVoice = false;
9984            updateSleepIfNeededLocked();
9985        }
9986    }
9987
9988    void updateSleepIfNeededLocked() {
9989        if (mSleeping && !shouldSleepLocked()) {
9990            mSleeping = false;
9991            mStackSupervisor.comeOutOfSleepIfNeededLocked();
9992        } else if (!mSleeping && shouldSleepLocked()) {
9993            mSleeping = true;
9994            mStackSupervisor.goingToSleepLocked();
9995
9996            // Initialize the wake times of all processes.
9997            checkExcessivePowerUsageLocked(false);
9998            mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9999            Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10000            mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10001        }
10002    }
10003
10004    private boolean shouldSleepLocked() {
10005        // Resume applications while running a voice interactor.
10006        if (mRunningVoice) {
10007            return false;
10008        }
10009
10010        switch (mWakefulness) {
10011            case PowerManagerInternal.WAKEFULNESS_AWAKE:
10012            case PowerManagerInternal.WAKEFULNESS_DREAMING:
10013                // If we're interactive but applications are already paused then defer
10014                // resuming them until the lock screen is hidden.
10015                return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10016            case PowerManagerInternal.WAKEFULNESS_DOZING:
10017                // If we're dozing then pause applications whenever the lock screen is shown.
10018                return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10019            case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10020            default:
10021                // If we're asleep then pause applications unconditionally.
10022                return true;
10023        }
10024    }
10025
10026    /** Pokes the task persister. */
10027    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10028        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10029            // Never persist the home stack.
10030            return;
10031        }
10032        mTaskPersister.wakeup(task, flush);
10033    }
10034
10035    /** Notifies all listeners when the task stack has changed. */
10036    void notifyTaskStackChangedLocked() {
10037        mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10038        Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10039        mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10040    }
10041
10042    @Override
10043    public boolean shutdown(int timeout) {
10044        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10045                != PackageManager.PERMISSION_GRANTED) {
10046            throw new SecurityException("Requires permission "
10047                    + android.Manifest.permission.SHUTDOWN);
10048        }
10049
10050        boolean timedout = false;
10051
10052        synchronized(this) {
10053            mShuttingDown = true;
10054            updateEventDispatchingLocked();
10055            timedout = mStackSupervisor.shutdownLocked(timeout);
10056        }
10057
10058        mAppOpsService.shutdown();
10059        if (mUsageStatsService != null) {
10060            mUsageStatsService.prepareShutdown();
10061        }
10062        mBatteryStatsService.shutdown();
10063        synchronized (this) {
10064            mProcessStats.shutdownLocked();
10065            notifyTaskPersisterLocked(null, true);
10066        }
10067
10068        return timedout;
10069    }
10070
10071    public final void activitySlept(IBinder token) {
10072        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10073
10074        final long origId = Binder.clearCallingIdentity();
10075
10076        synchronized (this) {
10077            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10078            if (r != null) {
10079                mStackSupervisor.activitySleptLocked(r);
10080            }
10081        }
10082
10083        Binder.restoreCallingIdentity(origId);
10084    }
10085
10086    private String lockScreenShownToString() {
10087        switch (mLockScreenShown) {
10088            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10089            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10090            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10091            default: return "Unknown=" + mLockScreenShown;
10092        }
10093    }
10094
10095    void logLockScreen(String msg) {
10096        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10097                + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10098                + PowerManagerInternal.wakefulnessToString(mWakefulness)
10099                + " mSleeping=" + mSleeping);
10100    }
10101
10102    void startRunningVoiceLocked() {
10103        if (!mRunningVoice) {
10104            mRunningVoice = true;
10105            updateSleepIfNeededLocked();
10106        }
10107    }
10108
10109    private void updateEventDispatchingLocked() {
10110        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10111    }
10112
10113    public void setLockScreenShown(boolean shown) {
10114        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10115                != PackageManager.PERMISSION_GRANTED) {
10116            throw new SecurityException("Requires permission "
10117                    + android.Manifest.permission.DEVICE_POWER);
10118        }
10119
10120        synchronized(this) {
10121            long ident = Binder.clearCallingIdentity();
10122            try {
10123                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10124                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10125                updateSleepIfNeededLocked();
10126            } finally {
10127                Binder.restoreCallingIdentity(ident);
10128            }
10129        }
10130    }
10131
10132    @Override
10133    public void stopAppSwitches() {
10134        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10135                != PackageManager.PERMISSION_GRANTED) {
10136            throw new SecurityException("Requires permission "
10137                    + android.Manifest.permission.STOP_APP_SWITCHES);
10138        }
10139
10140        synchronized(this) {
10141            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10142                    + APP_SWITCH_DELAY_TIME;
10143            mDidAppSwitch = false;
10144            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10145            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10146            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10147        }
10148    }
10149
10150    public void resumeAppSwitches() {
10151        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10152                != PackageManager.PERMISSION_GRANTED) {
10153            throw new SecurityException("Requires permission "
10154                    + android.Manifest.permission.STOP_APP_SWITCHES);
10155        }
10156
10157        synchronized(this) {
10158            // Note that we don't execute any pending app switches... we will
10159            // let those wait until either the timeout, or the next start
10160            // activity request.
10161            mAppSwitchesAllowedTime = 0;
10162        }
10163    }
10164
10165    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10166            int callingPid, int callingUid, String name) {
10167        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10168            return true;
10169        }
10170
10171        int perm = checkComponentPermission(
10172                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10173                sourceUid, -1, true);
10174        if (perm == PackageManager.PERMISSION_GRANTED) {
10175            return true;
10176        }
10177
10178        // If the actual IPC caller is different from the logical source, then
10179        // also see if they are allowed to control app switches.
10180        if (callingUid != -1 && callingUid != sourceUid) {
10181            perm = checkComponentPermission(
10182                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10183                    callingUid, -1, true);
10184            if (perm == PackageManager.PERMISSION_GRANTED) {
10185                return true;
10186            }
10187        }
10188
10189        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10190        return false;
10191    }
10192
10193    public void setDebugApp(String packageName, boolean waitForDebugger,
10194            boolean persistent) {
10195        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10196                "setDebugApp()");
10197
10198        long ident = Binder.clearCallingIdentity();
10199        try {
10200            // Note that this is not really thread safe if there are multiple
10201            // callers into it at the same time, but that's not a situation we
10202            // care about.
10203            if (persistent) {
10204                final ContentResolver resolver = mContext.getContentResolver();
10205                Settings.Global.putString(
10206                    resolver, Settings.Global.DEBUG_APP,
10207                    packageName);
10208                Settings.Global.putInt(
10209                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10210                    waitForDebugger ? 1 : 0);
10211            }
10212
10213            synchronized (this) {
10214                if (!persistent) {
10215                    mOrigDebugApp = mDebugApp;
10216                    mOrigWaitForDebugger = mWaitForDebugger;
10217                }
10218                mDebugApp = packageName;
10219                mWaitForDebugger = waitForDebugger;
10220                mDebugTransient = !persistent;
10221                if (packageName != null) {
10222                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10223                            false, UserHandle.USER_ALL, "set debug app");
10224                }
10225            }
10226        } finally {
10227            Binder.restoreCallingIdentity(ident);
10228        }
10229    }
10230
10231    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10232        synchronized (this) {
10233            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10234            if (!isDebuggable) {
10235                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10236                    throw new SecurityException("Process not debuggable: " + app.packageName);
10237                }
10238            }
10239
10240            mOpenGlTraceApp = processName;
10241        }
10242    }
10243
10244    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10245        synchronized (this) {
10246            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10247            if (!isDebuggable) {
10248                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10249                    throw new SecurityException("Process not debuggable: " + app.packageName);
10250                }
10251            }
10252            mProfileApp = processName;
10253            mProfileFile = profilerInfo.profileFile;
10254            if (mProfileFd != null) {
10255                try {
10256                    mProfileFd.close();
10257                } catch (IOException e) {
10258                }
10259                mProfileFd = null;
10260            }
10261            mProfileFd = profilerInfo.profileFd;
10262            mSamplingInterval = profilerInfo.samplingInterval;
10263            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10264            mProfileType = 0;
10265        }
10266    }
10267
10268    @Override
10269    public void setAlwaysFinish(boolean enabled) {
10270        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10271                "setAlwaysFinish()");
10272
10273        Settings.Global.putInt(
10274                mContext.getContentResolver(),
10275                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10276
10277        synchronized (this) {
10278            mAlwaysFinishActivities = enabled;
10279        }
10280    }
10281
10282    @Override
10283    public void setActivityController(IActivityController controller) {
10284        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10285                "setActivityController()");
10286        synchronized (this) {
10287            mController = controller;
10288            Watchdog.getInstance().setActivityController(controller);
10289        }
10290    }
10291
10292    @Override
10293    public void setUserIsMonkey(boolean userIsMonkey) {
10294        synchronized (this) {
10295            synchronized (mPidsSelfLocked) {
10296                final int callingPid = Binder.getCallingPid();
10297                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10298                if (precessRecord == null) {
10299                    throw new SecurityException("Unknown process: " + callingPid);
10300                }
10301                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10302                    throw new SecurityException("Only an instrumentation process "
10303                            + "with a UiAutomation can call setUserIsMonkey");
10304                }
10305            }
10306            mUserIsMonkey = userIsMonkey;
10307        }
10308    }
10309
10310    @Override
10311    public boolean isUserAMonkey() {
10312        synchronized (this) {
10313            // If there is a controller also implies the user is a monkey.
10314            return (mUserIsMonkey || mController != null);
10315        }
10316    }
10317
10318    public void requestBugReport() {
10319        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10320        SystemProperties.set("ctl.start", "bugreport");
10321    }
10322
10323    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10324        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10325    }
10326
10327    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10328        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10329            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10330        }
10331        return KEY_DISPATCHING_TIMEOUT;
10332    }
10333
10334    @Override
10335    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10336        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10337                != PackageManager.PERMISSION_GRANTED) {
10338            throw new SecurityException("Requires permission "
10339                    + android.Manifest.permission.FILTER_EVENTS);
10340        }
10341        ProcessRecord proc;
10342        long timeout;
10343        synchronized (this) {
10344            synchronized (mPidsSelfLocked) {
10345                proc = mPidsSelfLocked.get(pid);
10346            }
10347            timeout = getInputDispatchingTimeoutLocked(proc);
10348        }
10349
10350        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10351            return -1;
10352        }
10353
10354        return timeout;
10355    }
10356
10357    /**
10358     * Handle input dispatching timeouts.
10359     * Returns whether input dispatching should be aborted or not.
10360     */
10361    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10362            final ActivityRecord activity, final ActivityRecord parent,
10363            final boolean aboveSystem, String reason) {
10364        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10365                != PackageManager.PERMISSION_GRANTED) {
10366            throw new SecurityException("Requires permission "
10367                    + android.Manifest.permission.FILTER_EVENTS);
10368        }
10369
10370        final String annotation;
10371        if (reason == null) {
10372            annotation = "Input dispatching timed out";
10373        } else {
10374            annotation = "Input dispatching timed out (" + reason + ")";
10375        }
10376
10377        if (proc != null) {
10378            synchronized (this) {
10379                if (proc.debugging) {
10380                    return false;
10381                }
10382
10383                if (mDidDexOpt) {
10384                    // Give more time since we were dexopting.
10385                    mDidDexOpt = false;
10386                    return false;
10387                }
10388
10389                if (proc.instrumentationClass != null) {
10390                    Bundle info = new Bundle();
10391                    info.putString("shortMsg", "keyDispatchingTimedOut");
10392                    info.putString("longMsg", annotation);
10393                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10394                    return true;
10395                }
10396            }
10397            mHandler.post(new Runnable() {
10398                @Override
10399                public void run() {
10400                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10401                }
10402            });
10403        }
10404
10405        return true;
10406    }
10407
10408    public Bundle getAssistContextExtras(int requestType) {
10409        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10410                UserHandle.getCallingUserId());
10411        if (pae == null) {
10412            return null;
10413        }
10414        synchronized (pae) {
10415            while (!pae.haveResult) {
10416                try {
10417                    pae.wait();
10418                } catch (InterruptedException e) {
10419                }
10420            }
10421            if (pae.result != null) {
10422                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10423            }
10424        }
10425        synchronized (this) {
10426            mPendingAssistExtras.remove(pae);
10427            mHandler.removeCallbacks(pae);
10428        }
10429        return pae.extras;
10430    }
10431
10432    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10433            int userHandle) {
10434        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10435                "getAssistContextExtras()");
10436        PendingAssistExtras pae;
10437        Bundle extras = new Bundle();
10438        synchronized (this) {
10439            ActivityRecord activity = getFocusedStack().mResumedActivity;
10440            if (activity == null) {
10441                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10442                return null;
10443            }
10444            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10445            if (activity.app == null || activity.app.thread == null) {
10446                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10447                return null;
10448            }
10449            if (activity.app.pid == Binder.getCallingPid()) {
10450                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10451                return null;
10452            }
10453            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10454            try {
10455                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10456                        requestType);
10457                mPendingAssistExtras.add(pae);
10458                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10459            } catch (RemoteException e) {
10460                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10461                return null;
10462            }
10463            return pae;
10464        }
10465    }
10466
10467    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10468        PendingAssistExtras pae = (PendingAssistExtras)token;
10469        synchronized (pae) {
10470            pae.result = extras;
10471            pae.haveResult = true;
10472            pae.notifyAll();
10473            if (pae.intent == null) {
10474                // Caller is just waiting for the result.
10475                return;
10476            }
10477        }
10478
10479        // We are now ready to launch the assist activity.
10480        synchronized (this) {
10481            boolean exists = mPendingAssistExtras.remove(pae);
10482            mHandler.removeCallbacks(pae);
10483            if (!exists) {
10484                // Timed out.
10485                return;
10486            }
10487        }
10488        pae.intent.replaceExtras(extras);
10489        if (pae.hint != null) {
10490            pae.intent.putExtra(pae.hint, true);
10491        }
10492        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10493                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10494                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10495        closeSystemDialogs("assist");
10496        try {
10497            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10498        } catch (ActivityNotFoundException e) {
10499            Slog.w(TAG, "No activity to handle assist action.", e);
10500        }
10501    }
10502
10503    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10504        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10505    }
10506
10507    public void registerProcessObserver(IProcessObserver observer) {
10508        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10509                "registerProcessObserver()");
10510        synchronized (this) {
10511            mProcessObservers.register(observer);
10512        }
10513    }
10514
10515    @Override
10516    public void unregisterProcessObserver(IProcessObserver observer) {
10517        synchronized (this) {
10518            mProcessObservers.unregister(observer);
10519        }
10520    }
10521
10522    @Override
10523    public boolean convertFromTranslucent(IBinder token) {
10524        final long origId = Binder.clearCallingIdentity();
10525        try {
10526            synchronized (this) {
10527                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10528                if (r == null) {
10529                    return false;
10530                }
10531                final boolean translucentChanged = r.changeWindowTranslucency(true);
10532                if (translucentChanged) {
10533                    r.task.stack.releaseBackgroundResources();
10534                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10535                }
10536                mWindowManager.setAppFullscreen(token, true);
10537                return translucentChanged;
10538            }
10539        } finally {
10540            Binder.restoreCallingIdentity(origId);
10541        }
10542    }
10543
10544    @Override
10545    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10546        final long origId = Binder.clearCallingIdentity();
10547        try {
10548            synchronized (this) {
10549                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10550                if (r == null) {
10551                    return false;
10552                }
10553                int index = r.task.mActivities.lastIndexOf(r);
10554                if (index > 0) {
10555                    ActivityRecord under = r.task.mActivities.get(index - 1);
10556                    under.returningOptions = options;
10557                }
10558                final boolean translucentChanged = r.changeWindowTranslucency(false);
10559                if (translucentChanged) {
10560                    r.task.stack.convertToTranslucent(r);
10561                }
10562                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10563                mWindowManager.setAppFullscreen(token, false);
10564                return translucentChanged;
10565            }
10566        } finally {
10567            Binder.restoreCallingIdentity(origId);
10568        }
10569    }
10570
10571    @Override
10572    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10573        final long origId = Binder.clearCallingIdentity();
10574        try {
10575            synchronized (this) {
10576                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10577                if (r != null) {
10578                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10579                }
10580            }
10581            return false;
10582        } finally {
10583            Binder.restoreCallingIdentity(origId);
10584        }
10585    }
10586
10587    @Override
10588    public boolean isBackgroundVisibleBehind(IBinder token) {
10589        final long origId = Binder.clearCallingIdentity();
10590        try {
10591            synchronized (this) {
10592                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10593                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10594                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10595                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10596                return visible;
10597            }
10598        } finally {
10599            Binder.restoreCallingIdentity(origId);
10600        }
10601    }
10602
10603    @Override
10604    public ActivityOptions getActivityOptions(IBinder token) {
10605        final long origId = Binder.clearCallingIdentity();
10606        try {
10607            synchronized (this) {
10608                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10609                if (r != null) {
10610                    final ActivityOptions activityOptions = r.pendingOptions;
10611                    r.pendingOptions = null;
10612                    return activityOptions;
10613                }
10614                return null;
10615            }
10616        } finally {
10617            Binder.restoreCallingIdentity(origId);
10618        }
10619    }
10620
10621    @Override
10622    public void setImmersive(IBinder token, boolean immersive) {
10623        synchronized(this) {
10624            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10625            if (r == null) {
10626                throw new IllegalArgumentException();
10627            }
10628            r.immersive = immersive;
10629
10630            // update associated state if we're frontmost
10631            if (r == mFocusedActivity) {
10632                if (DEBUG_IMMERSIVE) {
10633                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10634                }
10635                applyUpdateLockStateLocked(r);
10636            }
10637        }
10638    }
10639
10640    @Override
10641    public boolean isImmersive(IBinder token) {
10642        synchronized (this) {
10643            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10644            if (r == null) {
10645                throw new IllegalArgumentException();
10646            }
10647            return r.immersive;
10648        }
10649    }
10650
10651    public boolean isTopActivityImmersive() {
10652        enforceNotIsolatedCaller("startActivity");
10653        synchronized (this) {
10654            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10655            return (r != null) ? r.immersive : false;
10656        }
10657    }
10658
10659    @Override
10660    public boolean isTopOfTask(IBinder token) {
10661        synchronized (this) {
10662            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10663            if (r == null) {
10664                throw new IllegalArgumentException();
10665            }
10666            return r.task.getTopActivity() == r;
10667        }
10668    }
10669
10670    public final void enterSafeMode() {
10671        synchronized(this) {
10672            // It only makes sense to do this before the system is ready
10673            // and started launching other packages.
10674            if (!mSystemReady) {
10675                try {
10676                    AppGlobals.getPackageManager().enterSafeMode();
10677                } catch (RemoteException e) {
10678                }
10679            }
10680
10681            mSafeMode = true;
10682        }
10683    }
10684
10685    public final void showSafeModeOverlay() {
10686        View v = LayoutInflater.from(mContext).inflate(
10687                com.android.internal.R.layout.safe_mode, null);
10688        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10689        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10690        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10691        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10692        lp.gravity = Gravity.BOTTOM | Gravity.START;
10693        lp.format = v.getBackground().getOpacity();
10694        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10695                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10696        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10697        ((WindowManager)mContext.getSystemService(
10698                Context.WINDOW_SERVICE)).addView(v, lp);
10699    }
10700
10701    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10702        if (!(sender instanceof PendingIntentRecord)) {
10703            return;
10704        }
10705        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10706        synchronized (stats) {
10707            if (mBatteryStatsService.isOnBattery()) {
10708                mBatteryStatsService.enforceCallingPermission();
10709                PendingIntentRecord rec = (PendingIntentRecord)sender;
10710                int MY_UID = Binder.getCallingUid();
10711                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10712                BatteryStatsImpl.Uid.Pkg pkg =
10713                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10714                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10715                pkg.incWakeupsLocked();
10716            }
10717        }
10718    }
10719
10720    public boolean killPids(int[] pids, String pReason, boolean secure) {
10721        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10722            throw new SecurityException("killPids only available to the system");
10723        }
10724        String reason = (pReason == null) ? "Unknown" : pReason;
10725        // XXX Note: don't acquire main activity lock here, because the window
10726        // manager calls in with its locks held.
10727
10728        boolean killed = false;
10729        synchronized (mPidsSelfLocked) {
10730            int[] types = new int[pids.length];
10731            int worstType = 0;
10732            for (int i=0; i<pids.length; i++) {
10733                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10734                if (proc != null) {
10735                    int type = proc.setAdj;
10736                    types[i] = type;
10737                    if (type > worstType) {
10738                        worstType = type;
10739                    }
10740                }
10741            }
10742
10743            // If the worst oom_adj is somewhere in the cached proc LRU range,
10744            // then constrain it so we will kill all cached procs.
10745            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10746                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10747                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10748            }
10749
10750            // If this is not a secure call, don't let it kill processes that
10751            // are important.
10752            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10753                worstType = ProcessList.SERVICE_ADJ;
10754            }
10755
10756            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10757            for (int i=0; i<pids.length; i++) {
10758                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10759                if (proc == null) {
10760                    continue;
10761                }
10762                int adj = proc.setAdj;
10763                if (adj >= worstType && !proc.killedByAm) {
10764                    proc.kill(reason, true);
10765                    killed = true;
10766                }
10767            }
10768        }
10769        return killed;
10770    }
10771
10772    @Override
10773    public void killUid(int uid, String reason) {
10774        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10775            throw new SecurityException("killUid only available to the system");
10776        }
10777        synchronized (this) {
10778            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10779                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10780                    reason != null ? reason : "kill uid");
10781        }
10782    }
10783
10784    @Override
10785    public boolean killProcessesBelowForeground(String reason) {
10786        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10787            throw new SecurityException("killProcessesBelowForeground() only available to system");
10788        }
10789
10790        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10791    }
10792
10793    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10794        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10795            throw new SecurityException("killProcessesBelowAdj() only available to system");
10796        }
10797
10798        boolean killed = false;
10799        synchronized (mPidsSelfLocked) {
10800            final int size = mPidsSelfLocked.size();
10801            for (int i = 0; i < size; i++) {
10802                final int pid = mPidsSelfLocked.keyAt(i);
10803                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10804                if (proc == null) continue;
10805
10806                final int adj = proc.setAdj;
10807                if (adj > belowAdj && !proc.killedByAm) {
10808                    proc.kill(reason, true);
10809                    killed = true;
10810                }
10811            }
10812        }
10813        return killed;
10814    }
10815
10816    @Override
10817    public void hang(final IBinder who, boolean allowRestart) {
10818        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10819                != PackageManager.PERMISSION_GRANTED) {
10820            throw new SecurityException("Requires permission "
10821                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10822        }
10823
10824        final IBinder.DeathRecipient death = new DeathRecipient() {
10825            @Override
10826            public void binderDied() {
10827                synchronized (this) {
10828                    notifyAll();
10829                }
10830            }
10831        };
10832
10833        try {
10834            who.linkToDeath(death, 0);
10835        } catch (RemoteException e) {
10836            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10837            return;
10838        }
10839
10840        synchronized (this) {
10841            Watchdog.getInstance().setAllowRestart(allowRestart);
10842            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10843            synchronized (death) {
10844                while (who.isBinderAlive()) {
10845                    try {
10846                        death.wait();
10847                    } catch (InterruptedException e) {
10848                    }
10849                }
10850            }
10851            Watchdog.getInstance().setAllowRestart(true);
10852        }
10853    }
10854
10855    @Override
10856    public void restart() {
10857        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10858                != PackageManager.PERMISSION_GRANTED) {
10859            throw new SecurityException("Requires permission "
10860                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10861        }
10862
10863        Log.i(TAG, "Sending shutdown broadcast...");
10864
10865        BroadcastReceiver br = new BroadcastReceiver() {
10866            @Override public void onReceive(Context context, Intent intent) {
10867                // Now the broadcast is done, finish up the low-level shutdown.
10868                Log.i(TAG, "Shutting down activity manager...");
10869                shutdown(10000);
10870                Log.i(TAG, "Shutdown complete, restarting!");
10871                Process.killProcess(Process.myPid());
10872                System.exit(10);
10873            }
10874        };
10875
10876        // First send the high-level shut down broadcast.
10877        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10878        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10879        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10880        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10881        mContext.sendOrderedBroadcastAsUser(intent,
10882                UserHandle.ALL, null, br, mHandler, 0, null, null);
10883        */
10884        br.onReceive(mContext, intent);
10885    }
10886
10887    private long getLowRamTimeSinceIdle(long now) {
10888        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10889    }
10890
10891    @Override
10892    public void performIdleMaintenance() {
10893        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10894                != PackageManager.PERMISSION_GRANTED) {
10895            throw new SecurityException("Requires permission "
10896                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10897        }
10898
10899        synchronized (this) {
10900            final long now = SystemClock.uptimeMillis();
10901            final long timeSinceLastIdle = now - mLastIdleTime;
10902            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10903            mLastIdleTime = now;
10904            mLowRamTimeSinceLastIdle = 0;
10905            if (mLowRamStartTime != 0) {
10906                mLowRamStartTime = now;
10907            }
10908
10909            StringBuilder sb = new StringBuilder(128);
10910            sb.append("Idle maintenance over ");
10911            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10912            sb.append(" low RAM for ");
10913            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10914            Slog.i(TAG, sb.toString());
10915
10916            // If at least 1/3 of our time since the last idle period has been spent
10917            // with RAM low, then we want to kill processes.
10918            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10919
10920            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10921                ProcessRecord proc = mLruProcesses.get(i);
10922                if (proc.notCachedSinceIdle) {
10923                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10924                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10925                        if (doKilling && proc.initialIdlePss != 0
10926                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10927                            proc.kill("idle maint (pss " + proc.lastPss
10928                                    + " from " + proc.initialIdlePss + ")", true);
10929                        }
10930                    }
10931                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10932                    proc.notCachedSinceIdle = true;
10933                    proc.initialIdlePss = 0;
10934                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10935                            isSleeping(), now);
10936                }
10937            }
10938
10939            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10940            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10941        }
10942    }
10943
10944    private void retrieveSettings() {
10945        final ContentResolver resolver = mContext.getContentResolver();
10946        String debugApp = Settings.Global.getString(
10947            resolver, Settings.Global.DEBUG_APP);
10948        boolean waitForDebugger = Settings.Global.getInt(
10949            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10950        boolean alwaysFinishActivities = Settings.Global.getInt(
10951            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10952        boolean forceRtl = Settings.Global.getInt(
10953                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10954        // Transfer any global setting for forcing RTL layout, into a System Property
10955        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10956
10957        Configuration configuration = new Configuration();
10958        Settings.System.getConfiguration(resolver, configuration);
10959        if (forceRtl) {
10960            // This will take care of setting the correct layout direction flags
10961            configuration.setLayoutDirection(configuration.locale);
10962        }
10963
10964        synchronized (this) {
10965            mDebugApp = mOrigDebugApp = debugApp;
10966            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10967            mAlwaysFinishActivities = alwaysFinishActivities;
10968            // This happens before any activities are started, so we can
10969            // change mConfiguration in-place.
10970            updateConfigurationLocked(configuration, null, false, true);
10971            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10972        }
10973    }
10974
10975    /** Loads resources after the current configuration has been set. */
10976    private void loadResourcesOnSystemReady() {
10977        final Resources res = mContext.getResources();
10978        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10979        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10980        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10981    }
10982
10983    public boolean testIsSystemReady() {
10984        // no need to synchronize(this) just to read & return the value
10985        return mSystemReady;
10986    }
10987
10988    private static File getCalledPreBootReceiversFile() {
10989        File dataDir = Environment.getDataDirectory();
10990        File systemDir = new File(dataDir, "system");
10991        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10992        return fname;
10993    }
10994
10995    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10996        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10997        File file = getCalledPreBootReceiversFile();
10998        FileInputStream fis = null;
10999        try {
11000            fis = new FileInputStream(file);
11001            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11002            int fvers = dis.readInt();
11003            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11004                String vers = dis.readUTF();
11005                String codename = dis.readUTF();
11006                String build = dis.readUTF();
11007                if (android.os.Build.VERSION.RELEASE.equals(vers)
11008                        && android.os.Build.VERSION.CODENAME.equals(codename)
11009                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11010                    int num = dis.readInt();
11011                    while (num > 0) {
11012                        num--;
11013                        String pkg = dis.readUTF();
11014                        String cls = dis.readUTF();
11015                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11016                    }
11017                }
11018            }
11019        } catch (FileNotFoundException e) {
11020        } catch (IOException e) {
11021            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11022        } finally {
11023            if (fis != null) {
11024                try {
11025                    fis.close();
11026                } catch (IOException e) {
11027                }
11028            }
11029        }
11030        return lastDoneReceivers;
11031    }
11032
11033    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11034        File file = getCalledPreBootReceiversFile();
11035        FileOutputStream fos = null;
11036        DataOutputStream dos = null;
11037        try {
11038            fos = new FileOutputStream(file);
11039            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11040            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11041            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11042            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11043            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11044            dos.writeInt(list.size());
11045            for (int i=0; i<list.size(); i++) {
11046                dos.writeUTF(list.get(i).getPackageName());
11047                dos.writeUTF(list.get(i).getClassName());
11048            }
11049        } catch (IOException e) {
11050            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11051            file.delete();
11052        } finally {
11053            FileUtils.sync(fos);
11054            if (dos != null) {
11055                try {
11056                    dos.close();
11057                } catch (IOException e) {
11058                    // TODO Auto-generated catch block
11059                    e.printStackTrace();
11060                }
11061            }
11062        }
11063    }
11064
11065    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11066            ArrayList<ComponentName> doneReceivers, int userId) {
11067        boolean waitingUpdate = false;
11068        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11069        List<ResolveInfo> ris = null;
11070        try {
11071            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11072                    intent, null, 0, userId);
11073        } catch (RemoteException e) {
11074        }
11075        if (ris != null) {
11076            for (int i=ris.size()-1; i>=0; i--) {
11077                if ((ris.get(i).activityInfo.applicationInfo.flags
11078                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11079                    ris.remove(i);
11080                }
11081            }
11082            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11083
11084            // For User 0, load the version number. When delivering to a new user, deliver
11085            // to all receivers.
11086            if (userId == UserHandle.USER_OWNER) {
11087                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11088                for (int i=0; i<ris.size(); i++) {
11089                    ActivityInfo ai = ris.get(i).activityInfo;
11090                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11091                    if (lastDoneReceivers.contains(comp)) {
11092                        // We already did the pre boot receiver for this app with the current
11093                        // platform version, so don't do it again...
11094                        ris.remove(i);
11095                        i--;
11096                        // ...however, do keep it as one that has been done, so we don't
11097                        // forget about it when rewriting the file of last done receivers.
11098                        doneReceivers.add(comp);
11099                    }
11100                }
11101            }
11102
11103            // If primary user, send broadcast to all available users, else just to userId
11104            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11105                    : new int[] { userId };
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                doneReceivers.add(comp);
11110                intent.setComponent(comp);
11111                for (int j=0; j<users.length; j++) {
11112                    IIntentReceiver finisher = null;
11113                    // On last receiver and user, set up a completion callback
11114                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11115                        finisher = new IIntentReceiver.Stub() {
11116                            public void performReceive(Intent intent, int resultCode,
11117                                    String data, Bundle extras, boolean ordered,
11118                                    boolean sticky, int sendingUser) {
11119                                // The raw IIntentReceiver interface is called
11120                                // with the AM lock held, so redispatch to
11121                                // execute our code without the lock.
11122                                mHandler.post(onFinishCallback);
11123                            }
11124                        };
11125                    }
11126                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11127                            + " for user " + users[j]);
11128                    broadcastIntentLocked(null, null, intent, null, finisher,
11129                            0, null, null, null, AppOpsManager.OP_NONE,
11130                            true, false, MY_PID, Process.SYSTEM_UID,
11131                            users[j]);
11132                    if (finisher != null) {
11133                        waitingUpdate = true;
11134                    }
11135                }
11136            }
11137        }
11138
11139        return waitingUpdate;
11140    }
11141
11142    public void systemReady(final Runnable goingCallback) {
11143        synchronized(this) {
11144            if (mSystemReady) {
11145                // If we're done calling all the receivers, run the next "boot phase" passed in
11146                // by the SystemServer
11147                if (goingCallback != null) {
11148                    goingCallback.run();
11149                }
11150                return;
11151            }
11152
11153            // Make sure we have the current profile info, since it is needed for
11154            // security checks.
11155            updateCurrentProfileIdsLocked();
11156
11157            if (mRecentTasks == null) {
11158                mRecentTasks = mTaskPersister.restoreTasksLocked();
11159                mTaskPersister.restoreTasksFromOtherDeviceLocked();
11160                if (!mRecentTasks.isEmpty()) {
11161                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11162                }
11163                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11164                mTaskPersister.startPersisting();
11165            }
11166
11167            // Check to see if there are any update receivers to run.
11168            if (!mDidUpdate) {
11169                if (mWaitingUpdate) {
11170                    return;
11171                }
11172                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11173                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11174                    public void run() {
11175                        synchronized (ActivityManagerService.this) {
11176                            mDidUpdate = true;
11177                        }
11178                        writeLastDonePreBootReceivers(doneReceivers);
11179                        showBootMessage(mContext.getText(
11180                                R.string.android_upgrading_complete),
11181                                false);
11182                        systemReady(goingCallback);
11183                    }
11184                }, doneReceivers, UserHandle.USER_OWNER);
11185
11186                if (mWaitingUpdate) {
11187                    return;
11188                }
11189                mDidUpdate = true;
11190            }
11191
11192            mAppOpsService.systemReady();
11193            mSystemReady = true;
11194        }
11195
11196        ArrayList<ProcessRecord> procsToKill = null;
11197        synchronized(mPidsSelfLocked) {
11198            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11199                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11200                if (!isAllowedWhileBooting(proc.info)){
11201                    if (procsToKill == null) {
11202                        procsToKill = new ArrayList<ProcessRecord>();
11203                    }
11204                    procsToKill.add(proc);
11205                }
11206            }
11207        }
11208
11209        synchronized(this) {
11210            if (procsToKill != null) {
11211                for (int i=procsToKill.size()-1; i>=0; i--) {
11212                    ProcessRecord proc = procsToKill.get(i);
11213                    Slog.i(TAG, "Removing system update proc: " + proc);
11214                    removeProcessLocked(proc, true, false, "system update done");
11215                }
11216            }
11217
11218            // Now that we have cleaned up any update processes, we
11219            // are ready to start launching real processes and know that
11220            // we won't trample on them any more.
11221            mProcessesReady = true;
11222        }
11223
11224        Slog.i(TAG, "System now ready");
11225        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11226            SystemClock.uptimeMillis());
11227
11228        synchronized(this) {
11229            // Make sure we have no pre-ready processes sitting around.
11230
11231            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11232                ResolveInfo ri = mContext.getPackageManager()
11233                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11234                                STOCK_PM_FLAGS);
11235                CharSequence errorMsg = null;
11236                if (ri != null) {
11237                    ActivityInfo ai = ri.activityInfo;
11238                    ApplicationInfo app = ai.applicationInfo;
11239                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11240                        mTopAction = Intent.ACTION_FACTORY_TEST;
11241                        mTopData = null;
11242                        mTopComponent = new ComponentName(app.packageName,
11243                                ai.name);
11244                    } else {
11245                        errorMsg = mContext.getResources().getText(
11246                                com.android.internal.R.string.factorytest_not_system);
11247                    }
11248                } else {
11249                    errorMsg = mContext.getResources().getText(
11250                            com.android.internal.R.string.factorytest_no_action);
11251                }
11252                if (errorMsg != null) {
11253                    mTopAction = null;
11254                    mTopData = null;
11255                    mTopComponent = null;
11256                    Message msg = Message.obtain();
11257                    msg.what = SHOW_FACTORY_ERROR_MSG;
11258                    msg.getData().putCharSequence("msg", errorMsg);
11259                    mHandler.sendMessage(msg);
11260                }
11261            }
11262        }
11263
11264        retrieveSettings();
11265        loadResourcesOnSystemReady();
11266
11267        synchronized (this) {
11268            readGrantedUriPermissionsLocked();
11269        }
11270
11271        if (goingCallback != null) goingCallback.run();
11272
11273        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11274                Integer.toString(mCurrentUserId), mCurrentUserId);
11275        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11276                Integer.toString(mCurrentUserId), mCurrentUserId);
11277        mSystemServiceManager.startUser(mCurrentUserId);
11278
11279        synchronized (this) {
11280            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11281                try {
11282                    List apps = AppGlobals.getPackageManager().
11283                        getPersistentApplications(STOCK_PM_FLAGS);
11284                    if (apps != null) {
11285                        int N = apps.size();
11286                        int i;
11287                        for (i=0; i<N; i++) {
11288                            ApplicationInfo info
11289                                = (ApplicationInfo)apps.get(i);
11290                            if (info != null &&
11291                                    !info.packageName.equals("android")) {
11292                                addAppLocked(info, false, null /* ABI override */);
11293                            }
11294                        }
11295                    }
11296                } catch (RemoteException ex) {
11297                    // pm is in same process, this will never happen.
11298                }
11299            }
11300
11301            // Start up initial activity.
11302            mBooting = true;
11303            startHomeActivityLocked(mCurrentUserId);
11304
11305            try {
11306                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11307                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11308                            + " data partition or your device will be unstable.");
11309                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11310                }
11311            } catch (RemoteException e) {
11312            }
11313
11314            if (!Build.isFingerprintConsistent()) {
11315                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11316                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11317            }
11318
11319            long ident = Binder.clearCallingIdentity();
11320            try {
11321                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11322                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11323                        | Intent.FLAG_RECEIVER_FOREGROUND);
11324                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11325                broadcastIntentLocked(null, null, intent,
11326                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11327                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11328                intent = new Intent(Intent.ACTION_USER_STARTING);
11329                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11330                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11331                broadcastIntentLocked(null, null, intent,
11332                        null, new IIntentReceiver.Stub() {
11333                            @Override
11334                            public void performReceive(Intent intent, int resultCode, String data,
11335                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11336                                    throws RemoteException {
11337                            }
11338                        }, 0, null, null,
11339                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11340                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11341            } catch (Throwable t) {
11342                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11343            } finally {
11344                Binder.restoreCallingIdentity(ident);
11345            }
11346            mStackSupervisor.resumeTopActivitiesLocked();
11347            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11348        }
11349    }
11350
11351    private boolean makeAppCrashingLocked(ProcessRecord app,
11352            String shortMsg, String longMsg, String stackTrace) {
11353        app.crashing = true;
11354        app.crashingReport = generateProcessError(app,
11355                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11356        startAppProblemLocked(app);
11357        app.stopFreezingAllLocked();
11358        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11359    }
11360
11361    private void makeAppNotRespondingLocked(ProcessRecord app,
11362            String activity, String shortMsg, String longMsg) {
11363        app.notResponding = true;
11364        app.notRespondingReport = generateProcessError(app,
11365                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11366                activity, shortMsg, longMsg, null);
11367        startAppProblemLocked(app);
11368        app.stopFreezingAllLocked();
11369    }
11370
11371    /**
11372     * Generate a process error record, suitable for attachment to a ProcessRecord.
11373     *
11374     * @param app The ProcessRecord in which the error occurred.
11375     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11376     *                      ActivityManager.AppErrorStateInfo
11377     * @param activity The activity associated with the crash, if known.
11378     * @param shortMsg Short message describing the crash.
11379     * @param longMsg Long message describing the crash.
11380     * @param stackTrace Full crash stack trace, may be null.
11381     *
11382     * @return Returns a fully-formed AppErrorStateInfo record.
11383     */
11384    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11385            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11386        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11387
11388        report.condition = condition;
11389        report.processName = app.processName;
11390        report.pid = app.pid;
11391        report.uid = app.info.uid;
11392        report.tag = activity;
11393        report.shortMsg = shortMsg;
11394        report.longMsg = longMsg;
11395        report.stackTrace = stackTrace;
11396
11397        return report;
11398    }
11399
11400    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11401        synchronized (this) {
11402            app.crashing = false;
11403            app.crashingReport = null;
11404            app.notResponding = false;
11405            app.notRespondingReport = null;
11406            if (app.anrDialog == fromDialog) {
11407                app.anrDialog = null;
11408            }
11409            if (app.waitDialog == fromDialog) {
11410                app.waitDialog = null;
11411            }
11412            if (app.pid > 0 && app.pid != MY_PID) {
11413                handleAppCrashLocked(app, null, null, null);
11414                app.kill("user request after error", true);
11415            }
11416        }
11417    }
11418
11419    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11420            String stackTrace) {
11421        long now = SystemClock.uptimeMillis();
11422
11423        Long crashTime;
11424        if (!app.isolated) {
11425            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11426        } else {
11427            crashTime = null;
11428        }
11429        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11430            // This process loses!
11431            Slog.w(TAG, "Process " + app.info.processName
11432                    + " has crashed too many times: killing!");
11433            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11434                    app.userId, app.info.processName, app.uid);
11435            mStackSupervisor.handleAppCrashLocked(app);
11436            if (!app.persistent) {
11437                // We don't want to start this process again until the user
11438                // explicitly does so...  but for persistent process, we really
11439                // need to keep it running.  If a persistent process is actually
11440                // repeatedly crashing, then badness for everyone.
11441                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11442                        app.info.processName);
11443                if (!app.isolated) {
11444                    // XXX We don't have a way to mark isolated processes
11445                    // as bad, since they don't have a peristent identity.
11446                    mBadProcesses.put(app.info.processName, app.uid,
11447                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11448                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11449                }
11450                app.bad = true;
11451                app.removed = true;
11452                // Don't let services in this process be restarted and potentially
11453                // annoy the user repeatedly.  Unless it is persistent, since those
11454                // processes run critical code.
11455                removeProcessLocked(app, false, false, "crash");
11456                mStackSupervisor.resumeTopActivitiesLocked();
11457                return false;
11458            }
11459            mStackSupervisor.resumeTopActivitiesLocked();
11460        } else {
11461            mStackSupervisor.finishTopRunningActivityLocked(app);
11462        }
11463
11464        // Bump up the crash count of any services currently running in the proc.
11465        for (int i=app.services.size()-1; i>=0; i--) {
11466            // Any services running in the application need to be placed
11467            // back in the pending list.
11468            ServiceRecord sr = app.services.valueAt(i);
11469            sr.crashCount++;
11470        }
11471
11472        // If the crashing process is what we consider to be the "home process" and it has been
11473        // replaced by a third-party app, clear the package preferred activities from packages
11474        // with a home activity running in the process to prevent a repeatedly crashing app
11475        // from blocking the user to manually clear the list.
11476        final ArrayList<ActivityRecord> activities = app.activities;
11477        if (app == mHomeProcess && activities.size() > 0
11478                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11479            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11480                final ActivityRecord r = activities.get(activityNdx);
11481                if (r.isHomeActivity()) {
11482                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11483                    try {
11484                        ActivityThread.getPackageManager()
11485                                .clearPackagePreferredActivities(r.packageName);
11486                    } catch (RemoteException c) {
11487                        // pm is in same process, this will never happen.
11488                    }
11489                }
11490            }
11491        }
11492
11493        if (!app.isolated) {
11494            // XXX Can't keep track of crash times for isolated processes,
11495            // because they don't have a perisistent identity.
11496            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11497        }
11498
11499        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11500        return true;
11501    }
11502
11503    void startAppProblemLocked(ProcessRecord app) {
11504        // If this app is not running under the current user, then we
11505        // can't give it a report button because that would require
11506        // launching the report UI under a different user.
11507        app.errorReportReceiver = null;
11508
11509        for (int userId : mCurrentProfileIds) {
11510            if (app.userId == userId) {
11511                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11512                        mContext, app.info.packageName, app.info.flags);
11513            }
11514        }
11515        skipCurrentReceiverLocked(app);
11516    }
11517
11518    void skipCurrentReceiverLocked(ProcessRecord app) {
11519        for (BroadcastQueue queue : mBroadcastQueues) {
11520            queue.skipCurrentReceiverLocked(app);
11521        }
11522    }
11523
11524    /**
11525     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11526     * The application process will exit immediately after this call returns.
11527     * @param app object of the crashing app, null for the system server
11528     * @param crashInfo describing the exception
11529     */
11530    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11531        ProcessRecord r = findAppProcess(app, "Crash");
11532        final String processName = app == null ? "system_server"
11533                : (r == null ? "unknown" : r.processName);
11534
11535        handleApplicationCrashInner("crash", r, processName, crashInfo);
11536    }
11537
11538    /* Native crash reporting uses this inner version because it needs to be somewhat
11539     * decoupled from the AM-managed cleanup lifecycle
11540     */
11541    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11542            ApplicationErrorReport.CrashInfo crashInfo) {
11543        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11544                UserHandle.getUserId(Binder.getCallingUid()), processName,
11545                r == null ? -1 : r.info.flags,
11546                crashInfo.exceptionClassName,
11547                crashInfo.exceptionMessage,
11548                crashInfo.throwFileName,
11549                crashInfo.throwLineNumber);
11550
11551        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11552
11553        crashApplication(r, crashInfo);
11554    }
11555
11556    public void handleApplicationStrictModeViolation(
11557            IBinder app,
11558            int violationMask,
11559            StrictMode.ViolationInfo info) {
11560        ProcessRecord r = findAppProcess(app, "StrictMode");
11561        if (r == null) {
11562            return;
11563        }
11564
11565        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11566            Integer stackFingerprint = info.hashCode();
11567            boolean logIt = true;
11568            synchronized (mAlreadyLoggedViolatedStacks) {
11569                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11570                    logIt = false;
11571                    // TODO: sub-sample into EventLog for these, with
11572                    // the info.durationMillis?  Then we'd get
11573                    // the relative pain numbers, without logging all
11574                    // the stack traces repeatedly.  We'd want to do
11575                    // likewise in the client code, which also does
11576                    // dup suppression, before the Binder call.
11577                } else {
11578                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11579                        mAlreadyLoggedViolatedStacks.clear();
11580                    }
11581                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11582                }
11583            }
11584            if (logIt) {
11585                logStrictModeViolationToDropBox(r, info);
11586            }
11587        }
11588
11589        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11590            AppErrorResult result = new AppErrorResult();
11591            synchronized (this) {
11592                final long origId = Binder.clearCallingIdentity();
11593
11594                Message msg = Message.obtain();
11595                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11596                HashMap<String, Object> data = new HashMap<String, Object>();
11597                data.put("result", result);
11598                data.put("app", r);
11599                data.put("violationMask", violationMask);
11600                data.put("info", info);
11601                msg.obj = data;
11602                mHandler.sendMessage(msg);
11603
11604                Binder.restoreCallingIdentity(origId);
11605            }
11606            int res = result.get();
11607            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11608        }
11609    }
11610
11611    // Depending on the policy in effect, there could be a bunch of
11612    // these in quick succession so we try to batch these together to
11613    // minimize disk writes, number of dropbox entries, and maximize
11614    // compression, by having more fewer, larger records.
11615    private void logStrictModeViolationToDropBox(
11616            ProcessRecord process,
11617            StrictMode.ViolationInfo info) {
11618        if (info == null) {
11619            return;
11620        }
11621        final boolean isSystemApp = process == null ||
11622                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11623                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11624        final String processName = process == null ? "unknown" : process.processName;
11625        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11626        final DropBoxManager dbox = (DropBoxManager)
11627                mContext.getSystemService(Context.DROPBOX_SERVICE);
11628
11629        // Exit early if the dropbox isn't configured to accept this report type.
11630        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11631
11632        boolean bufferWasEmpty;
11633        boolean needsFlush;
11634        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11635        synchronized (sb) {
11636            bufferWasEmpty = sb.length() == 0;
11637            appendDropBoxProcessHeaders(process, processName, sb);
11638            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11639            sb.append("System-App: ").append(isSystemApp).append("\n");
11640            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11641            if (info.violationNumThisLoop != 0) {
11642                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11643            }
11644            if (info.numAnimationsRunning != 0) {
11645                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11646            }
11647            if (info.broadcastIntentAction != null) {
11648                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11649            }
11650            if (info.durationMillis != -1) {
11651                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11652            }
11653            if (info.numInstances != -1) {
11654                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11655            }
11656            if (info.tags != null) {
11657                for (String tag : info.tags) {
11658                    sb.append("Span-Tag: ").append(tag).append("\n");
11659                }
11660            }
11661            sb.append("\n");
11662            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11663                sb.append(info.crashInfo.stackTrace);
11664            }
11665            sb.append("\n");
11666
11667            // Only buffer up to ~64k.  Various logging bits truncate
11668            // things at 128k.
11669            needsFlush = (sb.length() > 64 * 1024);
11670        }
11671
11672        // Flush immediately if the buffer's grown too large, or this
11673        // is a non-system app.  Non-system apps are isolated with a
11674        // different tag & policy and not batched.
11675        //
11676        // Batching is useful during internal testing with
11677        // StrictMode settings turned up high.  Without batching,
11678        // thousands of separate files could be created on boot.
11679        if (!isSystemApp || needsFlush) {
11680            new Thread("Error dump: " + dropboxTag) {
11681                @Override
11682                public void run() {
11683                    String report;
11684                    synchronized (sb) {
11685                        report = sb.toString();
11686                        sb.delete(0, sb.length());
11687                        sb.trimToSize();
11688                    }
11689                    if (report.length() != 0) {
11690                        dbox.addText(dropboxTag, report);
11691                    }
11692                }
11693            }.start();
11694            return;
11695        }
11696
11697        // System app batching:
11698        if (!bufferWasEmpty) {
11699            // An existing dropbox-writing thread is outstanding, so
11700            // we don't need to start it up.  The existing thread will
11701            // catch the buffer appends we just did.
11702            return;
11703        }
11704
11705        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11706        // (After this point, we shouldn't access AMS internal data structures.)
11707        new Thread("Error dump: " + dropboxTag) {
11708            @Override
11709            public void run() {
11710                // 5 second sleep to let stacks arrive and be batched together
11711                try {
11712                    Thread.sleep(5000);  // 5 seconds
11713                } catch (InterruptedException e) {}
11714
11715                String errorReport;
11716                synchronized (mStrictModeBuffer) {
11717                    errorReport = mStrictModeBuffer.toString();
11718                    if (errorReport.length() == 0) {
11719                        return;
11720                    }
11721                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11722                    mStrictModeBuffer.trimToSize();
11723                }
11724                dbox.addText(dropboxTag, errorReport);
11725            }
11726        }.start();
11727    }
11728
11729    /**
11730     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11731     * @param app object of the crashing app, null for the system server
11732     * @param tag reported by the caller
11733     * @param system whether this wtf is coming from the system
11734     * @param crashInfo describing the context of the error
11735     * @return true if the process should exit immediately (WTF is fatal)
11736     */
11737    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11738            final ApplicationErrorReport.CrashInfo crashInfo) {
11739        final int callingUid = Binder.getCallingUid();
11740        final int callingPid = Binder.getCallingPid();
11741
11742        if (system) {
11743            // If this is coming from the system, we could very well have low-level
11744            // system locks held, so we want to do this all asynchronously.  And we
11745            // never want this to become fatal, so there is that too.
11746            mHandler.post(new Runnable() {
11747                @Override public void run() {
11748                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11749                }
11750            });
11751            return false;
11752        }
11753
11754        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11755                crashInfo);
11756
11757        if (r != null && r.pid != Process.myPid() &&
11758                Settings.Global.getInt(mContext.getContentResolver(),
11759                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11760            crashApplication(r, crashInfo);
11761            return true;
11762        } else {
11763            return false;
11764        }
11765    }
11766
11767    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11768            final ApplicationErrorReport.CrashInfo crashInfo) {
11769        final ProcessRecord r = findAppProcess(app, "WTF");
11770        final String processName = app == null ? "system_server"
11771                : (r == null ? "unknown" : r.processName);
11772
11773        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11774                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11775
11776        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11777
11778        return r;
11779    }
11780
11781    /**
11782     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11783     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11784     */
11785    private ProcessRecord findAppProcess(IBinder app, String reason) {
11786        if (app == null) {
11787            return null;
11788        }
11789
11790        synchronized (this) {
11791            final int NP = mProcessNames.getMap().size();
11792            for (int ip=0; ip<NP; ip++) {
11793                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11794                final int NA = apps.size();
11795                for (int ia=0; ia<NA; ia++) {
11796                    ProcessRecord p = apps.valueAt(ia);
11797                    if (p.thread != null && p.thread.asBinder() == app) {
11798                        return p;
11799                    }
11800                }
11801            }
11802
11803            Slog.w(TAG, "Can't find mystery application for " + reason
11804                    + " from pid=" + Binder.getCallingPid()
11805                    + " uid=" + Binder.getCallingUid() + ": " + app);
11806            return null;
11807        }
11808    }
11809
11810    /**
11811     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11812     * to append various headers to the dropbox log text.
11813     */
11814    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11815            StringBuilder sb) {
11816        // Watchdog thread ends up invoking this function (with
11817        // a null ProcessRecord) to add the stack file to dropbox.
11818        // Do not acquire a lock on this (am) in such cases, as it
11819        // could cause a potential deadlock, if and when watchdog
11820        // is invoked due to unavailability of lock on am and it
11821        // would prevent watchdog from killing system_server.
11822        if (process == null) {
11823            sb.append("Process: ").append(processName).append("\n");
11824            return;
11825        }
11826        // Note: ProcessRecord 'process' is guarded by the service
11827        // instance.  (notably process.pkgList, which could otherwise change
11828        // concurrently during execution of this method)
11829        synchronized (this) {
11830            sb.append("Process: ").append(processName).append("\n");
11831            int flags = process.info.flags;
11832            IPackageManager pm = AppGlobals.getPackageManager();
11833            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11834            for (int ip=0; ip<process.pkgList.size(); ip++) {
11835                String pkg = process.pkgList.keyAt(ip);
11836                sb.append("Package: ").append(pkg);
11837                try {
11838                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11839                    if (pi != null) {
11840                        sb.append(" v").append(pi.versionCode);
11841                        if (pi.versionName != null) {
11842                            sb.append(" (").append(pi.versionName).append(")");
11843                        }
11844                    }
11845                } catch (RemoteException e) {
11846                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11847                }
11848                sb.append("\n");
11849            }
11850        }
11851    }
11852
11853    private static String processClass(ProcessRecord process) {
11854        if (process == null || process.pid == MY_PID) {
11855            return "system_server";
11856        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11857            return "system_app";
11858        } else {
11859            return "data_app";
11860        }
11861    }
11862
11863    /**
11864     * Write a description of an error (crash, WTF, ANR) to the drop box.
11865     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11866     * @param process which caused the error, null means the system server
11867     * @param activity which triggered the error, null if unknown
11868     * @param parent activity related to the error, null if unknown
11869     * @param subject line related to the error, null if absent
11870     * @param report in long form describing the error, null if absent
11871     * @param logFile to include in the report, null if none
11872     * @param crashInfo giving an application stack trace, null if absent
11873     */
11874    public void addErrorToDropBox(String eventType,
11875            ProcessRecord process, String processName, ActivityRecord activity,
11876            ActivityRecord parent, String subject,
11877            final String report, final File logFile,
11878            final ApplicationErrorReport.CrashInfo crashInfo) {
11879        // NOTE -- this must never acquire the ActivityManagerService lock,
11880        // otherwise the watchdog may be prevented from resetting the system.
11881
11882        final String dropboxTag = processClass(process) + "_" + eventType;
11883        final DropBoxManager dbox = (DropBoxManager)
11884                mContext.getSystemService(Context.DROPBOX_SERVICE);
11885
11886        // Exit early if the dropbox isn't configured to accept this report type.
11887        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11888
11889        final StringBuilder sb = new StringBuilder(1024);
11890        appendDropBoxProcessHeaders(process, processName, sb);
11891        if (activity != null) {
11892            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11893        }
11894        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11895            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11896        }
11897        if (parent != null && parent != activity) {
11898            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11899        }
11900        if (subject != null) {
11901            sb.append("Subject: ").append(subject).append("\n");
11902        }
11903        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11904        if (Debug.isDebuggerConnected()) {
11905            sb.append("Debugger: Connected\n");
11906        }
11907        sb.append("\n");
11908
11909        // Do the rest in a worker thread to avoid blocking the caller on I/O
11910        // (After this point, we shouldn't access AMS internal data structures.)
11911        Thread worker = new Thread("Error dump: " + dropboxTag) {
11912            @Override
11913            public void run() {
11914                if (report != null) {
11915                    sb.append(report);
11916                }
11917                if (logFile != null) {
11918                    try {
11919                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11920                                    "\n\n[[TRUNCATED]]"));
11921                    } catch (IOException e) {
11922                        Slog.e(TAG, "Error reading " + logFile, e);
11923                    }
11924                }
11925                if (crashInfo != null && crashInfo.stackTrace != null) {
11926                    sb.append(crashInfo.stackTrace);
11927                }
11928
11929                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11930                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11931                if (lines > 0) {
11932                    sb.append("\n");
11933
11934                    // Merge several logcat streams, and take the last N lines
11935                    InputStreamReader input = null;
11936                    try {
11937                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11938                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11939                                "-b", "crash",
11940                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11941
11942                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11943                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11944                        input = new InputStreamReader(logcat.getInputStream());
11945
11946                        int num;
11947                        char[] buf = new char[8192];
11948                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11949                    } catch (IOException e) {
11950                        Slog.e(TAG, "Error running logcat", e);
11951                    } finally {
11952                        if (input != null) try { input.close(); } catch (IOException e) {}
11953                    }
11954                }
11955
11956                dbox.addText(dropboxTag, sb.toString());
11957            }
11958        };
11959
11960        if (process == null) {
11961            // If process is null, we are being called from some internal code
11962            // and may be about to die -- run this synchronously.
11963            worker.run();
11964        } else {
11965            worker.start();
11966        }
11967    }
11968
11969    /**
11970     * Bring up the "unexpected error" dialog box for a crashing app.
11971     * Deal with edge cases (intercepts from instrumented applications,
11972     * ActivityController, error intent receivers, that sort of thing).
11973     * @param r the application crashing
11974     * @param crashInfo describing the failure
11975     */
11976    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11977        long timeMillis = System.currentTimeMillis();
11978        String shortMsg = crashInfo.exceptionClassName;
11979        String longMsg = crashInfo.exceptionMessage;
11980        String stackTrace = crashInfo.stackTrace;
11981        if (shortMsg != null && longMsg != null) {
11982            longMsg = shortMsg + ": " + longMsg;
11983        } else if (shortMsg != null) {
11984            longMsg = shortMsg;
11985        }
11986
11987        AppErrorResult result = new AppErrorResult();
11988        synchronized (this) {
11989            if (mController != null) {
11990                try {
11991                    String name = r != null ? r.processName : null;
11992                    int pid = r != null ? r.pid : Binder.getCallingPid();
11993                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11994                    if (!mController.appCrashed(name, pid,
11995                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11996                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11997                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11998                            Slog.w(TAG, "Skip killing native crashed app " + name
11999                                    + "(" + pid + ") during testing");
12000                        } else {
12001                            Slog.w(TAG, "Force-killing crashed app " + name
12002                                    + " at watcher's request");
12003                            if (r != null) {
12004                                r.kill("crash", true);
12005                            } else {
12006                                // Huh.
12007                                Process.killProcess(pid);
12008                                Process.killProcessGroup(uid, pid);
12009                            }
12010                        }
12011                        return;
12012                    }
12013                } catch (RemoteException e) {
12014                    mController = null;
12015                    Watchdog.getInstance().setActivityController(null);
12016                }
12017            }
12018
12019            final long origId = Binder.clearCallingIdentity();
12020
12021            // If this process is running instrumentation, finish it.
12022            if (r != null && r.instrumentationClass != null) {
12023                Slog.w(TAG, "Error in app " + r.processName
12024                      + " running instrumentation " + r.instrumentationClass + ":");
12025                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12026                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12027                Bundle info = new Bundle();
12028                info.putString("shortMsg", shortMsg);
12029                info.putString("longMsg", longMsg);
12030                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12031                Binder.restoreCallingIdentity(origId);
12032                return;
12033            }
12034
12035            // If we can't identify the process or it's already exceeded its crash quota,
12036            // quit right away without showing a crash dialog.
12037            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12038                Binder.restoreCallingIdentity(origId);
12039                return;
12040            }
12041
12042            Message msg = Message.obtain();
12043            msg.what = SHOW_ERROR_MSG;
12044            HashMap data = new HashMap();
12045            data.put("result", result);
12046            data.put("app", r);
12047            msg.obj = data;
12048            mHandler.sendMessage(msg);
12049
12050            Binder.restoreCallingIdentity(origId);
12051        }
12052
12053        int res = result.get();
12054
12055        Intent appErrorIntent = null;
12056        synchronized (this) {
12057            if (r != null && !r.isolated) {
12058                // XXX Can't keep track of crash time for isolated processes,
12059                // since they don't have a persistent identity.
12060                mProcessCrashTimes.put(r.info.processName, r.uid,
12061                        SystemClock.uptimeMillis());
12062            }
12063            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12064                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12065            }
12066        }
12067
12068        if (appErrorIntent != null) {
12069            try {
12070                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12071            } catch (ActivityNotFoundException e) {
12072                Slog.w(TAG, "bug report receiver dissappeared", e);
12073            }
12074        }
12075    }
12076
12077    Intent createAppErrorIntentLocked(ProcessRecord r,
12078            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12079        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12080        if (report == null) {
12081            return null;
12082        }
12083        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12084        result.setComponent(r.errorReportReceiver);
12085        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12086        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12087        return result;
12088    }
12089
12090    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12091            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12092        if (r.errorReportReceiver == null) {
12093            return null;
12094        }
12095
12096        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12097            return null;
12098        }
12099
12100        ApplicationErrorReport report = new ApplicationErrorReport();
12101        report.packageName = r.info.packageName;
12102        report.installerPackageName = r.errorReportReceiver.getPackageName();
12103        report.processName = r.processName;
12104        report.time = timeMillis;
12105        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12106
12107        if (r.crashing || r.forceCrashReport) {
12108            report.type = ApplicationErrorReport.TYPE_CRASH;
12109            report.crashInfo = crashInfo;
12110        } else if (r.notResponding) {
12111            report.type = ApplicationErrorReport.TYPE_ANR;
12112            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12113
12114            report.anrInfo.activity = r.notRespondingReport.tag;
12115            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12116            report.anrInfo.info = r.notRespondingReport.longMsg;
12117        }
12118
12119        return report;
12120    }
12121
12122    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12123        enforceNotIsolatedCaller("getProcessesInErrorState");
12124        // assume our apps are happy - lazy create the list
12125        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12126
12127        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12128                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12129        int userId = UserHandle.getUserId(Binder.getCallingUid());
12130
12131        synchronized (this) {
12132
12133            // iterate across all processes
12134            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12135                ProcessRecord app = mLruProcesses.get(i);
12136                if (!allUsers && app.userId != userId) {
12137                    continue;
12138                }
12139                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12140                    // This one's in trouble, so we'll generate a report for it
12141                    // crashes are higher priority (in case there's a crash *and* an anr)
12142                    ActivityManager.ProcessErrorStateInfo report = null;
12143                    if (app.crashing) {
12144                        report = app.crashingReport;
12145                    } else if (app.notResponding) {
12146                        report = app.notRespondingReport;
12147                    }
12148
12149                    if (report != null) {
12150                        if (errList == null) {
12151                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12152                        }
12153                        errList.add(report);
12154                    } else {
12155                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12156                                " crashing = " + app.crashing +
12157                                " notResponding = " + app.notResponding);
12158                    }
12159                }
12160            }
12161        }
12162
12163        return errList;
12164    }
12165
12166    static int procStateToImportance(int procState, int memAdj,
12167            ActivityManager.RunningAppProcessInfo currApp) {
12168        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12169        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12170            currApp.lru = memAdj;
12171        } else {
12172            currApp.lru = 0;
12173        }
12174        return imp;
12175    }
12176
12177    private void fillInProcMemInfo(ProcessRecord app,
12178            ActivityManager.RunningAppProcessInfo outInfo) {
12179        outInfo.pid = app.pid;
12180        outInfo.uid = app.info.uid;
12181        if (mHeavyWeightProcess == app) {
12182            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12183        }
12184        if (app.persistent) {
12185            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12186        }
12187        if (app.activities.size() > 0) {
12188            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12189        }
12190        outInfo.lastTrimLevel = app.trimMemoryLevel;
12191        int adj = app.curAdj;
12192        int procState = app.curProcState;
12193        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12194        outInfo.importanceReasonCode = app.adjTypeCode;
12195        outInfo.processState = app.curProcState;
12196    }
12197
12198    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12199        enforceNotIsolatedCaller("getRunningAppProcesses");
12200        // Lazy instantiation of list
12201        List<ActivityManager.RunningAppProcessInfo> runList = null;
12202        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12203                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12204        int userId = UserHandle.getUserId(Binder.getCallingUid());
12205        synchronized (this) {
12206            // Iterate across all processes
12207            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12208                ProcessRecord app = mLruProcesses.get(i);
12209                if (!allUsers && app.userId != userId) {
12210                    continue;
12211                }
12212                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12213                    // Generate process state info for running application
12214                    ActivityManager.RunningAppProcessInfo currApp =
12215                        new ActivityManager.RunningAppProcessInfo(app.processName,
12216                                app.pid, app.getPackageList());
12217                    fillInProcMemInfo(app, currApp);
12218                    if (app.adjSource instanceof ProcessRecord) {
12219                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12220                        currApp.importanceReasonImportance =
12221                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12222                                        app.adjSourceProcState);
12223                    } else if (app.adjSource instanceof ActivityRecord) {
12224                        ActivityRecord r = (ActivityRecord)app.adjSource;
12225                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12226                    }
12227                    if (app.adjTarget instanceof ComponentName) {
12228                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12229                    }
12230                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12231                    //        + " lru=" + currApp.lru);
12232                    if (runList == null) {
12233                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12234                    }
12235                    runList.add(currApp);
12236                }
12237            }
12238        }
12239        return runList;
12240    }
12241
12242    public List<ApplicationInfo> getRunningExternalApplications() {
12243        enforceNotIsolatedCaller("getRunningExternalApplications");
12244        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12245        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12246        if (runningApps != null && runningApps.size() > 0) {
12247            Set<String> extList = new HashSet<String>();
12248            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12249                if (app.pkgList != null) {
12250                    for (String pkg : app.pkgList) {
12251                        extList.add(pkg);
12252                    }
12253                }
12254            }
12255            IPackageManager pm = AppGlobals.getPackageManager();
12256            for (String pkg : extList) {
12257                try {
12258                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12259                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12260                        retList.add(info);
12261                    }
12262                } catch (RemoteException e) {
12263                }
12264            }
12265        }
12266        return retList;
12267    }
12268
12269    @Override
12270    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12271        enforceNotIsolatedCaller("getMyMemoryState");
12272        synchronized (this) {
12273            ProcessRecord proc;
12274            synchronized (mPidsSelfLocked) {
12275                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12276            }
12277            fillInProcMemInfo(proc, outInfo);
12278        }
12279    }
12280
12281    @Override
12282    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12283        if (checkCallingPermission(android.Manifest.permission.DUMP)
12284                != PackageManager.PERMISSION_GRANTED) {
12285            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12286                    + Binder.getCallingPid()
12287                    + ", uid=" + Binder.getCallingUid()
12288                    + " without permission "
12289                    + android.Manifest.permission.DUMP);
12290            return;
12291        }
12292
12293        boolean dumpAll = false;
12294        boolean dumpClient = false;
12295        String dumpPackage = null;
12296
12297        int opti = 0;
12298        while (opti < args.length) {
12299            String opt = args[opti];
12300            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12301                break;
12302            }
12303            opti++;
12304            if ("-a".equals(opt)) {
12305                dumpAll = true;
12306            } else if ("-c".equals(opt)) {
12307                dumpClient = true;
12308            } else if ("-h".equals(opt)) {
12309                pw.println("Activity manager dump options:");
12310                pw.println("  [-a] [-c] [-h] [cmd] ...");
12311                pw.println("  cmd may be one of:");
12312                pw.println("    a[ctivities]: activity stack state");
12313                pw.println("    r[recents]: recent activities state");
12314                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12315                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12316                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12317                pw.println("    o[om]: out of memory management");
12318                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12319                pw.println("    provider [COMP_SPEC]: provider client-side state");
12320                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12321                pw.println("    service [COMP_SPEC]: service client-side state");
12322                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12323                pw.println("    all: dump all activities");
12324                pw.println("    top: dump the top activity");
12325                pw.println("    write: write all pending state to storage");
12326                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12327                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12328                pw.println("    a partial substring in a component name, a");
12329                pw.println("    hex object identifier.");
12330                pw.println("  -a: include all available server state.");
12331                pw.println("  -c: include client state.");
12332                return;
12333            } else {
12334                pw.println("Unknown argument: " + opt + "; use -h for help");
12335            }
12336        }
12337
12338        long origId = Binder.clearCallingIdentity();
12339        boolean more = false;
12340        // Is the caller requesting to dump a particular piece of data?
12341        if (opti < args.length) {
12342            String cmd = args[opti];
12343            opti++;
12344            if ("activities".equals(cmd) || "a".equals(cmd)) {
12345                synchronized (this) {
12346                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12347                }
12348            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12349                synchronized (this) {
12350                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12351                }
12352            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12353                String[] newArgs;
12354                String name;
12355                if (opti >= args.length) {
12356                    name = null;
12357                    newArgs = EMPTY_STRING_ARRAY;
12358                } else {
12359                    name = args[opti];
12360                    opti++;
12361                    newArgs = new String[args.length - opti];
12362                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12363                            args.length - opti);
12364                }
12365                synchronized (this) {
12366                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12367                }
12368            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12369                String[] newArgs;
12370                String name;
12371                if (opti >= args.length) {
12372                    name = null;
12373                    newArgs = EMPTY_STRING_ARRAY;
12374                } else {
12375                    name = args[opti];
12376                    opti++;
12377                    newArgs = new String[args.length - opti];
12378                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12379                            args.length - opti);
12380                }
12381                synchronized (this) {
12382                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12383                }
12384            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12385                String[] newArgs;
12386                String name;
12387                if (opti >= args.length) {
12388                    name = null;
12389                    newArgs = EMPTY_STRING_ARRAY;
12390                } else {
12391                    name = args[opti];
12392                    opti++;
12393                    newArgs = new String[args.length - opti];
12394                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12395                            args.length - opti);
12396                }
12397                synchronized (this) {
12398                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12399                }
12400            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12401                synchronized (this) {
12402                    dumpOomLocked(fd, pw, args, opti, true);
12403                }
12404            } else if ("provider".equals(cmd)) {
12405                String[] newArgs;
12406                String name;
12407                if (opti >= args.length) {
12408                    name = null;
12409                    newArgs = EMPTY_STRING_ARRAY;
12410                } else {
12411                    name = args[opti];
12412                    opti++;
12413                    newArgs = new String[args.length - opti];
12414                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12415                }
12416                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12417                    pw.println("No providers match: " + name);
12418                    pw.println("Use -h for help.");
12419                }
12420            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12421                synchronized (this) {
12422                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12423                }
12424            } else if ("service".equals(cmd)) {
12425                String[] newArgs;
12426                String name;
12427                if (opti >= args.length) {
12428                    name = null;
12429                    newArgs = EMPTY_STRING_ARRAY;
12430                } else {
12431                    name = args[opti];
12432                    opti++;
12433                    newArgs = new String[args.length - opti];
12434                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12435                            args.length - opti);
12436                }
12437                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12438                    pw.println("No services match: " + name);
12439                    pw.println("Use -h for help.");
12440                }
12441            } else if ("package".equals(cmd)) {
12442                String[] newArgs;
12443                if (opti >= args.length) {
12444                    pw.println("package: no package name specified");
12445                    pw.println("Use -h for help.");
12446                } else {
12447                    dumpPackage = args[opti];
12448                    opti++;
12449                    newArgs = new String[args.length - opti];
12450                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12451                            args.length - opti);
12452                    args = newArgs;
12453                    opti = 0;
12454                    more = true;
12455                }
12456            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12457                synchronized (this) {
12458                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12459                }
12460            } else if ("write".equals(cmd)) {
12461                mTaskPersister.flush();
12462                pw.println("All tasks persisted.");
12463                return;
12464            } else {
12465                // Dumping a single activity?
12466                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12467                    pw.println("Bad activity command, or no activities match: " + cmd);
12468                    pw.println("Use -h for help.");
12469                }
12470            }
12471            if (!more) {
12472                Binder.restoreCallingIdentity(origId);
12473                return;
12474            }
12475        }
12476
12477        // No piece of data specified, dump everything.
12478        synchronized (this) {
12479            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12480            pw.println();
12481            if (dumpAll) {
12482                pw.println("-------------------------------------------------------------------------------");
12483            }
12484            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12485            pw.println();
12486            if (dumpAll) {
12487                pw.println("-------------------------------------------------------------------------------");
12488            }
12489            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12490            pw.println();
12491            if (dumpAll) {
12492                pw.println("-------------------------------------------------------------------------------");
12493            }
12494            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12495            pw.println();
12496            if (dumpAll) {
12497                pw.println("-------------------------------------------------------------------------------");
12498            }
12499            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12500            pw.println();
12501            if (dumpAll) {
12502                pw.println("-------------------------------------------------------------------------------");
12503            }
12504            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12505            pw.println();
12506            if (dumpAll) {
12507                pw.println("-------------------------------------------------------------------------------");
12508            }
12509            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12510        }
12511        Binder.restoreCallingIdentity(origId);
12512    }
12513
12514    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12515            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12516        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12517
12518        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12519                dumpPackage);
12520        boolean needSep = printedAnything;
12521
12522        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12523                dumpPackage, needSep, "  mFocusedActivity: ");
12524        if (printed) {
12525            printedAnything = true;
12526            needSep = false;
12527        }
12528
12529        if (dumpPackage == null) {
12530            if (needSep) {
12531                pw.println();
12532            }
12533            needSep = true;
12534            printedAnything = true;
12535            mStackSupervisor.dump(pw, "  ");
12536        }
12537
12538        if (!printedAnything) {
12539            pw.println("  (nothing)");
12540        }
12541    }
12542
12543    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12544            int opti, boolean dumpAll, String dumpPackage) {
12545        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12546
12547        boolean printedAnything = false;
12548
12549        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12550            boolean printedHeader = false;
12551
12552            final int N = mRecentTasks.size();
12553            for (int i=0; i<N; i++) {
12554                TaskRecord tr = mRecentTasks.get(i);
12555                if (dumpPackage != null) {
12556                    if (tr.realActivity == null ||
12557                            !dumpPackage.equals(tr.realActivity)) {
12558                        continue;
12559                    }
12560                }
12561                if (!printedHeader) {
12562                    pw.println("  Recent tasks:");
12563                    printedHeader = true;
12564                    printedAnything = true;
12565                }
12566                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12567                        pw.println(tr);
12568                if (dumpAll) {
12569                    mRecentTasks.get(i).dump(pw, "    ");
12570                }
12571            }
12572        }
12573
12574        if (!printedAnything) {
12575            pw.println("  (nothing)");
12576        }
12577    }
12578
12579    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12580            int opti, boolean dumpAll, String dumpPackage) {
12581        boolean needSep = false;
12582        boolean printedAnything = false;
12583        int numPers = 0;
12584
12585        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12586
12587        if (dumpAll) {
12588            final int NP = mProcessNames.getMap().size();
12589            for (int ip=0; ip<NP; ip++) {
12590                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12591                final int NA = procs.size();
12592                for (int ia=0; ia<NA; ia++) {
12593                    ProcessRecord r = procs.valueAt(ia);
12594                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12595                        continue;
12596                    }
12597                    if (!needSep) {
12598                        pw.println("  All known processes:");
12599                        needSep = true;
12600                        printedAnything = true;
12601                    }
12602                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12603                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12604                        pw.print(" "); pw.println(r);
12605                    r.dump(pw, "    ");
12606                    if (r.persistent) {
12607                        numPers++;
12608                    }
12609                }
12610            }
12611        }
12612
12613        if (mIsolatedProcesses.size() > 0) {
12614            boolean printed = false;
12615            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12616                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12617                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12618                    continue;
12619                }
12620                if (!printed) {
12621                    if (needSep) {
12622                        pw.println();
12623                    }
12624                    pw.println("  Isolated process list (sorted by uid):");
12625                    printedAnything = true;
12626                    printed = true;
12627                    needSep = true;
12628                }
12629                pw.println(String.format("%sIsolated #%2d: %s",
12630                        "    ", i, r.toString()));
12631            }
12632        }
12633
12634        if (mLruProcesses.size() > 0) {
12635            if (needSep) {
12636                pw.println();
12637            }
12638            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12639                    pw.print(" total, non-act at ");
12640                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12641                    pw.print(", non-svc at ");
12642                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12643                    pw.println("):");
12644            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12645            needSep = true;
12646            printedAnything = true;
12647        }
12648
12649        if (dumpAll || dumpPackage != null) {
12650            synchronized (mPidsSelfLocked) {
12651                boolean printed = false;
12652                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12653                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12654                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12655                        continue;
12656                    }
12657                    if (!printed) {
12658                        if (needSep) pw.println();
12659                        needSep = true;
12660                        pw.println("  PID mappings:");
12661                        printed = true;
12662                        printedAnything = true;
12663                    }
12664                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12665                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12666                }
12667            }
12668        }
12669
12670        if (mForegroundProcesses.size() > 0) {
12671            synchronized (mPidsSelfLocked) {
12672                boolean printed = false;
12673                for (int i=0; i<mForegroundProcesses.size(); i++) {
12674                    ProcessRecord r = mPidsSelfLocked.get(
12675                            mForegroundProcesses.valueAt(i).pid);
12676                    if (dumpPackage != null && (r == null
12677                            || !r.pkgList.containsKey(dumpPackage))) {
12678                        continue;
12679                    }
12680                    if (!printed) {
12681                        if (needSep) pw.println();
12682                        needSep = true;
12683                        pw.println("  Foreground Processes:");
12684                        printed = true;
12685                        printedAnything = true;
12686                    }
12687                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12688                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12689                }
12690            }
12691        }
12692
12693        if (mPersistentStartingProcesses.size() > 0) {
12694            if (needSep) pw.println();
12695            needSep = true;
12696            printedAnything = true;
12697            pw.println("  Persisent processes that are starting:");
12698            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12699                    "Starting Norm", "Restarting PERS", dumpPackage);
12700        }
12701
12702        if (mRemovedProcesses.size() > 0) {
12703            if (needSep) pw.println();
12704            needSep = true;
12705            printedAnything = true;
12706            pw.println("  Processes that are being removed:");
12707            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12708                    "Removed Norm", "Removed PERS", dumpPackage);
12709        }
12710
12711        if (mProcessesOnHold.size() > 0) {
12712            if (needSep) pw.println();
12713            needSep = true;
12714            printedAnything = true;
12715            pw.println("  Processes that are on old until the system is ready:");
12716            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12717                    "OnHold Norm", "OnHold PERS", dumpPackage);
12718        }
12719
12720        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12721
12722        if (mProcessCrashTimes.getMap().size() > 0) {
12723            boolean printed = false;
12724            long now = SystemClock.uptimeMillis();
12725            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12726            final int NP = pmap.size();
12727            for (int ip=0; ip<NP; ip++) {
12728                String pname = pmap.keyAt(ip);
12729                SparseArray<Long> uids = pmap.valueAt(ip);
12730                final int N = uids.size();
12731                for (int i=0; i<N; i++) {
12732                    int puid = uids.keyAt(i);
12733                    ProcessRecord r = mProcessNames.get(pname, puid);
12734                    if (dumpPackage != null && (r == null
12735                            || !r.pkgList.containsKey(dumpPackage))) {
12736                        continue;
12737                    }
12738                    if (!printed) {
12739                        if (needSep) pw.println();
12740                        needSep = true;
12741                        pw.println("  Time since processes crashed:");
12742                        printed = true;
12743                        printedAnything = true;
12744                    }
12745                    pw.print("    Process "); pw.print(pname);
12746                            pw.print(" uid "); pw.print(puid);
12747                            pw.print(": last crashed ");
12748                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12749                            pw.println(" ago");
12750                }
12751            }
12752        }
12753
12754        if (mBadProcesses.getMap().size() > 0) {
12755            boolean printed = false;
12756            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12757            final int NP = pmap.size();
12758            for (int ip=0; ip<NP; ip++) {
12759                String pname = pmap.keyAt(ip);
12760                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12761                final int N = uids.size();
12762                for (int i=0; i<N; i++) {
12763                    int puid = uids.keyAt(i);
12764                    ProcessRecord r = mProcessNames.get(pname, puid);
12765                    if (dumpPackage != null && (r == null
12766                            || !r.pkgList.containsKey(dumpPackage))) {
12767                        continue;
12768                    }
12769                    if (!printed) {
12770                        if (needSep) pw.println();
12771                        needSep = true;
12772                        pw.println("  Bad processes:");
12773                        printedAnything = true;
12774                    }
12775                    BadProcessInfo info = uids.valueAt(i);
12776                    pw.print("    Bad process "); pw.print(pname);
12777                            pw.print(" uid "); pw.print(puid);
12778                            pw.print(": crashed at time "); pw.println(info.time);
12779                    if (info.shortMsg != null) {
12780                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12781                    }
12782                    if (info.longMsg != null) {
12783                        pw.print("      Long msg: "); pw.println(info.longMsg);
12784                    }
12785                    if (info.stack != null) {
12786                        pw.println("      Stack:");
12787                        int lastPos = 0;
12788                        for (int pos=0; pos<info.stack.length(); pos++) {
12789                            if (info.stack.charAt(pos) == '\n') {
12790                                pw.print("        ");
12791                                pw.write(info.stack, lastPos, pos-lastPos);
12792                                pw.println();
12793                                lastPos = pos+1;
12794                            }
12795                        }
12796                        if (lastPos < info.stack.length()) {
12797                            pw.print("        ");
12798                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12799                            pw.println();
12800                        }
12801                    }
12802                }
12803            }
12804        }
12805
12806        if (dumpPackage == null) {
12807            pw.println();
12808            needSep = false;
12809            pw.println("  mStartedUsers:");
12810            for (int i=0; i<mStartedUsers.size(); i++) {
12811                UserStartedState uss = mStartedUsers.valueAt(i);
12812                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12813                        pw.print(": "); uss.dump("", pw);
12814            }
12815            pw.print("  mStartedUserArray: [");
12816            for (int i=0; i<mStartedUserArray.length; i++) {
12817                if (i > 0) pw.print(", ");
12818                pw.print(mStartedUserArray[i]);
12819            }
12820            pw.println("]");
12821            pw.print("  mUserLru: [");
12822            for (int i=0; i<mUserLru.size(); i++) {
12823                if (i > 0) pw.print(", ");
12824                pw.print(mUserLru.get(i));
12825            }
12826            pw.println("]");
12827            if (dumpAll) {
12828                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12829            }
12830            synchronized (mUserProfileGroupIdsSelfLocked) {
12831                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12832                    pw.println("  mUserProfileGroupIds:");
12833                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12834                        pw.print("    User #");
12835                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12836                        pw.print(" -> profile #");
12837                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12838                    }
12839                }
12840            }
12841        }
12842        if (mHomeProcess != null && (dumpPackage == null
12843                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12844            if (needSep) {
12845                pw.println();
12846                needSep = false;
12847            }
12848            pw.println("  mHomeProcess: " + mHomeProcess);
12849        }
12850        if (mPreviousProcess != null && (dumpPackage == null
12851                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12852            if (needSep) {
12853                pw.println();
12854                needSep = false;
12855            }
12856            pw.println("  mPreviousProcess: " + mPreviousProcess);
12857        }
12858        if (dumpAll) {
12859            StringBuilder sb = new StringBuilder(128);
12860            sb.append("  mPreviousProcessVisibleTime: ");
12861            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12862            pw.println(sb);
12863        }
12864        if (mHeavyWeightProcess != null && (dumpPackage == null
12865                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12866            if (needSep) {
12867                pw.println();
12868                needSep = false;
12869            }
12870            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12871        }
12872        if (dumpPackage == null) {
12873            pw.println("  mConfiguration: " + mConfiguration);
12874        }
12875        if (dumpAll) {
12876            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12877            if (mCompatModePackages.getPackages().size() > 0) {
12878                boolean printed = false;
12879                for (Map.Entry<String, Integer> entry
12880                        : mCompatModePackages.getPackages().entrySet()) {
12881                    String pkg = entry.getKey();
12882                    int mode = entry.getValue();
12883                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12884                        continue;
12885                    }
12886                    if (!printed) {
12887                        pw.println("  mScreenCompatPackages:");
12888                        printed = true;
12889                    }
12890                    pw.print("    "); pw.print(pkg); pw.print(": ");
12891                            pw.print(mode); pw.println();
12892                }
12893            }
12894        }
12895        if (dumpPackage == null) {
12896            pw.println("  mWakefulness="
12897                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
12898            pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
12899                    + lockScreenShownToString());
12900            pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12901        }
12902        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12903                || mOrigWaitForDebugger) {
12904            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12905                    || dumpPackage.equals(mOrigDebugApp)) {
12906                if (needSep) {
12907                    pw.println();
12908                    needSep = false;
12909                }
12910                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12911                        + " mDebugTransient=" + mDebugTransient
12912                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12913            }
12914        }
12915        if (mOpenGlTraceApp != null) {
12916            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12917                if (needSep) {
12918                    pw.println();
12919                    needSep = false;
12920                }
12921                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12922            }
12923        }
12924        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12925                || mProfileFd != null) {
12926            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12927                if (needSep) {
12928                    pw.println();
12929                    needSep = false;
12930                }
12931                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12932                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12933                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12934                        + mAutoStopProfiler);
12935                pw.println("  mProfileType=" + mProfileType);
12936            }
12937        }
12938        if (dumpPackage == null) {
12939            if (mAlwaysFinishActivities || mController != null) {
12940                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12941                        + " mController=" + mController);
12942            }
12943            if (dumpAll) {
12944                pw.println("  Total persistent processes: " + numPers);
12945                pw.println("  mProcessesReady=" + mProcessesReady
12946                        + " mSystemReady=" + mSystemReady
12947                        + " mBooted=" + mBooted
12948                        + " mFactoryTest=" + mFactoryTest);
12949                pw.println("  mBooting=" + mBooting
12950                        + " mCallFinishBooting=" + mCallFinishBooting
12951                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12952                pw.print("  mLastPowerCheckRealtime=");
12953                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12954                        pw.println("");
12955                pw.print("  mLastPowerCheckUptime=");
12956                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12957                        pw.println("");
12958                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12959                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12960                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12961                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12962                        + " (" + mLruProcesses.size() + " total)"
12963                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12964                        + " mNumServiceProcs=" + mNumServiceProcs
12965                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12966                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12967                        + " mLastMemoryLevel" + mLastMemoryLevel
12968                        + " mLastNumProcesses" + mLastNumProcesses);
12969                long now = SystemClock.uptimeMillis();
12970                pw.print("  mLastIdleTime=");
12971                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12972                        pw.print(" mLowRamSinceLastIdle=");
12973                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12974                        pw.println();
12975            }
12976        }
12977
12978        if (!printedAnything) {
12979            pw.println("  (nothing)");
12980        }
12981    }
12982
12983    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12984            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12985        if (mProcessesToGc.size() > 0) {
12986            boolean printed = false;
12987            long now = SystemClock.uptimeMillis();
12988            for (int i=0; i<mProcessesToGc.size(); i++) {
12989                ProcessRecord proc = mProcessesToGc.get(i);
12990                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12991                    continue;
12992                }
12993                if (!printed) {
12994                    if (needSep) pw.println();
12995                    needSep = true;
12996                    pw.println("  Processes that are waiting to GC:");
12997                    printed = true;
12998                }
12999                pw.print("    Process "); pw.println(proc);
13000                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13001                        pw.print(", last gced=");
13002                        pw.print(now-proc.lastRequestedGc);
13003                        pw.print(" ms ago, last lowMem=");
13004                        pw.print(now-proc.lastLowMemory);
13005                        pw.println(" ms ago");
13006
13007            }
13008        }
13009        return needSep;
13010    }
13011
13012    void printOomLevel(PrintWriter pw, String name, int adj) {
13013        pw.print("    ");
13014        if (adj >= 0) {
13015            pw.print(' ');
13016            if (adj < 10) pw.print(' ');
13017        } else {
13018            if (adj > -10) pw.print(' ');
13019        }
13020        pw.print(adj);
13021        pw.print(": ");
13022        pw.print(name);
13023        pw.print(" (");
13024        pw.print(mProcessList.getMemLevel(adj)/1024);
13025        pw.println(" kB)");
13026    }
13027
13028    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13029            int opti, boolean dumpAll) {
13030        boolean needSep = false;
13031
13032        if (mLruProcesses.size() > 0) {
13033            if (needSep) pw.println();
13034            needSep = true;
13035            pw.println("  OOM levels:");
13036            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13037            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13038            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13039            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13040            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13041            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13042            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13043            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13044            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13045            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13046            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13047            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13048            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13049            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13050
13051            if (needSep) pw.println();
13052            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13053                    pw.print(" total, non-act at ");
13054                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13055                    pw.print(", non-svc at ");
13056                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13057                    pw.println("):");
13058            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13059            needSep = true;
13060        }
13061
13062        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13063
13064        pw.println();
13065        pw.println("  mHomeProcess: " + mHomeProcess);
13066        pw.println("  mPreviousProcess: " + mPreviousProcess);
13067        if (mHeavyWeightProcess != null) {
13068            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13069        }
13070
13071        return true;
13072    }
13073
13074    /**
13075     * There are three ways to call this:
13076     *  - no provider specified: dump all the providers
13077     *  - a flattened component name that matched an existing provider was specified as the
13078     *    first arg: dump that one provider
13079     *  - the first arg isn't the flattened component name of an existing provider:
13080     *    dump all providers whose component contains the first arg as a substring
13081     */
13082    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13083            int opti, boolean dumpAll) {
13084        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13085    }
13086
13087    static class ItemMatcher {
13088        ArrayList<ComponentName> components;
13089        ArrayList<String> strings;
13090        ArrayList<Integer> objects;
13091        boolean all;
13092
13093        ItemMatcher() {
13094            all = true;
13095        }
13096
13097        void build(String name) {
13098            ComponentName componentName = ComponentName.unflattenFromString(name);
13099            if (componentName != null) {
13100                if (components == null) {
13101                    components = new ArrayList<ComponentName>();
13102                }
13103                components.add(componentName);
13104                all = false;
13105            } else {
13106                int objectId = 0;
13107                // Not a '/' separated full component name; maybe an object ID?
13108                try {
13109                    objectId = Integer.parseInt(name, 16);
13110                    if (objects == null) {
13111                        objects = new ArrayList<Integer>();
13112                    }
13113                    objects.add(objectId);
13114                    all = false;
13115                } catch (RuntimeException e) {
13116                    // Not an integer; just do string match.
13117                    if (strings == null) {
13118                        strings = new ArrayList<String>();
13119                    }
13120                    strings.add(name);
13121                    all = false;
13122                }
13123            }
13124        }
13125
13126        int build(String[] args, int opti) {
13127            for (; opti<args.length; opti++) {
13128                String name = args[opti];
13129                if ("--".equals(name)) {
13130                    return opti+1;
13131                }
13132                build(name);
13133            }
13134            return opti;
13135        }
13136
13137        boolean match(Object object, ComponentName comp) {
13138            if (all) {
13139                return true;
13140            }
13141            if (components != null) {
13142                for (int i=0; i<components.size(); i++) {
13143                    if (components.get(i).equals(comp)) {
13144                        return true;
13145                    }
13146                }
13147            }
13148            if (objects != null) {
13149                for (int i=0; i<objects.size(); i++) {
13150                    if (System.identityHashCode(object) == objects.get(i)) {
13151                        return true;
13152                    }
13153                }
13154            }
13155            if (strings != null) {
13156                String flat = comp.flattenToString();
13157                for (int i=0; i<strings.size(); i++) {
13158                    if (flat.contains(strings.get(i))) {
13159                        return true;
13160                    }
13161                }
13162            }
13163            return false;
13164        }
13165    }
13166
13167    /**
13168     * There are three things that cmd can be:
13169     *  - a flattened component name that matches an existing activity
13170     *  - the cmd arg isn't the flattened component name of an existing activity:
13171     *    dump all activity whose component contains the cmd as a substring
13172     *  - A hex number of the ActivityRecord object instance.
13173     */
13174    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13175            int opti, boolean dumpAll) {
13176        ArrayList<ActivityRecord> activities;
13177
13178        synchronized (this) {
13179            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13180        }
13181
13182        if (activities.size() <= 0) {
13183            return false;
13184        }
13185
13186        String[] newArgs = new String[args.length - opti];
13187        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13188
13189        TaskRecord lastTask = null;
13190        boolean needSep = false;
13191        for (int i=activities.size()-1; i>=0; i--) {
13192            ActivityRecord r = activities.get(i);
13193            if (needSep) {
13194                pw.println();
13195            }
13196            needSep = true;
13197            synchronized (this) {
13198                if (lastTask != r.task) {
13199                    lastTask = r.task;
13200                    pw.print("TASK "); pw.print(lastTask.affinity);
13201                            pw.print(" id="); pw.println(lastTask.taskId);
13202                    if (dumpAll) {
13203                        lastTask.dump(pw, "  ");
13204                    }
13205                }
13206            }
13207            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13208        }
13209        return true;
13210    }
13211
13212    /**
13213     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13214     * there is a thread associated with the activity.
13215     */
13216    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13217            final ActivityRecord r, String[] args, boolean dumpAll) {
13218        String innerPrefix = prefix + "  ";
13219        synchronized (this) {
13220            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13221                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13222                    pw.print(" pid=");
13223                    if (r.app != null) pw.println(r.app.pid);
13224                    else pw.println("(not running)");
13225            if (dumpAll) {
13226                r.dump(pw, innerPrefix);
13227            }
13228        }
13229        if (r.app != null && r.app.thread != null) {
13230            // flush anything that is already in the PrintWriter since the thread is going
13231            // to write to the file descriptor directly
13232            pw.flush();
13233            try {
13234                TransferPipe tp = new TransferPipe();
13235                try {
13236                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13237                            r.appToken, innerPrefix, args);
13238                    tp.go(fd);
13239                } finally {
13240                    tp.kill();
13241                }
13242            } catch (IOException e) {
13243                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13244            } catch (RemoteException e) {
13245                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13246            }
13247        }
13248    }
13249
13250    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13251            int opti, boolean dumpAll, String dumpPackage) {
13252        boolean needSep = false;
13253        boolean onlyHistory = false;
13254        boolean printedAnything = false;
13255
13256        if ("history".equals(dumpPackage)) {
13257            if (opti < args.length && "-s".equals(args[opti])) {
13258                dumpAll = false;
13259            }
13260            onlyHistory = true;
13261            dumpPackage = null;
13262        }
13263
13264        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13265        if (!onlyHistory && dumpAll) {
13266            if (mRegisteredReceivers.size() > 0) {
13267                boolean printed = false;
13268                Iterator it = mRegisteredReceivers.values().iterator();
13269                while (it.hasNext()) {
13270                    ReceiverList r = (ReceiverList)it.next();
13271                    if (dumpPackage != null && (r.app == null ||
13272                            !dumpPackage.equals(r.app.info.packageName))) {
13273                        continue;
13274                    }
13275                    if (!printed) {
13276                        pw.println("  Registered Receivers:");
13277                        needSep = true;
13278                        printed = true;
13279                        printedAnything = true;
13280                    }
13281                    pw.print("  * "); pw.println(r);
13282                    r.dump(pw, "    ");
13283                }
13284            }
13285
13286            if (mReceiverResolver.dump(pw, needSep ?
13287                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13288                    "    ", dumpPackage, false, false)) {
13289                needSep = true;
13290                printedAnything = true;
13291            }
13292        }
13293
13294        for (BroadcastQueue q : mBroadcastQueues) {
13295            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13296            printedAnything |= needSep;
13297        }
13298
13299        needSep = true;
13300
13301        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13302            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13303                if (needSep) {
13304                    pw.println();
13305                }
13306                needSep = true;
13307                printedAnything = true;
13308                pw.print("  Sticky broadcasts for user ");
13309                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13310                StringBuilder sb = new StringBuilder(128);
13311                for (Map.Entry<String, ArrayList<Intent>> ent
13312                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13313                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13314                    if (dumpAll) {
13315                        pw.println(":");
13316                        ArrayList<Intent> intents = ent.getValue();
13317                        final int N = intents.size();
13318                        for (int i=0; i<N; i++) {
13319                            sb.setLength(0);
13320                            sb.append("    Intent: ");
13321                            intents.get(i).toShortString(sb, false, true, false, false);
13322                            pw.println(sb.toString());
13323                            Bundle bundle = intents.get(i).getExtras();
13324                            if (bundle != null) {
13325                                pw.print("      ");
13326                                pw.println(bundle.toString());
13327                            }
13328                        }
13329                    } else {
13330                        pw.println("");
13331                    }
13332                }
13333            }
13334        }
13335
13336        if (!onlyHistory && dumpAll) {
13337            pw.println();
13338            for (BroadcastQueue queue : mBroadcastQueues) {
13339                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13340                        + queue.mBroadcastsScheduled);
13341            }
13342            pw.println("  mHandler:");
13343            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13344            needSep = true;
13345            printedAnything = true;
13346        }
13347
13348        if (!printedAnything) {
13349            pw.println("  (nothing)");
13350        }
13351    }
13352
13353    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13354            int opti, boolean dumpAll, String dumpPackage) {
13355        boolean needSep;
13356        boolean printedAnything = false;
13357
13358        ItemMatcher matcher = new ItemMatcher();
13359        matcher.build(args, opti);
13360
13361        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13362
13363        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13364        printedAnything |= needSep;
13365
13366        if (mLaunchingProviders.size() > 0) {
13367            boolean printed = false;
13368            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13369                ContentProviderRecord r = mLaunchingProviders.get(i);
13370                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13371                    continue;
13372                }
13373                if (!printed) {
13374                    if (needSep) pw.println();
13375                    needSep = true;
13376                    pw.println("  Launching content providers:");
13377                    printed = true;
13378                    printedAnything = true;
13379                }
13380                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13381                        pw.println(r);
13382            }
13383        }
13384
13385        if (mGrantedUriPermissions.size() > 0) {
13386            boolean printed = false;
13387            int dumpUid = -2;
13388            if (dumpPackage != null) {
13389                try {
13390                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13391                } catch (NameNotFoundException e) {
13392                    dumpUid = -1;
13393                }
13394            }
13395            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13396                int uid = mGrantedUriPermissions.keyAt(i);
13397                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13398                    continue;
13399                }
13400                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13401                if (!printed) {
13402                    if (needSep) pw.println();
13403                    needSep = true;
13404                    pw.println("  Granted Uri Permissions:");
13405                    printed = true;
13406                    printedAnything = true;
13407                }
13408                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13409                for (UriPermission perm : perms.values()) {
13410                    pw.print("    "); pw.println(perm);
13411                    if (dumpAll) {
13412                        perm.dump(pw, "      ");
13413                    }
13414                }
13415            }
13416        }
13417
13418        if (!printedAnything) {
13419            pw.println("  (nothing)");
13420        }
13421    }
13422
13423    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13424            int opti, boolean dumpAll, String dumpPackage) {
13425        boolean printed = false;
13426
13427        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13428
13429        if (mIntentSenderRecords.size() > 0) {
13430            Iterator<WeakReference<PendingIntentRecord>> it
13431                    = mIntentSenderRecords.values().iterator();
13432            while (it.hasNext()) {
13433                WeakReference<PendingIntentRecord> ref = it.next();
13434                PendingIntentRecord rec = ref != null ? ref.get(): null;
13435                if (dumpPackage != null && (rec == null
13436                        || !dumpPackage.equals(rec.key.packageName))) {
13437                    continue;
13438                }
13439                printed = true;
13440                if (rec != null) {
13441                    pw.print("  * "); pw.println(rec);
13442                    if (dumpAll) {
13443                        rec.dump(pw, "    ");
13444                    }
13445                } else {
13446                    pw.print("  * "); pw.println(ref);
13447                }
13448            }
13449        }
13450
13451        if (!printed) {
13452            pw.println("  (nothing)");
13453        }
13454    }
13455
13456    private static final int dumpProcessList(PrintWriter pw,
13457            ActivityManagerService service, List list,
13458            String prefix, String normalLabel, String persistentLabel,
13459            String dumpPackage) {
13460        int numPers = 0;
13461        final int N = list.size()-1;
13462        for (int i=N; i>=0; i--) {
13463            ProcessRecord r = (ProcessRecord)list.get(i);
13464            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13465                continue;
13466            }
13467            pw.println(String.format("%s%s #%2d: %s",
13468                    prefix, (r.persistent ? persistentLabel : normalLabel),
13469                    i, r.toString()));
13470            if (r.persistent) {
13471                numPers++;
13472            }
13473        }
13474        return numPers;
13475    }
13476
13477    private static final boolean dumpProcessOomList(PrintWriter pw,
13478            ActivityManagerService service, List<ProcessRecord> origList,
13479            String prefix, String normalLabel, String persistentLabel,
13480            boolean inclDetails, String dumpPackage) {
13481
13482        ArrayList<Pair<ProcessRecord, Integer>> list
13483                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13484        for (int i=0; i<origList.size(); i++) {
13485            ProcessRecord r = origList.get(i);
13486            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13487                continue;
13488            }
13489            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13490        }
13491
13492        if (list.size() <= 0) {
13493            return false;
13494        }
13495
13496        Comparator<Pair<ProcessRecord, Integer>> comparator
13497                = new Comparator<Pair<ProcessRecord, Integer>>() {
13498            @Override
13499            public int compare(Pair<ProcessRecord, Integer> object1,
13500                    Pair<ProcessRecord, Integer> object2) {
13501                if (object1.first.setAdj != object2.first.setAdj) {
13502                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13503                }
13504                if (object1.second.intValue() != object2.second.intValue()) {
13505                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13506                }
13507                return 0;
13508            }
13509        };
13510
13511        Collections.sort(list, comparator);
13512
13513        final long curRealtime = SystemClock.elapsedRealtime();
13514        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13515        final long curUptime = SystemClock.uptimeMillis();
13516        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13517
13518        for (int i=list.size()-1; i>=0; i--) {
13519            ProcessRecord r = list.get(i).first;
13520            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13521            char schedGroup;
13522            switch (r.setSchedGroup) {
13523                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13524                    schedGroup = 'B';
13525                    break;
13526                case Process.THREAD_GROUP_DEFAULT:
13527                    schedGroup = 'F';
13528                    break;
13529                default:
13530                    schedGroup = '?';
13531                    break;
13532            }
13533            char foreground;
13534            if (r.foregroundActivities) {
13535                foreground = 'A';
13536            } else if (r.foregroundServices) {
13537                foreground = 'S';
13538            } else {
13539                foreground = ' ';
13540            }
13541            String procState = ProcessList.makeProcStateString(r.curProcState);
13542            pw.print(prefix);
13543            pw.print(r.persistent ? persistentLabel : normalLabel);
13544            pw.print(" #");
13545            int num = (origList.size()-1)-list.get(i).second;
13546            if (num < 10) pw.print(' ');
13547            pw.print(num);
13548            pw.print(": ");
13549            pw.print(oomAdj);
13550            pw.print(' ');
13551            pw.print(schedGroup);
13552            pw.print('/');
13553            pw.print(foreground);
13554            pw.print('/');
13555            pw.print(procState);
13556            pw.print(" trm:");
13557            if (r.trimMemoryLevel < 10) pw.print(' ');
13558            pw.print(r.trimMemoryLevel);
13559            pw.print(' ');
13560            pw.print(r.toShortString());
13561            pw.print(" (");
13562            pw.print(r.adjType);
13563            pw.println(')');
13564            if (r.adjSource != null || r.adjTarget != null) {
13565                pw.print(prefix);
13566                pw.print("    ");
13567                if (r.adjTarget instanceof ComponentName) {
13568                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13569                } else if (r.adjTarget != null) {
13570                    pw.print(r.adjTarget.toString());
13571                } else {
13572                    pw.print("{null}");
13573                }
13574                pw.print("<=");
13575                if (r.adjSource instanceof ProcessRecord) {
13576                    pw.print("Proc{");
13577                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13578                    pw.println("}");
13579                } else if (r.adjSource != null) {
13580                    pw.println(r.adjSource.toString());
13581                } else {
13582                    pw.println("{null}");
13583                }
13584            }
13585            if (inclDetails) {
13586                pw.print(prefix);
13587                pw.print("    ");
13588                pw.print("oom: max="); pw.print(r.maxAdj);
13589                pw.print(" curRaw="); pw.print(r.curRawAdj);
13590                pw.print(" setRaw="); pw.print(r.setRawAdj);
13591                pw.print(" cur="); pw.print(r.curAdj);
13592                pw.print(" set="); pw.println(r.setAdj);
13593                pw.print(prefix);
13594                pw.print("    ");
13595                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13596                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13597                pw.print(" lastPss="); pw.print(r.lastPss);
13598                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13599                pw.print(prefix);
13600                pw.print("    ");
13601                pw.print("cached="); pw.print(r.cached);
13602                pw.print(" empty="); pw.print(r.empty);
13603                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13604
13605                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13606                    if (r.lastWakeTime != 0) {
13607                        long wtime;
13608                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13609                        synchronized (stats) {
13610                            wtime = stats.getProcessWakeTime(r.info.uid,
13611                                    r.pid, curRealtime);
13612                        }
13613                        long timeUsed = wtime - r.lastWakeTime;
13614                        pw.print(prefix);
13615                        pw.print("    ");
13616                        pw.print("keep awake over ");
13617                        TimeUtils.formatDuration(realtimeSince, pw);
13618                        pw.print(" used ");
13619                        TimeUtils.formatDuration(timeUsed, pw);
13620                        pw.print(" (");
13621                        pw.print((timeUsed*100)/realtimeSince);
13622                        pw.println("%)");
13623                    }
13624                    if (r.lastCpuTime != 0) {
13625                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13626                        pw.print(prefix);
13627                        pw.print("    ");
13628                        pw.print("run cpu over ");
13629                        TimeUtils.formatDuration(uptimeSince, pw);
13630                        pw.print(" used ");
13631                        TimeUtils.formatDuration(timeUsed, pw);
13632                        pw.print(" (");
13633                        pw.print((timeUsed*100)/uptimeSince);
13634                        pw.println("%)");
13635                    }
13636                }
13637            }
13638        }
13639        return true;
13640    }
13641
13642    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13643            String[] args) {
13644        ArrayList<ProcessRecord> procs;
13645        synchronized (this) {
13646            if (args != null && args.length > start
13647                    && args[start].charAt(0) != '-') {
13648                procs = new ArrayList<ProcessRecord>();
13649                int pid = -1;
13650                try {
13651                    pid = Integer.parseInt(args[start]);
13652                } catch (NumberFormatException e) {
13653                }
13654                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13655                    ProcessRecord proc = mLruProcesses.get(i);
13656                    if (proc.pid == pid) {
13657                        procs.add(proc);
13658                    } else if (allPkgs && proc.pkgList != null
13659                            && proc.pkgList.containsKey(args[start])) {
13660                        procs.add(proc);
13661                    } else if (proc.processName.equals(args[start])) {
13662                        procs.add(proc);
13663                    }
13664                }
13665                if (procs.size() <= 0) {
13666                    return null;
13667                }
13668            } else {
13669                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13670            }
13671        }
13672        return procs;
13673    }
13674
13675    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13676            PrintWriter pw, String[] args) {
13677        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13678        if (procs == null) {
13679            pw.println("No process found for: " + args[0]);
13680            return;
13681        }
13682
13683        long uptime = SystemClock.uptimeMillis();
13684        long realtime = SystemClock.elapsedRealtime();
13685        pw.println("Applications Graphics Acceleration Info:");
13686        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13687
13688        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13689            ProcessRecord r = procs.get(i);
13690            if (r.thread != null) {
13691                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13692                pw.flush();
13693                try {
13694                    TransferPipe tp = new TransferPipe();
13695                    try {
13696                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13697                        tp.go(fd);
13698                    } finally {
13699                        tp.kill();
13700                    }
13701                } catch (IOException e) {
13702                    pw.println("Failure while dumping the app: " + r);
13703                    pw.flush();
13704                } catch (RemoteException e) {
13705                    pw.println("Got a RemoteException while dumping the app " + r);
13706                    pw.flush();
13707                }
13708            }
13709        }
13710    }
13711
13712    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13713        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13714        if (procs == null) {
13715            pw.println("No process found for: " + args[0]);
13716            return;
13717        }
13718
13719        pw.println("Applications Database Info:");
13720
13721        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13722            ProcessRecord r = procs.get(i);
13723            if (r.thread != null) {
13724                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13725                pw.flush();
13726                try {
13727                    TransferPipe tp = new TransferPipe();
13728                    try {
13729                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13730                        tp.go(fd);
13731                    } finally {
13732                        tp.kill();
13733                    }
13734                } catch (IOException e) {
13735                    pw.println("Failure while dumping the app: " + r);
13736                    pw.flush();
13737                } catch (RemoteException e) {
13738                    pw.println("Got a RemoteException while dumping the app " + r);
13739                    pw.flush();
13740                }
13741            }
13742        }
13743    }
13744
13745    final static class MemItem {
13746        final boolean isProc;
13747        final String label;
13748        final String shortLabel;
13749        final long pss;
13750        final int id;
13751        final boolean hasActivities;
13752        ArrayList<MemItem> subitems;
13753
13754        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13755                boolean _hasActivities) {
13756            isProc = true;
13757            label = _label;
13758            shortLabel = _shortLabel;
13759            pss = _pss;
13760            id = _id;
13761            hasActivities = _hasActivities;
13762        }
13763
13764        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13765            isProc = false;
13766            label = _label;
13767            shortLabel = _shortLabel;
13768            pss = _pss;
13769            id = _id;
13770            hasActivities = false;
13771        }
13772    }
13773
13774    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13775            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13776        if (sort && !isCompact) {
13777            Collections.sort(items, new Comparator<MemItem>() {
13778                @Override
13779                public int compare(MemItem lhs, MemItem rhs) {
13780                    if (lhs.pss < rhs.pss) {
13781                        return 1;
13782                    } else if (lhs.pss > rhs.pss) {
13783                        return -1;
13784                    }
13785                    return 0;
13786                }
13787            });
13788        }
13789
13790        for (int i=0; i<items.size(); i++) {
13791            MemItem mi = items.get(i);
13792            if (!isCompact) {
13793                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13794            } else if (mi.isProc) {
13795                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13796                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13797                pw.println(mi.hasActivities ? ",a" : ",e");
13798            } else {
13799                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13800                pw.println(mi.pss);
13801            }
13802            if (mi.subitems != null) {
13803                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13804                        true, isCompact);
13805            }
13806        }
13807    }
13808
13809    // These are in KB.
13810    static final long[] DUMP_MEM_BUCKETS = new long[] {
13811        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13812        120*1024, 160*1024, 200*1024,
13813        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13814        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13815    };
13816
13817    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13818            boolean stackLike) {
13819        int start = label.lastIndexOf('.');
13820        if (start >= 0) start++;
13821        else start = 0;
13822        int end = label.length();
13823        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13824            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13825                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13826                out.append(bucket);
13827                out.append(stackLike ? "MB." : "MB ");
13828                out.append(label, start, end);
13829                return;
13830            }
13831        }
13832        out.append(memKB/1024);
13833        out.append(stackLike ? "MB." : "MB ");
13834        out.append(label, start, end);
13835    }
13836
13837    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13838            ProcessList.NATIVE_ADJ,
13839            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13840            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13841            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13842            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13843            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13844            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13845    };
13846    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13847            "Native",
13848            "System", "Persistent", "Persistent Service", "Foreground",
13849            "Visible", "Perceptible",
13850            "Heavy Weight", "Backup",
13851            "A Services", "Home",
13852            "Previous", "B Services", "Cached"
13853    };
13854    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13855            "native",
13856            "sys", "pers", "persvc", "fore",
13857            "vis", "percept",
13858            "heavy", "backup",
13859            "servicea", "home",
13860            "prev", "serviceb", "cached"
13861    };
13862
13863    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13864            long realtime, boolean isCheckinRequest, boolean isCompact) {
13865        if (isCheckinRequest || isCompact) {
13866            // short checkin version
13867            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13868        } else {
13869            pw.println("Applications Memory Usage (kB):");
13870            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13871        }
13872    }
13873
13874    private static final int KSM_SHARED = 0;
13875    private static final int KSM_SHARING = 1;
13876    private static final int KSM_UNSHARED = 2;
13877    private static final int KSM_VOLATILE = 3;
13878
13879    private final long[] getKsmInfo() {
13880        long[] longOut = new long[4];
13881        final int[] SINGLE_LONG_FORMAT = new int[] {
13882            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13883        };
13884        long[] longTmp = new long[1];
13885        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13886                SINGLE_LONG_FORMAT, null, longTmp, null);
13887        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13888        longTmp[0] = 0;
13889        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13890                SINGLE_LONG_FORMAT, null, longTmp, null);
13891        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13892        longTmp[0] = 0;
13893        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13894                SINGLE_LONG_FORMAT, null, longTmp, null);
13895        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13896        longTmp[0] = 0;
13897        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13898                SINGLE_LONG_FORMAT, null, longTmp, null);
13899        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13900        return longOut;
13901    }
13902
13903    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13904            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13905        boolean dumpDetails = false;
13906        boolean dumpFullDetails = false;
13907        boolean dumpDalvik = false;
13908        boolean oomOnly = false;
13909        boolean isCompact = false;
13910        boolean localOnly = false;
13911        boolean packages = false;
13912
13913        int opti = 0;
13914        while (opti < args.length) {
13915            String opt = args[opti];
13916            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13917                break;
13918            }
13919            opti++;
13920            if ("-a".equals(opt)) {
13921                dumpDetails = true;
13922                dumpFullDetails = true;
13923                dumpDalvik = true;
13924            } else if ("-d".equals(opt)) {
13925                dumpDalvik = true;
13926            } else if ("-c".equals(opt)) {
13927                isCompact = true;
13928            } else if ("--oom".equals(opt)) {
13929                oomOnly = true;
13930            } else if ("--local".equals(opt)) {
13931                localOnly = true;
13932            } else if ("--package".equals(opt)) {
13933                packages = true;
13934            } else if ("-h".equals(opt)) {
13935                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13936                pw.println("  -a: include all available information for each process.");
13937                pw.println("  -d: include dalvik details when dumping process details.");
13938                pw.println("  -c: dump in a compact machine-parseable representation.");
13939                pw.println("  --oom: only show processes organized by oom adj.");
13940                pw.println("  --local: only collect details locally, don't call process.");
13941                pw.println("  --package: interpret process arg as package, dumping all");
13942                pw.println("             processes that have loaded that package.");
13943                pw.println("If [process] is specified it can be the name or ");
13944                pw.println("pid of a specific process to dump.");
13945                return;
13946            } else {
13947                pw.println("Unknown argument: " + opt + "; use -h for help");
13948            }
13949        }
13950
13951        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13952        long uptime = SystemClock.uptimeMillis();
13953        long realtime = SystemClock.elapsedRealtime();
13954        final long[] tmpLong = new long[1];
13955
13956        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13957        if (procs == null) {
13958            // No Java processes.  Maybe they want to print a native process.
13959            if (args != null && args.length > opti
13960                    && args[opti].charAt(0) != '-') {
13961                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13962                        = new ArrayList<ProcessCpuTracker.Stats>();
13963                updateCpuStatsNow();
13964                int findPid = -1;
13965                try {
13966                    findPid = Integer.parseInt(args[opti]);
13967                } catch (NumberFormatException e) {
13968                }
13969                synchronized (mProcessCpuTracker) {
13970                    final int N = mProcessCpuTracker.countStats();
13971                    for (int i=0; i<N; i++) {
13972                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13973                        if (st.pid == findPid || (st.baseName != null
13974                                && st.baseName.equals(args[opti]))) {
13975                            nativeProcs.add(st);
13976                        }
13977                    }
13978                }
13979                if (nativeProcs.size() > 0) {
13980                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13981                            isCompact);
13982                    Debug.MemoryInfo mi = null;
13983                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13984                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13985                        final int pid = r.pid;
13986                        if (!isCheckinRequest && dumpDetails) {
13987                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13988                        }
13989                        if (mi == null) {
13990                            mi = new Debug.MemoryInfo();
13991                        }
13992                        if (dumpDetails || (!brief && !oomOnly)) {
13993                            Debug.getMemoryInfo(pid, mi);
13994                        } else {
13995                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13996                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13997                        }
13998                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13999                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14000                        if (isCheckinRequest) {
14001                            pw.println();
14002                        }
14003                    }
14004                    return;
14005                }
14006            }
14007            pw.println("No process found for: " + args[opti]);
14008            return;
14009        }
14010
14011        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14012            dumpDetails = true;
14013        }
14014
14015        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14016
14017        String[] innerArgs = new String[args.length-opti];
14018        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14019
14020        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14021        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14022        long nativePss = 0;
14023        long dalvikPss = 0;
14024        long otherPss = 0;
14025        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14026
14027        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14028        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14029                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14030
14031        long totalPss = 0;
14032        long cachedPss = 0;
14033
14034        Debug.MemoryInfo mi = null;
14035        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14036            final ProcessRecord r = procs.get(i);
14037            final IApplicationThread thread;
14038            final int pid;
14039            final int oomAdj;
14040            final boolean hasActivities;
14041            synchronized (this) {
14042                thread = r.thread;
14043                pid = r.pid;
14044                oomAdj = r.getSetAdjWithServices();
14045                hasActivities = r.activities.size() > 0;
14046            }
14047            if (thread != null) {
14048                if (!isCheckinRequest && dumpDetails) {
14049                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14050                }
14051                if (mi == null) {
14052                    mi = new Debug.MemoryInfo();
14053                }
14054                if (dumpDetails || (!brief && !oomOnly)) {
14055                    Debug.getMemoryInfo(pid, mi);
14056                } else {
14057                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14058                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14059                }
14060                if (dumpDetails) {
14061                    if (localOnly) {
14062                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14063                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14064                        if (isCheckinRequest) {
14065                            pw.println();
14066                        }
14067                    } else {
14068                        try {
14069                            pw.flush();
14070                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14071                                    dumpDalvik, innerArgs);
14072                        } catch (RemoteException e) {
14073                            if (!isCheckinRequest) {
14074                                pw.println("Got RemoteException!");
14075                                pw.flush();
14076                            }
14077                        }
14078                    }
14079                }
14080
14081                final long myTotalPss = mi.getTotalPss();
14082                final long myTotalUss = mi.getTotalUss();
14083
14084                synchronized (this) {
14085                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14086                        // Record this for posterity if the process has been stable.
14087                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14088                    }
14089                }
14090
14091                if (!isCheckinRequest && mi != null) {
14092                    totalPss += myTotalPss;
14093                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14094                            (hasActivities ? " / activities)" : ")"),
14095                            r.processName, myTotalPss, pid, hasActivities);
14096                    procMems.add(pssItem);
14097                    procMemsMap.put(pid, pssItem);
14098
14099                    nativePss += mi.nativePss;
14100                    dalvikPss += mi.dalvikPss;
14101                    otherPss += mi.otherPss;
14102                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14103                        long mem = mi.getOtherPss(j);
14104                        miscPss[j] += mem;
14105                        otherPss -= mem;
14106                    }
14107
14108                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14109                        cachedPss += myTotalPss;
14110                    }
14111
14112                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14113                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14114                                || oomIndex == (oomPss.length-1)) {
14115                            oomPss[oomIndex] += myTotalPss;
14116                            if (oomProcs[oomIndex] == null) {
14117                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14118                            }
14119                            oomProcs[oomIndex].add(pssItem);
14120                            break;
14121                        }
14122                    }
14123                }
14124            }
14125        }
14126
14127        long nativeProcTotalPss = 0;
14128
14129        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14130            // If we are showing aggregations, also look for native processes to
14131            // include so that our aggregations are more accurate.
14132            updateCpuStatsNow();
14133            synchronized (mProcessCpuTracker) {
14134                final int N = mProcessCpuTracker.countStats();
14135                for (int i=0; i<N; i++) {
14136                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14137                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14138                        if (mi == null) {
14139                            mi = new Debug.MemoryInfo();
14140                        }
14141                        if (!brief && !oomOnly) {
14142                            Debug.getMemoryInfo(st.pid, mi);
14143                        } else {
14144                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14145                            mi.nativePrivateDirty = (int)tmpLong[0];
14146                        }
14147
14148                        final long myTotalPss = mi.getTotalPss();
14149                        totalPss += myTotalPss;
14150                        nativeProcTotalPss += myTotalPss;
14151
14152                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14153                                st.name, myTotalPss, st.pid, false);
14154                        procMems.add(pssItem);
14155
14156                        nativePss += mi.nativePss;
14157                        dalvikPss += mi.dalvikPss;
14158                        otherPss += mi.otherPss;
14159                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14160                            long mem = mi.getOtherPss(j);
14161                            miscPss[j] += mem;
14162                            otherPss -= mem;
14163                        }
14164                        oomPss[0] += myTotalPss;
14165                        if (oomProcs[0] == null) {
14166                            oomProcs[0] = new ArrayList<MemItem>();
14167                        }
14168                        oomProcs[0].add(pssItem);
14169                    }
14170                }
14171            }
14172
14173            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14174
14175            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14176            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14177            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14178            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14179                String label = Debug.MemoryInfo.getOtherLabel(j);
14180                catMems.add(new MemItem(label, label, miscPss[j], j));
14181            }
14182
14183            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14184            for (int j=0; j<oomPss.length; j++) {
14185                if (oomPss[j] != 0) {
14186                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14187                            : DUMP_MEM_OOM_LABEL[j];
14188                    MemItem item = new MemItem(label, label, oomPss[j],
14189                            DUMP_MEM_OOM_ADJ[j]);
14190                    item.subitems = oomProcs[j];
14191                    oomMems.add(item);
14192                }
14193            }
14194
14195            if (!brief && !oomOnly && !isCompact) {
14196                pw.println();
14197                pw.println("Total PSS by process:");
14198                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14199                pw.println();
14200            }
14201            if (!isCompact) {
14202                pw.println("Total PSS by OOM adjustment:");
14203            }
14204            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14205            if (!brief && !oomOnly) {
14206                PrintWriter out = categoryPw != null ? categoryPw : pw;
14207                if (!isCompact) {
14208                    out.println();
14209                    out.println("Total PSS by category:");
14210                }
14211                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14212            }
14213            if (!isCompact) {
14214                pw.println();
14215            }
14216            MemInfoReader memInfo = new MemInfoReader();
14217            memInfo.readMemInfo();
14218            if (nativeProcTotalPss > 0) {
14219                synchronized (this) {
14220                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14221                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14222                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14223                }
14224            }
14225            if (!brief) {
14226                if (!isCompact) {
14227                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14228                    pw.print(" kB (status ");
14229                    switch (mLastMemoryLevel) {
14230                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14231                            pw.println("normal)");
14232                            break;
14233                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14234                            pw.println("moderate)");
14235                            break;
14236                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14237                            pw.println("low)");
14238                            break;
14239                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14240                            pw.println("critical)");
14241                            break;
14242                        default:
14243                            pw.print(mLastMemoryLevel);
14244                            pw.println(")");
14245                            break;
14246                    }
14247                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14248                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14249                            pw.print(cachedPss); pw.print(" cached pss + ");
14250                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14251                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14252                } else {
14253                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14254                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14255                            + memInfo.getFreeSizeKb()); pw.print(",");
14256                    pw.println(totalPss - cachedPss);
14257                }
14258            }
14259            if (!isCompact) {
14260                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14261                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14262                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14263                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14264                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14265                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14266                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14267            }
14268            if (!brief) {
14269                if (memInfo.getZramTotalSizeKb() != 0) {
14270                    if (!isCompact) {
14271                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14272                                pw.print(" kB physical used for ");
14273                                pw.print(memInfo.getSwapTotalSizeKb()
14274                                        - memInfo.getSwapFreeSizeKb());
14275                                pw.print(" kB in swap (");
14276                                pw.print(memInfo.getSwapTotalSizeKb());
14277                                pw.println(" kB total swap)");
14278                    } else {
14279                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14280                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14281                                pw.println(memInfo.getSwapFreeSizeKb());
14282                    }
14283                }
14284                final long[] ksm = getKsmInfo();
14285                if (!isCompact) {
14286                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14287                            || ksm[KSM_VOLATILE] != 0) {
14288                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14289                                pw.print(" kB saved from shared ");
14290                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14291                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14292                                pw.print(" kB unshared; ");
14293                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14294                    }
14295                    pw.print("   Tuning: ");
14296                    pw.print(ActivityManager.staticGetMemoryClass());
14297                    pw.print(" (large ");
14298                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14299                    pw.print("), oom ");
14300                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14301                    pw.print(" kB");
14302                    pw.print(", restore limit ");
14303                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14304                    pw.print(" kB");
14305                    if (ActivityManager.isLowRamDeviceStatic()) {
14306                        pw.print(" (low-ram)");
14307                    }
14308                    if (ActivityManager.isHighEndGfx()) {
14309                        pw.print(" (high-end-gfx)");
14310                    }
14311                    pw.println();
14312                } else {
14313                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14314                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14315                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14316                    pw.print("tuning,");
14317                    pw.print(ActivityManager.staticGetMemoryClass());
14318                    pw.print(',');
14319                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14320                    pw.print(',');
14321                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14322                    if (ActivityManager.isLowRamDeviceStatic()) {
14323                        pw.print(",low-ram");
14324                    }
14325                    if (ActivityManager.isHighEndGfx()) {
14326                        pw.print(",high-end-gfx");
14327                    }
14328                    pw.println();
14329                }
14330            }
14331        }
14332    }
14333
14334    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14335            String name) {
14336        sb.append("  ");
14337        sb.append(ProcessList.makeOomAdjString(oomAdj));
14338        sb.append(' ');
14339        sb.append(ProcessList.makeProcStateString(procState));
14340        sb.append(' ');
14341        ProcessList.appendRamKb(sb, pss);
14342        sb.append(" kB: ");
14343        sb.append(name);
14344    }
14345
14346    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14347        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14348        sb.append(" (");
14349        sb.append(mi.pid);
14350        sb.append(") ");
14351        sb.append(mi.adjType);
14352        sb.append('\n');
14353        if (mi.adjReason != null) {
14354            sb.append("                      ");
14355            sb.append(mi.adjReason);
14356            sb.append('\n');
14357        }
14358    }
14359
14360    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14361        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14362        for (int i=0, N=memInfos.size(); i<N; i++) {
14363            ProcessMemInfo mi = memInfos.get(i);
14364            infoMap.put(mi.pid, mi);
14365        }
14366        updateCpuStatsNow();
14367        synchronized (mProcessCpuTracker) {
14368            final int N = mProcessCpuTracker.countStats();
14369            for (int i=0; i<N; i++) {
14370                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14371                if (st.vsize > 0) {
14372                    long pss = Debug.getPss(st.pid, null);
14373                    if (pss > 0) {
14374                        if (infoMap.indexOfKey(st.pid) < 0) {
14375                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14376                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14377                            mi.pss = pss;
14378                            memInfos.add(mi);
14379                        }
14380                    }
14381                }
14382            }
14383        }
14384
14385        long totalPss = 0;
14386        for (int i=0, N=memInfos.size(); i<N; i++) {
14387            ProcessMemInfo mi = memInfos.get(i);
14388            if (mi.pss == 0) {
14389                mi.pss = Debug.getPss(mi.pid, null);
14390            }
14391            totalPss += mi.pss;
14392        }
14393        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14394            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14395                if (lhs.oomAdj != rhs.oomAdj) {
14396                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14397                }
14398                if (lhs.pss != rhs.pss) {
14399                    return lhs.pss < rhs.pss ? 1 : -1;
14400                }
14401                return 0;
14402            }
14403        });
14404
14405        StringBuilder tag = new StringBuilder(128);
14406        StringBuilder stack = new StringBuilder(128);
14407        tag.append("Low on memory -- ");
14408        appendMemBucket(tag, totalPss, "total", false);
14409        appendMemBucket(stack, totalPss, "total", true);
14410
14411        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14412        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14413        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14414
14415        boolean firstLine = true;
14416        int lastOomAdj = Integer.MIN_VALUE;
14417        long extraNativeRam = 0;
14418        long cachedPss = 0;
14419        for (int i=0, N=memInfos.size(); i<N; i++) {
14420            ProcessMemInfo mi = memInfos.get(i);
14421
14422            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14423                cachedPss += mi.pss;
14424            }
14425
14426            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14427                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14428                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14429                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14430                if (lastOomAdj != mi.oomAdj) {
14431                    lastOomAdj = mi.oomAdj;
14432                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14433                        tag.append(" / ");
14434                    }
14435                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14436                        if (firstLine) {
14437                            stack.append(":");
14438                            firstLine = false;
14439                        }
14440                        stack.append("\n\t at ");
14441                    } else {
14442                        stack.append("$");
14443                    }
14444                } else {
14445                    tag.append(" ");
14446                    stack.append("$");
14447                }
14448                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14449                    appendMemBucket(tag, mi.pss, mi.name, false);
14450                }
14451                appendMemBucket(stack, mi.pss, mi.name, true);
14452                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14453                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14454                    stack.append("(");
14455                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14456                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14457                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14458                            stack.append(":");
14459                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14460                        }
14461                    }
14462                    stack.append(")");
14463                }
14464            }
14465
14466            appendMemInfo(fullNativeBuilder, mi);
14467            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14468                // The short form only has native processes that are >= 1MB.
14469                if (mi.pss >= 1000) {
14470                    appendMemInfo(shortNativeBuilder, mi);
14471                } else {
14472                    extraNativeRam += mi.pss;
14473                }
14474            } else {
14475                // Short form has all other details, but if we have collected RAM
14476                // from smaller native processes let's dump a summary of that.
14477                if (extraNativeRam > 0) {
14478                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14479                            -1, extraNativeRam, "(Other native)");
14480                    shortNativeBuilder.append('\n');
14481                    extraNativeRam = 0;
14482                }
14483                appendMemInfo(fullJavaBuilder, mi);
14484            }
14485        }
14486
14487        fullJavaBuilder.append("           ");
14488        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14489        fullJavaBuilder.append(" kB: TOTAL\n");
14490
14491        MemInfoReader memInfo = new MemInfoReader();
14492        memInfo.readMemInfo();
14493        final long[] infos = memInfo.getRawInfo();
14494
14495        StringBuilder memInfoBuilder = new StringBuilder(1024);
14496        Debug.getMemInfo(infos);
14497        memInfoBuilder.append("  MemInfo: ");
14498        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14499        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14500        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14501        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14502        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14503        memInfoBuilder.append("           ");
14504        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14505        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14506        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14507        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14508        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14509            memInfoBuilder.append("  ZRAM: ");
14510            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14511            memInfoBuilder.append(" kB RAM, ");
14512            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14513            memInfoBuilder.append(" kB swap total, ");
14514            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14515            memInfoBuilder.append(" kB swap free\n");
14516        }
14517        final long[] ksm = getKsmInfo();
14518        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14519                || ksm[KSM_VOLATILE] != 0) {
14520            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14521            memInfoBuilder.append(" kB saved from shared ");
14522            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14523            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14524            memInfoBuilder.append(" kB unshared; ");
14525            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14526        }
14527        memInfoBuilder.append("  Free RAM: ");
14528        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14529                + memInfo.getFreeSizeKb());
14530        memInfoBuilder.append(" kB\n");
14531        memInfoBuilder.append("  Used RAM: ");
14532        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14533        memInfoBuilder.append(" kB\n");
14534        memInfoBuilder.append("  Lost RAM: ");
14535        memInfoBuilder.append(memInfo.getTotalSizeKb()
14536                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14537                - memInfo.getKernelUsedSizeKb());
14538        memInfoBuilder.append(" kB\n");
14539        Slog.i(TAG, "Low on memory:");
14540        Slog.i(TAG, shortNativeBuilder.toString());
14541        Slog.i(TAG, fullJavaBuilder.toString());
14542        Slog.i(TAG, memInfoBuilder.toString());
14543
14544        StringBuilder dropBuilder = new StringBuilder(1024);
14545        /*
14546        StringWriter oomSw = new StringWriter();
14547        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14548        StringWriter catSw = new StringWriter();
14549        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14550        String[] emptyArgs = new String[] { };
14551        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14552        oomPw.flush();
14553        String oomString = oomSw.toString();
14554        */
14555        dropBuilder.append("Low on memory:");
14556        dropBuilder.append(stack);
14557        dropBuilder.append('\n');
14558        dropBuilder.append(fullNativeBuilder);
14559        dropBuilder.append(fullJavaBuilder);
14560        dropBuilder.append('\n');
14561        dropBuilder.append(memInfoBuilder);
14562        dropBuilder.append('\n');
14563        /*
14564        dropBuilder.append(oomString);
14565        dropBuilder.append('\n');
14566        */
14567        StringWriter catSw = new StringWriter();
14568        synchronized (ActivityManagerService.this) {
14569            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14570            String[] emptyArgs = new String[] { };
14571            catPw.println();
14572            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14573            catPw.println();
14574            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14575                    false, false, null);
14576            catPw.println();
14577            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14578            catPw.flush();
14579        }
14580        dropBuilder.append(catSw.toString());
14581        addErrorToDropBox("lowmem", null, "system_server", null,
14582                null, tag.toString(), dropBuilder.toString(), null, null);
14583        //Slog.i(TAG, "Sent to dropbox:");
14584        //Slog.i(TAG, dropBuilder.toString());
14585        synchronized (ActivityManagerService.this) {
14586            long now = SystemClock.uptimeMillis();
14587            if (mLastMemUsageReportTime < now) {
14588                mLastMemUsageReportTime = now;
14589            }
14590        }
14591    }
14592
14593    /**
14594     * Searches array of arguments for the specified string
14595     * @param args array of argument strings
14596     * @param value value to search for
14597     * @return true if the value is contained in the array
14598     */
14599    private static boolean scanArgs(String[] args, String value) {
14600        if (args != null) {
14601            for (String arg : args) {
14602                if (value.equals(arg)) {
14603                    return true;
14604                }
14605            }
14606        }
14607        return false;
14608    }
14609
14610    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14611            ContentProviderRecord cpr, boolean always) {
14612        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14613
14614        if (!inLaunching || always) {
14615            synchronized (cpr) {
14616                cpr.launchingApp = null;
14617                cpr.notifyAll();
14618            }
14619            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14620            String names[] = cpr.info.authority.split(";");
14621            for (int j = 0; j < names.length; j++) {
14622                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14623            }
14624        }
14625
14626        for (int i=0; i<cpr.connections.size(); i++) {
14627            ContentProviderConnection conn = cpr.connections.get(i);
14628            if (conn.waiting) {
14629                // If this connection is waiting for the provider, then we don't
14630                // need to mess with its process unless we are always removing
14631                // or for some reason the provider is not currently launching.
14632                if (inLaunching && !always) {
14633                    continue;
14634                }
14635            }
14636            ProcessRecord capp = conn.client;
14637            conn.dead = true;
14638            if (conn.stableCount > 0) {
14639                if (!capp.persistent && capp.thread != null
14640                        && capp.pid != 0
14641                        && capp.pid != MY_PID) {
14642                    capp.kill("depends on provider "
14643                            + cpr.name.flattenToShortString()
14644                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14645                }
14646            } else if (capp.thread != null && conn.provider.provider != null) {
14647                try {
14648                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14649                } catch (RemoteException e) {
14650                }
14651                // In the protocol here, we don't expect the client to correctly
14652                // clean up this connection, we'll just remove it.
14653                cpr.connections.remove(i);
14654                conn.client.conProviders.remove(conn);
14655            }
14656        }
14657
14658        if (inLaunching && always) {
14659            mLaunchingProviders.remove(cpr);
14660        }
14661        return inLaunching;
14662    }
14663
14664    /**
14665     * Main code for cleaning up a process when it has gone away.  This is
14666     * called both as a result of the process dying, or directly when stopping
14667     * a process when running in single process mode.
14668     *
14669     * @return Returns true if the given process has been restarted, so the
14670     * app that was passed in must remain on the process lists.
14671     */
14672    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14673            boolean restarting, boolean allowRestart, int index) {
14674        if (index >= 0) {
14675            removeLruProcessLocked(app);
14676            ProcessList.remove(app.pid);
14677        }
14678
14679        mProcessesToGc.remove(app);
14680        mPendingPssProcesses.remove(app);
14681
14682        // Dismiss any open dialogs.
14683        if (app.crashDialog != null && !app.forceCrashReport) {
14684            app.crashDialog.dismiss();
14685            app.crashDialog = null;
14686        }
14687        if (app.anrDialog != null) {
14688            app.anrDialog.dismiss();
14689            app.anrDialog = null;
14690        }
14691        if (app.waitDialog != null) {
14692            app.waitDialog.dismiss();
14693            app.waitDialog = null;
14694        }
14695
14696        app.crashing = false;
14697        app.notResponding = false;
14698
14699        app.resetPackageList(mProcessStats);
14700        app.unlinkDeathRecipient();
14701        app.makeInactive(mProcessStats);
14702        app.waitingToKill = null;
14703        app.forcingToForeground = null;
14704        updateProcessForegroundLocked(app, false, false);
14705        app.foregroundActivities = false;
14706        app.hasShownUi = false;
14707        app.treatLikeActivity = false;
14708        app.hasAboveClient = false;
14709        app.hasClientActivities = false;
14710
14711        mServices.killServicesLocked(app, allowRestart);
14712
14713        boolean restart = false;
14714
14715        // Remove published content providers.
14716        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14717            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14718            final boolean always = app.bad || !allowRestart;
14719            if (removeDyingProviderLocked(app, cpr, always) || always) {
14720                // We left the provider in the launching list, need to
14721                // restart it.
14722                restart = true;
14723            }
14724
14725            cpr.provider = null;
14726            cpr.proc = null;
14727        }
14728        app.pubProviders.clear();
14729
14730        // Take care of any launching providers waiting for this process.
14731        if (checkAppInLaunchingProvidersLocked(app, false)) {
14732            restart = true;
14733        }
14734
14735        // Unregister from connected content providers.
14736        if (!app.conProviders.isEmpty()) {
14737            for (int i=0; i<app.conProviders.size(); i++) {
14738                ContentProviderConnection conn = app.conProviders.get(i);
14739                conn.provider.connections.remove(conn);
14740            }
14741            app.conProviders.clear();
14742        }
14743
14744        // At this point there may be remaining entries in mLaunchingProviders
14745        // where we were the only one waiting, so they are no longer of use.
14746        // Look for these and clean up if found.
14747        // XXX Commented out for now.  Trying to figure out a way to reproduce
14748        // the actual situation to identify what is actually going on.
14749        if (false) {
14750            for (int i=0; i<mLaunchingProviders.size(); i++) {
14751                ContentProviderRecord cpr = (ContentProviderRecord)
14752                        mLaunchingProviders.get(i);
14753                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14754                    synchronized (cpr) {
14755                        cpr.launchingApp = null;
14756                        cpr.notifyAll();
14757                    }
14758                }
14759            }
14760        }
14761
14762        skipCurrentReceiverLocked(app);
14763
14764        // Unregister any receivers.
14765        for (int i=app.receivers.size()-1; i>=0; i--) {
14766            removeReceiverLocked(app.receivers.valueAt(i));
14767        }
14768        app.receivers.clear();
14769
14770        // If the app is undergoing backup, tell the backup manager about it
14771        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14772            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14773                    + mBackupTarget.appInfo + " died during backup");
14774            try {
14775                IBackupManager bm = IBackupManager.Stub.asInterface(
14776                        ServiceManager.getService(Context.BACKUP_SERVICE));
14777                bm.agentDisconnected(app.info.packageName);
14778            } catch (RemoteException e) {
14779                // can't happen; backup manager is local
14780            }
14781        }
14782
14783        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14784            ProcessChangeItem item = mPendingProcessChanges.get(i);
14785            if (item.pid == app.pid) {
14786                mPendingProcessChanges.remove(i);
14787                mAvailProcessChanges.add(item);
14788            }
14789        }
14790        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14791
14792        // If the caller is restarting this app, then leave it in its
14793        // current lists and let the caller take care of it.
14794        if (restarting) {
14795            return false;
14796        }
14797
14798        if (!app.persistent || app.isolated) {
14799            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14800                    "Removing non-persistent process during cleanup: " + app);
14801            mProcessNames.remove(app.processName, app.uid);
14802            mIsolatedProcesses.remove(app.uid);
14803            if (mHeavyWeightProcess == app) {
14804                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14805                        mHeavyWeightProcess.userId, 0));
14806                mHeavyWeightProcess = null;
14807            }
14808        } else if (!app.removed) {
14809            // This app is persistent, so we need to keep its record around.
14810            // If it is not already on the pending app list, add it there
14811            // and start a new process for it.
14812            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14813                mPersistentStartingProcesses.add(app);
14814                restart = true;
14815            }
14816        }
14817        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14818                "Clean-up removing on hold: " + app);
14819        mProcessesOnHold.remove(app);
14820
14821        if (app == mHomeProcess) {
14822            mHomeProcess = null;
14823        }
14824        if (app == mPreviousProcess) {
14825            mPreviousProcess = null;
14826        }
14827
14828        if (restart && !app.isolated) {
14829            // We have components that still need to be running in the
14830            // process, so re-launch it.
14831            if (index < 0) {
14832                ProcessList.remove(app.pid);
14833            }
14834            mProcessNames.put(app.processName, app.uid, app);
14835            startProcessLocked(app, "restart", app.processName);
14836            return true;
14837        } else if (app.pid > 0 && app.pid != MY_PID) {
14838            // Goodbye!
14839            boolean removed;
14840            synchronized (mPidsSelfLocked) {
14841                mPidsSelfLocked.remove(app.pid);
14842                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14843            }
14844            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14845            if (app.isolated) {
14846                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14847            }
14848            app.setPid(0);
14849        }
14850        return false;
14851    }
14852
14853    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14854        // Look through the content providers we are waiting to have launched,
14855        // and if any run in this process then either schedule a restart of
14856        // the process or kill the client waiting for it if this process has
14857        // gone bad.
14858        int NL = mLaunchingProviders.size();
14859        boolean restart = false;
14860        for (int i=0; i<NL; i++) {
14861            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14862            if (cpr.launchingApp == app) {
14863                if (!alwaysBad && !app.bad) {
14864                    restart = true;
14865                } else {
14866                    removeDyingProviderLocked(app, cpr, true);
14867                    // cpr should have been removed from mLaunchingProviders
14868                    NL = mLaunchingProviders.size();
14869                    i--;
14870                }
14871            }
14872        }
14873        return restart;
14874    }
14875
14876    // =========================================================
14877    // SERVICES
14878    // =========================================================
14879
14880    @Override
14881    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14882            int flags) {
14883        enforceNotIsolatedCaller("getServices");
14884        synchronized (this) {
14885            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14886        }
14887    }
14888
14889    @Override
14890    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14891        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14892        synchronized (this) {
14893            return mServices.getRunningServiceControlPanelLocked(name);
14894        }
14895    }
14896
14897    @Override
14898    public ComponentName startService(IApplicationThread caller, Intent service,
14899            String resolvedType, int userId) {
14900        enforceNotIsolatedCaller("startService");
14901        // Refuse possible leaked file descriptors
14902        if (service != null && service.hasFileDescriptors() == true) {
14903            throw new IllegalArgumentException("File descriptors passed in Intent");
14904        }
14905
14906        if (DEBUG_SERVICE)
14907            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14908        synchronized(this) {
14909            final int callingPid = Binder.getCallingPid();
14910            final int callingUid = Binder.getCallingUid();
14911            final long origId = Binder.clearCallingIdentity();
14912            ComponentName res = mServices.startServiceLocked(caller, service,
14913                    resolvedType, callingPid, callingUid, userId);
14914            Binder.restoreCallingIdentity(origId);
14915            return res;
14916        }
14917    }
14918
14919    ComponentName startServiceInPackage(int uid,
14920            Intent service, String resolvedType, int userId) {
14921        synchronized(this) {
14922            if (DEBUG_SERVICE)
14923                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14924            final long origId = Binder.clearCallingIdentity();
14925            ComponentName res = mServices.startServiceLocked(null, service,
14926                    resolvedType, -1, uid, userId);
14927            Binder.restoreCallingIdentity(origId);
14928            return res;
14929        }
14930    }
14931
14932    @Override
14933    public int stopService(IApplicationThread caller, Intent service,
14934            String resolvedType, int userId) {
14935        enforceNotIsolatedCaller("stopService");
14936        // Refuse possible leaked file descriptors
14937        if (service != null && service.hasFileDescriptors() == true) {
14938            throw new IllegalArgumentException("File descriptors passed in Intent");
14939        }
14940
14941        synchronized(this) {
14942            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14943        }
14944    }
14945
14946    @Override
14947    public IBinder peekService(Intent service, String resolvedType) {
14948        enforceNotIsolatedCaller("peekService");
14949        // Refuse possible leaked file descriptors
14950        if (service != null && service.hasFileDescriptors() == true) {
14951            throw new IllegalArgumentException("File descriptors passed in Intent");
14952        }
14953        synchronized(this) {
14954            return mServices.peekServiceLocked(service, resolvedType);
14955        }
14956    }
14957
14958    @Override
14959    public boolean stopServiceToken(ComponentName className, IBinder token,
14960            int startId) {
14961        synchronized(this) {
14962            return mServices.stopServiceTokenLocked(className, token, startId);
14963        }
14964    }
14965
14966    @Override
14967    public void setServiceForeground(ComponentName className, IBinder token,
14968            int id, Notification notification, boolean removeNotification) {
14969        synchronized(this) {
14970            mServices.setServiceForegroundLocked(className, token, id, notification,
14971                    removeNotification);
14972        }
14973    }
14974
14975    @Override
14976    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14977            boolean requireFull, String name, String callerPackage) {
14978        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14979                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14980    }
14981
14982    int unsafeConvertIncomingUser(int userId) {
14983        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14984                ? mCurrentUserId : userId;
14985    }
14986
14987    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14988            int allowMode, String name, String callerPackage) {
14989        final int callingUserId = UserHandle.getUserId(callingUid);
14990        if (callingUserId == userId) {
14991            return userId;
14992        }
14993
14994        // Note that we may be accessing mCurrentUserId outside of a lock...
14995        // shouldn't be a big deal, if this is being called outside
14996        // of a locked context there is intrinsically a race with
14997        // the value the caller will receive and someone else changing it.
14998        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14999        // we will switch to the calling user if access to the current user fails.
15000        int targetUserId = unsafeConvertIncomingUser(userId);
15001
15002        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15003            final boolean allow;
15004            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15005                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15006                // If the caller has this permission, they always pass go.  And collect $200.
15007                allow = true;
15008            } else if (allowMode == ALLOW_FULL_ONLY) {
15009                // We require full access, sucks to be you.
15010                allow = false;
15011            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15012                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15013                // If the caller does not have either permission, they are always doomed.
15014                allow = false;
15015            } else if (allowMode == ALLOW_NON_FULL) {
15016                // We are blanket allowing non-full access, you lucky caller!
15017                allow = true;
15018            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15019                // We may or may not allow this depending on whether the two users are
15020                // in the same profile.
15021                synchronized (mUserProfileGroupIdsSelfLocked) {
15022                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15023                            UserInfo.NO_PROFILE_GROUP_ID);
15024                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15025                            UserInfo.NO_PROFILE_GROUP_ID);
15026                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15027                            && callingProfile == targetProfile;
15028                }
15029            } else {
15030                throw new IllegalArgumentException("Unknown mode: " + allowMode);
15031            }
15032            if (!allow) {
15033                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15034                    // In this case, they would like to just execute as their
15035                    // owner user instead of failing.
15036                    targetUserId = callingUserId;
15037                } else {
15038                    StringBuilder builder = new StringBuilder(128);
15039                    builder.append("Permission Denial: ");
15040                    builder.append(name);
15041                    if (callerPackage != null) {
15042                        builder.append(" from ");
15043                        builder.append(callerPackage);
15044                    }
15045                    builder.append(" asks to run as user ");
15046                    builder.append(userId);
15047                    builder.append(" but is calling from user ");
15048                    builder.append(UserHandle.getUserId(callingUid));
15049                    builder.append("; this requires ");
15050                    builder.append(INTERACT_ACROSS_USERS_FULL);
15051                    if (allowMode != ALLOW_FULL_ONLY) {
15052                        builder.append(" or ");
15053                        builder.append(INTERACT_ACROSS_USERS);
15054                    }
15055                    String msg = builder.toString();
15056                    Slog.w(TAG, msg);
15057                    throw new SecurityException(msg);
15058                }
15059            }
15060        }
15061        if (!allowAll && targetUserId < 0) {
15062            throw new IllegalArgumentException(
15063                    "Call does not support special user #" + targetUserId);
15064        }
15065        // Check shell permission
15066        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15067            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15068                    targetUserId)) {
15069                throw new SecurityException("Shell does not have permission to access user "
15070                        + targetUserId + "\n " + Debug.getCallers(3));
15071            }
15072        }
15073        return targetUserId;
15074    }
15075
15076    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15077            String className, int flags) {
15078        boolean result = false;
15079        // For apps that don't have pre-defined UIDs, check for permission
15080        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15081            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15082                if (ActivityManager.checkUidPermission(
15083                        INTERACT_ACROSS_USERS,
15084                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15085                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15086                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15087                            + " requests FLAG_SINGLE_USER, but app does not hold "
15088                            + INTERACT_ACROSS_USERS;
15089                    Slog.w(TAG, msg);
15090                    throw new SecurityException(msg);
15091                }
15092                // Permission passed
15093                result = true;
15094            }
15095        } else if ("system".equals(componentProcessName)) {
15096            result = true;
15097        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15098            // Phone app and persistent apps are allowed to export singleuser providers.
15099            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15100                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15101        }
15102        if (DEBUG_MU) {
15103            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15104                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15105        }
15106        return result;
15107    }
15108
15109    /**
15110     * Checks to see if the caller is in the same app as the singleton
15111     * component, or the component is in a special app. It allows special apps
15112     * to export singleton components but prevents exporting singleton
15113     * components for regular apps.
15114     */
15115    boolean isValidSingletonCall(int callingUid, int componentUid) {
15116        int componentAppId = UserHandle.getAppId(componentUid);
15117        return UserHandle.isSameApp(callingUid, componentUid)
15118                || componentAppId == Process.SYSTEM_UID
15119                || componentAppId == Process.PHONE_UID
15120                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15121                        == PackageManager.PERMISSION_GRANTED;
15122    }
15123
15124    public int bindService(IApplicationThread caller, IBinder token,
15125            Intent service, String resolvedType,
15126            IServiceConnection connection, int flags, int userId) {
15127        enforceNotIsolatedCaller("bindService");
15128
15129        // Refuse possible leaked file descriptors
15130        if (service != null && service.hasFileDescriptors() == true) {
15131            throw new IllegalArgumentException("File descriptors passed in Intent");
15132        }
15133
15134        synchronized(this) {
15135            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15136                    connection, flags, userId);
15137        }
15138    }
15139
15140    public boolean unbindService(IServiceConnection connection) {
15141        synchronized (this) {
15142            return mServices.unbindServiceLocked(connection);
15143        }
15144    }
15145
15146    public void publishService(IBinder token, Intent intent, IBinder service) {
15147        // Refuse possible leaked file descriptors
15148        if (intent != null && intent.hasFileDescriptors() == true) {
15149            throw new IllegalArgumentException("File descriptors passed in Intent");
15150        }
15151
15152        synchronized(this) {
15153            if (!(token instanceof ServiceRecord)) {
15154                throw new IllegalArgumentException("Invalid service token");
15155            }
15156            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15157        }
15158    }
15159
15160    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15161        // Refuse possible leaked file descriptors
15162        if (intent != null && intent.hasFileDescriptors() == true) {
15163            throw new IllegalArgumentException("File descriptors passed in Intent");
15164        }
15165
15166        synchronized(this) {
15167            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15168        }
15169    }
15170
15171    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15172        synchronized(this) {
15173            if (!(token instanceof ServiceRecord)) {
15174                throw new IllegalArgumentException("Invalid service token");
15175            }
15176            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15177        }
15178    }
15179
15180    // =========================================================
15181    // BACKUP AND RESTORE
15182    // =========================================================
15183
15184    // Cause the target app to be launched if necessary and its backup agent
15185    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15186    // activity manager to announce its creation.
15187    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15188        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15189        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15190
15191        synchronized(this) {
15192            // !!! TODO: currently no check here that we're already bound
15193            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15194            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15195            synchronized (stats) {
15196                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15197            }
15198
15199            // Backup agent is now in use, its package can't be stopped.
15200            try {
15201                AppGlobals.getPackageManager().setPackageStoppedState(
15202                        app.packageName, false, UserHandle.getUserId(app.uid));
15203            } catch (RemoteException e) {
15204            } catch (IllegalArgumentException e) {
15205                Slog.w(TAG, "Failed trying to unstop package "
15206                        + app.packageName + ": " + e);
15207            }
15208
15209            BackupRecord r = new BackupRecord(ss, app, backupMode);
15210            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15211                    ? new ComponentName(app.packageName, app.backupAgentName)
15212                    : new ComponentName("android", "FullBackupAgent");
15213            // startProcessLocked() returns existing proc's record if it's already running
15214            ProcessRecord proc = startProcessLocked(app.processName, app,
15215                    false, 0, "backup", hostingName, false, false, false);
15216            if (proc == null) {
15217                Slog.e(TAG, "Unable to start backup agent process " + r);
15218                return false;
15219            }
15220
15221            r.app = proc;
15222            mBackupTarget = r;
15223            mBackupAppName = app.packageName;
15224
15225            // Try not to kill the process during backup
15226            updateOomAdjLocked(proc);
15227
15228            // If the process is already attached, schedule the creation of the backup agent now.
15229            // If it is not yet live, this will be done when it attaches to the framework.
15230            if (proc.thread != null) {
15231                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15232                try {
15233                    proc.thread.scheduleCreateBackupAgent(app,
15234                            compatibilityInfoForPackageLocked(app), backupMode);
15235                } catch (RemoteException e) {
15236                    // Will time out on the backup manager side
15237                }
15238            } else {
15239                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15240            }
15241            // Invariants: at this point, the target app process exists and the application
15242            // is either already running or in the process of coming up.  mBackupTarget and
15243            // mBackupAppName describe the app, so that when it binds back to the AM we
15244            // know that it's scheduled for a backup-agent operation.
15245        }
15246
15247        return true;
15248    }
15249
15250    @Override
15251    public void clearPendingBackup() {
15252        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15253        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15254
15255        synchronized (this) {
15256            mBackupTarget = null;
15257            mBackupAppName = null;
15258        }
15259    }
15260
15261    // A backup agent has just come up
15262    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15263        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15264                + " = " + agent);
15265
15266        synchronized(this) {
15267            if (!agentPackageName.equals(mBackupAppName)) {
15268                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15269                return;
15270            }
15271        }
15272
15273        long oldIdent = Binder.clearCallingIdentity();
15274        try {
15275            IBackupManager bm = IBackupManager.Stub.asInterface(
15276                    ServiceManager.getService(Context.BACKUP_SERVICE));
15277            bm.agentConnected(agentPackageName, agent);
15278        } catch (RemoteException e) {
15279            // can't happen; the backup manager service is local
15280        } catch (Exception e) {
15281            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15282            e.printStackTrace();
15283        } finally {
15284            Binder.restoreCallingIdentity(oldIdent);
15285        }
15286    }
15287
15288    // done with this agent
15289    public void unbindBackupAgent(ApplicationInfo appInfo) {
15290        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15291        if (appInfo == null) {
15292            Slog.w(TAG, "unbind backup agent for null app");
15293            return;
15294        }
15295
15296        synchronized(this) {
15297            try {
15298                if (mBackupAppName == null) {
15299                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15300                    return;
15301                }
15302
15303                if (!mBackupAppName.equals(appInfo.packageName)) {
15304                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15305                    return;
15306                }
15307
15308                // Not backing this app up any more; reset its OOM adjustment
15309                final ProcessRecord proc = mBackupTarget.app;
15310                updateOomAdjLocked(proc);
15311
15312                // If the app crashed during backup, 'thread' will be null here
15313                if (proc.thread != null) {
15314                    try {
15315                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15316                                compatibilityInfoForPackageLocked(appInfo));
15317                    } catch (Exception e) {
15318                        Slog.e(TAG, "Exception when unbinding backup agent:");
15319                        e.printStackTrace();
15320                    }
15321                }
15322            } finally {
15323                mBackupTarget = null;
15324                mBackupAppName = null;
15325            }
15326        }
15327    }
15328    // =========================================================
15329    // BROADCASTS
15330    // =========================================================
15331
15332    private final List getStickiesLocked(String action, IntentFilter filter,
15333            List cur, int userId) {
15334        final ContentResolver resolver = mContext.getContentResolver();
15335        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15336        if (stickies == null) {
15337            return cur;
15338        }
15339        final ArrayList<Intent> list = stickies.get(action);
15340        if (list == null) {
15341            return cur;
15342        }
15343        int N = list.size();
15344        for (int i=0; i<N; i++) {
15345            Intent intent = list.get(i);
15346            if (filter.match(resolver, intent, true, TAG) >= 0) {
15347                if (cur == null) {
15348                    cur = new ArrayList<Intent>();
15349                }
15350                cur.add(intent);
15351            }
15352        }
15353        return cur;
15354    }
15355
15356    boolean isPendingBroadcastProcessLocked(int pid) {
15357        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15358                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15359    }
15360
15361    void skipPendingBroadcastLocked(int pid) {
15362            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15363            for (BroadcastQueue queue : mBroadcastQueues) {
15364                queue.skipPendingBroadcastLocked(pid);
15365            }
15366    }
15367
15368    // The app just attached; send any pending broadcasts that it should receive
15369    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15370        boolean didSomething = false;
15371        for (BroadcastQueue queue : mBroadcastQueues) {
15372            didSomething |= queue.sendPendingBroadcastsLocked(app);
15373        }
15374        return didSomething;
15375    }
15376
15377    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15378            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15379        enforceNotIsolatedCaller("registerReceiver");
15380        int callingUid;
15381        int callingPid;
15382        synchronized(this) {
15383            ProcessRecord callerApp = null;
15384            if (caller != null) {
15385                callerApp = getRecordForAppLocked(caller);
15386                if (callerApp == null) {
15387                    throw new SecurityException(
15388                            "Unable to find app for caller " + caller
15389                            + " (pid=" + Binder.getCallingPid()
15390                            + ") when registering receiver " + receiver);
15391                }
15392                if (callerApp.info.uid != Process.SYSTEM_UID &&
15393                        !callerApp.pkgList.containsKey(callerPackage) &&
15394                        !"android".equals(callerPackage)) {
15395                    throw new SecurityException("Given caller package " + callerPackage
15396                            + " is not running in process " + callerApp);
15397                }
15398                callingUid = callerApp.info.uid;
15399                callingPid = callerApp.pid;
15400            } else {
15401                callerPackage = null;
15402                callingUid = Binder.getCallingUid();
15403                callingPid = Binder.getCallingPid();
15404            }
15405
15406            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15407                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15408
15409            List allSticky = null;
15410
15411            // Look for any matching sticky broadcasts...
15412            Iterator actions = filter.actionsIterator();
15413            if (actions != null) {
15414                while (actions.hasNext()) {
15415                    String action = (String)actions.next();
15416                    allSticky = getStickiesLocked(action, filter, allSticky,
15417                            UserHandle.USER_ALL);
15418                    allSticky = getStickiesLocked(action, filter, allSticky,
15419                            UserHandle.getUserId(callingUid));
15420                }
15421            } else {
15422                allSticky = getStickiesLocked(null, filter, allSticky,
15423                        UserHandle.USER_ALL);
15424                allSticky = getStickiesLocked(null, filter, allSticky,
15425                        UserHandle.getUserId(callingUid));
15426            }
15427
15428            // The first sticky in the list is returned directly back to
15429            // the client.
15430            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15431
15432            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15433                    + ": " + sticky);
15434
15435            if (receiver == null) {
15436                return sticky;
15437            }
15438
15439            ReceiverList rl
15440                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15441            if (rl == null) {
15442                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15443                        userId, receiver);
15444                if (rl.app != null) {
15445                    rl.app.receivers.add(rl);
15446                } else {
15447                    try {
15448                        receiver.asBinder().linkToDeath(rl, 0);
15449                    } catch (RemoteException e) {
15450                        return sticky;
15451                    }
15452                    rl.linkedToDeath = true;
15453                }
15454                mRegisteredReceivers.put(receiver.asBinder(), rl);
15455            } else if (rl.uid != callingUid) {
15456                throw new IllegalArgumentException(
15457                        "Receiver requested to register for uid " + callingUid
15458                        + " was previously registered for uid " + rl.uid);
15459            } else if (rl.pid != callingPid) {
15460                throw new IllegalArgumentException(
15461                        "Receiver requested to register for pid " + callingPid
15462                        + " was previously registered for pid " + rl.pid);
15463            } else if (rl.userId != userId) {
15464                throw new IllegalArgumentException(
15465                        "Receiver requested to register for user " + userId
15466                        + " was previously registered for user " + rl.userId);
15467            }
15468            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15469                    permission, callingUid, userId);
15470            rl.add(bf);
15471            if (!bf.debugCheck()) {
15472                Slog.w(TAG, "==> For Dynamic broadast");
15473            }
15474            mReceiverResolver.addFilter(bf);
15475
15476            // Enqueue broadcasts for all existing stickies that match
15477            // this filter.
15478            if (allSticky != null) {
15479                ArrayList receivers = new ArrayList();
15480                receivers.add(bf);
15481
15482                int N = allSticky.size();
15483                for (int i=0; i<N; i++) {
15484                    Intent intent = (Intent)allSticky.get(i);
15485                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15486                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15487                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15488                            null, null, false, true, true, -1);
15489                    queue.enqueueParallelBroadcastLocked(r);
15490                    queue.scheduleBroadcastsLocked();
15491                }
15492            }
15493
15494            return sticky;
15495        }
15496    }
15497
15498    public void unregisterReceiver(IIntentReceiver receiver) {
15499        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15500
15501        final long origId = Binder.clearCallingIdentity();
15502        try {
15503            boolean doTrim = false;
15504
15505            synchronized(this) {
15506                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15507                if (rl != null) {
15508                    if (rl.curBroadcast != null) {
15509                        BroadcastRecord r = rl.curBroadcast;
15510                        final boolean doNext = finishReceiverLocked(
15511                                receiver.asBinder(), r.resultCode, r.resultData,
15512                                r.resultExtras, r.resultAbort);
15513                        if (doNext) {
15514                            doTrim = true;
15515                            r.queue.processNextBroadcast(false);
15516                        }
15517                    }
15518
15519                    if (rl.app != null) {
15520                        rl.app.receivers.remove(rl);
15521                    }
15522                    removeReceiverLocked(rl);
15523                    if (rl.linkedToDeath) {
15524                        rl.linkedToDeath = false;
15525                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15526                    }
15527                }
15528            }
15529
15530            // If we actually concluded any broadcasts, we might now be able
15531            // to trim the recipients' apps from our working set
15532            if (doTrim) {
15533                trimApplications();
15534                return;
15535            }
15536
15537        } finally {
15538            Binder.restoreCallingIdentity(origId);
15539        }
15540    }
15541
15542    void removeReceiverLocked(ReceiverList rl) {
15543        mRegisteredReceivers.remove(rl.receiver.asBinder());
15544        int N = rl.size();
15545        for (int i=0; i<N; i++) {
15546            mReceiverResolver.removeFilter(rl.get(i));
15547        }
15548    }
15549
15550    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15551        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15552            ProcessRecord r = mLruProcesses.get(i);
15553            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15554                try {
15555                    r.thread.dispatchPackageBroadcast(cmd, packages);
15556                } catch (RemoteException ex) {
15557                }
15558            }
15559        }
15560    }
15561
15562    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15563            int callingUid, int[] users) {
15564        List<ResolveInfo> receivers = null;
15565        try {
15566            HashSet<ComponentName> singleUserReceivers = null;
15567            boolean scannedFirstReceivers = false;
15568            for (int user : users) {
15569                // Skip users that have Shell restrictions
15570                if (callingUid == Process.SHELL_UID
15571                        && getUserManagerLocked().hasUserRestriction(
15572                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15573                    continue;
15574                }
15575                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15576                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15577                if (user != 0 && newReceivers != null) {
15578                    // If this is not the primary user, we need to check for
15579                    // any receivers that should be filtered out.
15580                    for (int i=0; i<newReceivers.size(); i++) {
15581                        ResolveInfo ri = newReceivers.get(i);
15582                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15583                            newReceivers.remove(i);
15584                            i--;
15585                        }
15586                    }
15587                }
15588                if (newReceivers != null && newReceivers.size() == 0) {
15589                    newReceivers = null;
15590                }
15591                if (receivers == null) {
15592                    receivers = newReceivers;
15593                } else if (newReceivers != null) {
15594                    // We need to concatenate the additional receivers
15595                    // found with what we have do far.  This would be easy,
15596                    // but we also need to de-dup any receivers that are
15597                    // singleUser.
15598                    if (!scannedFirstReceivers) {
15599                        // Collect any single user receivers we had already retrieved.
15600                        scannedFirstReceivers = true;
15601                        for (int i=0; i<receivers.size(); i++) {
15602                            ResolveInfo ri = receivers.get(i);
15603                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15604                                ComponentName cn = new ComponentName(
15605                                        ri.activityInfo.packageName, ri.activityInfo.name);
15606                                if (singleUserReceivers == null) {
15607                                    singleUserReceivers = new HashSet<ComponentName>();
15608                                }
15609                                singleUserReceivers.add(cn);
15610                            }
15611                        }
15612                    }
15613                    // Add the new results to the existing results, tracking
15614                    // and de-dupping single user receivers.
15615                    for (int i=0; i<newReceivers.size(); i++) {
15616                        ResolveInfo ri = newReceivers.get(i);
15617                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15618                            ComponentName cn = new ComponentName(
15619                                    ri.activityInfo.packageName, ri.activityInfo.name);
15620                            if (singleUserReceivers == null) {
15621                                singleUserReceivers = new HashSet<ComponentName>();
15622                            }
15623                            if (!singleUserReceivers.contains(cn)) {
15624                                singleUserReceivers.add(cn);
15625                                receivers.add(ri);
15626                            }
15627                        } else {
15628                            receivers.add(ri);
15629                        }
15630                    }
15631                }
15632            }
15633        } catch (RemoteException ex) {
15634            // pm is in same process, this will never happen.
15635        }
15636        return receivers;
15637    }
15638
15639    private final int broadcastIntentLocked(ProcessRecord callerApp,
15640            String callerPackage, Intent intent, String resolvedType,
15641            IIntentReceiver resultTo, int resultCode, String resultData,
15642            Bundle map, String requiredPermission, int appOp,
15643            boolean ordered, boolean sticky, int callingPid, int callingUid,
15644            int userId) {
15645        intent = new Intent(intent);
15646
15647        // By default broadcasts do not go to stopped apps.
15648        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15649
15650        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15651            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15652            + " ordered=" + ordered + " userid=" + userId);
15653        if ((resultTo != null) && !ordered) {
15654            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15655        }
15656
15657        userId = handleIncomingUser(callingPid, callingUid, userId,
15658                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15659
15660        // Make sure that the user who is receiving this broadcast is started.
15661        // If not, we will just skip it.
15662
15663        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15664            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15665                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15666                Slog.w(TAG, "Skipping broadcast of " + intent
15667                        + ": user " + userId + " is stopped");
15668                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15669            }
15670        }
15671
15672        /*
15673         * Prevent non-system code (defined here to be non-persistent
15674         * processes) from sending protected broadcasts.
15675         */
15676        int callingAppId = UserHandle.getAppId(callingUid);
15677        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15678            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15679            || callingAppId == Process.NFC_UID || callingUid == 0) {
15680            // Always okay.
15681        } else if (callerApp == null || !callerApp.persistent) {
15682            try {
15683                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15684                        intent.getAction())) {
15685                    String msg = "Permission Denial: not allowed to send broadcast "
15686                            + intent.getAction() + " from pid="
15687                            + callingPid + ", uid=" + callingUid;
15688                    Slog.w(TAG, msg);
15689                    throw new SecurityException(msg);
15690                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15691                    // Special case for compatibility: we don't want apps to send this,
15692                    // but historically it has not been protected and apps may be using it
15693                    // to poke their own app widget.  So, instead of making it protected,
15694                    // just limit it to the caller.
15695                    if (callerApp == null) {
15696                        String msg = "Permission Denial: not allowed to send broadcast "
15697                                + intent.getAction() + " from unknown caller.";
15698                        Slog.w(TAG, msg);
15699                        throw new SecurityException(msg);
15700                    } else if (intent.getComponent() != null) {
15701                        // They are good enough to send to an explicit component...  verify
15702                        // it is being sent to the calling app.
15703                        if (!intent.getComponent().getPackageName().equals(
15704                                callerApp.info.packageName)) {
15705                            String msg = "Permission Denial: not allowed to send broadcast "
15706                                    + intent.getAction() + " to "
15707                                    + intent.getComponent().getPackageName() + " from "
15708                                    + callerApp.info.packageName;
15709                            Slog.w(TAG, msg);
15710                            throw new SecurityException(msg);
15711                        }
15712                    } else {
15713                        // Limit broadcast to their own package.
15714                        intent.setPackage(callerApp.info.packageName);
15715                    }
15716                }
15717            } catch (RemoteException e) {
15718                Slog.w(TAG, "Remote exception", e);
15719                return ActivityManager.BROADCAST_SUCCESS;
15720            }
15721        }
15722
15723        final String action = intent.getAction();
15724        if (action != null) {
15725            switch (action) {
15726                case Intent.ACTION_UID_REMOVED:
15727                case Intent.ACTION_PACKAGE_REMOVED:
15728                case Intent.ACTION_PACKAGE_CHANGED:
15729                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15730                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15731                    // Handle special intents: if this broadcast is from the package
15732                    // manager about a package being removed, we need to remove all of
15733                    // its activities from the history stack.
15734                    if (checkComponentPermission(
15735                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15736                            callingPid, callingUid, -1, true)
15737                            != PackageManager.PERMISSION_GRANTED) {
15738                        String msg = "Permission Denial: " + intent.getAction()
15739                                + " broadcast from " + callerPackage + " (pid=" + callingPid
15740                                + ", uid=" + callingUid + ")"
15741                                + " requires "
15742                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15743                        Slog.w(TAG, msg);
15744                        throw new SecurityException(msg);
15745                    }
15746                    switch (action) {
15747                        case Intent.ACTION_UID_REMOVED:
15748                            final Bundle intentExtras = intent.getExtras();
15749                            final int uid = intentExtras != null
15750                                    ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15751                            if (uid >= 0) {
15752                                BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15753                                synchronized (bs) {
15754                                    bs.removeUidStatsLocked(uid);
15755                                }
15756                                mAppOpsService.uidRemoved(uid);
15757                            }
15758                            break;
15759                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
15760                            // If resources are unavailable just force stop all those packages
15761                            // and flush the attribute cache as well.
15762                            String list[] =
15763                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15764                            if (list != null && list.length > 0) {
15765                                for (int i = 0; i < list.length; i++) {
15766                                    forceStopPackageLocked(list[i], -1, false, true, true,
15767                                            false, false, userId, "storage unmount");
15768                                }
15769                                cleanupRecentTasksLocked(UserHandle.USER_ALL);
15770                                sendPackageBroadcastLocked(
15771                                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
15772                                        userId);
15773                            }
15774                            break;
15775                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
15776                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15777                            break;
15778                        case Intent.ACTION_PACKAGE_REMOVED:
15779                        case Intent.ACTION_PACKAGE_CHANGED:
15780                            Uri data = intent.getData();
15781                            String ssp;
15782                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15783                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
15784                                boolean fullUninstall = removed &&
15785                                        !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15786                                if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15787                                    forceStopPackageLocked(ssp, UserHandle.getAppId(
15788                                            intent.getIntExtra(Intent.EXTRA_UID, -1)),
15789                                            false, true, true, false, fullUninstall, userId,
15790                                            removed ? "pkg removed" : "pkg changed");
15791                                }
15792                                if (removed) {
15793                                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15794                                            new String[] {ssp}, userId);
15795                                    if (fullUninstall) {
15796                                        mAppOpsService.packageRemoved(
15797                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15798
15799                                        // Remove all permissions granted from/to this package
15800                                        removeUriPermissionsForPackageLocked(ssp, userId, true);
15801
15802                                        removeTasksByPackageNameLocked(ssp, userId);
15803                                    }
15804                                } else {
15805                                    removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15806                                    if (userId == UserHandle.USER_OWNER) {
15807                                        mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15808                                    }
15809                                }
15810                            }
15811                            break;
15812                    }
15813                    break;
15814                case Intent.ACTION_PACKAGE_ADDED:
15815                    // Special case for adding a package: by default turn on compatibility mode.
15816                    Uri data = intent.getData();
15817                    String ssp;
15818                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
15819                        final boolean replacing =
15820                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15821                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
15822
15823                        if (replacing) {
15824                            removeTasksByRemovedPackageComponentsLocked(ssp, userId);
15825                        }
15826                        if (userId == UserHandle.USER_OWNER) {
15827                            mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
15828                        }
15829                    }
15830                    break;
15831                case Intent.ACTION_TIMEZONE_CHANGED:
15832                    // If this is the time zone changed action, queue up a message that will reset
15833                    // the timezone of all currently running processes. This message will get
15834                    // queued up before the broadcast happens.
15835                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15836                    break;
15837                case Intent.ACTION_TIME_CHANGED:
15838                    // If the user set the time, let all running processes know.
15839                    final int is24Hour =
15840                            intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
15841                                    : 0;
15842                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15843                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15844                    synchronized (stats) {
15845                        stats.noteCurrentTimeChangedLocked();
15846                    }
15847                    break;
15848                case Intent.ACTION_CLEAR_DNS_CACHE:
15849                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15850                    break;
15851                case Proxy.PROXY_CHANGE_ACTION:
15852                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15853                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15854                    break;
15855            }
15856        }
15857
15858        // Add to the sticky list if requested.
15859        if (sticky) {
15860            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15861                    callingPid, callingUid)
15862                    != PackageManager.PERMISSION_GRANTED) {
15863                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15864                        + callingPid + ", uid=" + callingUid
15865                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15866                Slog.w(TAG, msg);
15867                throw new SecurityException(msg);
15868            }
15869            if (requiredPermission != null) {
15870                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15871                        + " and enforce permission " + requiredPermission);
15872                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15873            }
15874            if (intent.getComponent() != null) {
15875                throw new SecurityException(
15876                        "Sticky broadcasts can't target a specific component");
15877            }
15878            // We use userId directly here, since the "all" target is maintained
15879            // as a separate set of sticky broadcasts.
15880            if (userId != UserHandle.USER_ALL) {
15881                // But first, if this is not a broadcast to all users, then
15882                // make sure it doesn't conflict with an existing broadcast to
15883                // all users.
15884                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15885                        UserHandle.USER_ALL);
15886                if (stickies != null) {
15887                    ArrayList<Intent> list = stickies.get(intent.getAction());
15888                    if (list != null) {
15889                        int N = list.size();
15890                        int i;
15891                        for (i=0; i<N; i++) {
15892                            if (intent.filterEquals(list.get(i))) {
15893                                throw new IllegalArgumentException(
15894                                        "Sticky broadcast " + intent + " for user "
15895                                        + userId + " conflicts with existing global broadcast");
15896                            }
15897                        }
15898                    }
15899                }
15900            }
15901            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15902            if (stickies == null) {
15903                stickies = new ArrayMap<String, ArrayList<Intent>>();
15904                mStickyBroadcasts.put(userId, stickies);
15905            }
15906            ArrayList<Intent> list = stickies.get(intent.getAction());
15907            if (list == null) {
15908                list = new ArrayList<Intent>();
15909                stickies.put(intent.getAction(), list);
15910            }
15911            int N = list.size();
15912            int i;
15913            for (i=0; i<N; i++) {
15914                if (intent.filterEquals(list.get(i))) {
15915                    // This sticky already exists, replace it.
15916                    list.set(i, new Intent(intent));
15917                    break;
15918                }
15919            }
15920            if (i >= N) {
15921                list.add(new Intent(intent));
15922            }
15923        }
15924
15925        int[] users;
15926        if (userId == UserHandle.USER_ALL) {
15927            // Caller wants broadcast to go to all started users.
15928            users = mStartedUserArray;
15929        } else {
15930            // Caller wants broadcast to go to one specific user.
15931            users = new int[] {userId};
15932        }
15933
15934        // Figure out who all will receive this broadcast.
15935        List receivers = null;
15936        List<BroadcastFilter> registeredReceivers = null;
15937        // Need to resolve the intent to interested receivers...
15938        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15939                 == 0) {
15940            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15941        }
15942        if (intent.getComponent() == null) {
15943            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15944                // Query one target user at a time, excluding shell-restricted users
15945                UserManagerService ums = getUserManagerLocked();
15946                for (int i = 0; i < users.length; i++) {
15947                    if (ums.hasUserRestriction(
15948                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15949                        continue;
15950                    }
15951                    List<BroadcastFilter> registeredReceiversForUser =
15952                            mReceiverResolver.queryIntent(intent,
15953                                    resolvedType, false, users[i]);
15954                    if (registeredReceivers == null) {
15955                        registeredReceivers = registeredReceiversForUser;
15956                    } else if (registeredReceiversForUser != null) {
15957                        registeredReceivers.addAll(registeredReceiversForUser);
15958                    }
15959                }
15960            } else {
15961                registeredReceivers = mReceiverResolver.queryIntent(intent,
15962                        resolvedType, false, userId);
15963            }
15964        }
15965
15966        final boolean replacePending =
15967                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15968
15969        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15970                + " replacePending=" + replacePending);
15971
15972        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15973        if (!ordered && NR > 0) {
15974            // If we are not serializing this broadcast, then send the
15975            // registered receivers separately so they don't wait for the
15976            // components to be launched.
15977            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15978            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15979                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15980                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15981                    ordered, sticky, false, userId);
15982            if (DEBUG_BROADCAST) Slog.v(
15983                    TAG, "Enqueueing parallel broadcast " + r);
15984            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15985            if (!replaced) {
15986                queue.enqueueParallelBroadcastLocked(r);
15987                queue.scheduleBroadcastsLocked();
15988            }
15989            registeredReceivers = null;
15990            NR = 0;
15991        }
15992
15993        // Merge into one list.
15994        int ir = 0;
15995        if (receivers != null) {
15996            // A special case for PACKAGE_ADDED: do not allow the package
15997            // being added to see this broadcast.  This prevents them from
15998            // using this as a back door to get run as soon as they are
15999            // installed.  Maybe in the future we want to have a special install
16000            // broadcast or such for apps, but we'd like to deliberately make
16001            // this decision.
16002            String skipPackages[] = null;
16003            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16004                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16005                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16006                Uri data = intent.getData();
16007                if (data != null) {
16008                    String pkgName = data.getSchemeSpecificPart();
16009                    if (pkgName != null) {
16010                        skipPackages = new String[] { pkgName };
16011                    }
16012                }
16013            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16014                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16015            }
16016            if (skipPackages != null && (skipPackages.length > 0)) {
16017                for (String skipPackage : skipPackages) {
16018                    if (skipPackage != null) {
16019                        int NT = receivers.size();
16020                        for (int it=0; it<NT; it++) {
16021                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
16022                            if (curt.activityInfo.packageName.equals(skipPackage)) {
16023                                receivers.remove(it);
16024                                it--;
16025                                NT--;
16026                            }
16027                        }
16028                    }
16029                }
16030            }
16031
16032            int NT = receivers != null ? receivers.size() : 0;
16033            int it = 0;
16034            ResolveInfo curt = null;
16035            BroadcastFilter curr = null;
16036            while (it < NT && ir < NR) {
16037                if (curt == null) {
16038                    curt = (ResolveInfo)receivers.get(it);
16039                }
16040                if (curr == null) {
16041                    curr = registeredReceivers.get(ir);
16042                }
16043                if (curr.getPriority() >= curt.priority) {
16044                    // Insert this broadcast record into the final list.
16045                    receivers.add(it, curr);
16046                    ir++;
16047                    curr = null;
16048                    it++;
16049                    NT++;
16050                } else {
16051                    // Skip to the next ResolveInfo in the final list.
16052                    it++;
16053                    curt = null;
16054                }
16055            }
16056        }
16057        while (ir < NR) {
16058            if (receivers == null) {
16059                receivers = new ArrayList();
16060            }
16061            receivers.add(registeredReceivers.get(ir));
16062            ir++;
16063        }
16064
16065        if ((receivers != null && receivers.size() > 0)
16066                || resultTo != null) {
16067            BroadcastQueue queue = broadcastQueueForIntent(intent);
16068            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16069                    callerPackage, callingPid, callingUid, resolvedType,
16070                    requiredPermission, appOp, receivers, resultTo, resultCode,
16071                    resultData, map, ordered, sticky, false, userId);
16072            if (DEBUG_BROADCAST) Slog.v(
16073                    TAG, "Enqueueing ordered broadcast " + r
16074                    + ": prev had " + queue.mOrderedBroadcasts.size());
16075            if (DEBUG_BROADCAST) {
16076                int seq = r.intent.getIntExtra("seq", -1);
16077                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16078            }
16079            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16080            if (!replaced) {
16081                queue.enqueueOrderedBroadcastLocked(r);
16082                queue.scheduleBroadcastsLocked();
16083            }
16084        }
16085
16086        return ActivityManager.BROADCAST_SUCCESS;
16087    }
16088
16089    final Intent verifyBroadcastLocked(Intent intent) {
16090        // Refuse possible leaked file descriptors
16091        if (intent != null && intent.hasFileDescriptors() == true) {
16092            throw new IllegalArgumentException("File descriptors passed in Intent");
16093        }
16094
16095        int flags = intent.getFlags();
16096
16097        if (!mProcessesReady) {
16098            // if the caller really truly claims to know what they're doing, go
16099            // ahead and allow the broadcast without launching any receivers
16100            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16101                intent = new Intent(intent);
16102                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16103            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16104                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16105                        + " before boot completion");
16106                throw new IllegalStateException("Cannot broadcast before boot completed");
16107            }
16108        }
16109
16110        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16111            throw new IllegalArgumentException(
16112                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16113        }
16114
16115        return intent;
16116    }
16117
16118    public final int broadcastIntent(IApplicationThread caller,
16119            Intent intent, String resolvedType, IIntentReceiver resultTo,
16120            int resultCode, String resultData, Bundle map,
16121            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16122        enforceNotIsolatedCaller("broadcastIntent");
16123        synchronized(this) {
16124            intent = verifyBroadcastLocked(intent);
16125
16126            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16127            final int callingPid = Binder.getCallingPid();
16128            final int callingUid = Binder.getCallingUid();
16129            final long origId = Binder.clearCallingIdentity();
16130            int res = broadcastIntentLocked(callerApp,
16131                    callerApp != null ? callerApp.info.packageName : null,
16132                    intent, resolvedType, resultTo,
16133                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16134                    callingPid, callingUid, userId);
16135            Binder.restoreCallingIdentity(origId);
16136            return res;
16137        }
16138    }
16139
16140    int broadcastIntentInPackage(String packageName, int uid,
16141            Intent intent, String resolvedType, IIntentReceiver resultTo,
16142            int resultCode, String resultData, Bundle map,
16143            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16144        synchronized(this) {
16145            intent = verifyBroadcastLocked(intent);
16146
16147            final long origId = Binder.clearCallingIdentity();
16148            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16149                    resultTo, resultCode, resultData, map, requiredPermission,
16150                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16151            Binder.restoreCallingIdentity(origId);
16152            return res;
16153        }
16154    }
16155
16156    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16157        // Refuse possible leaked file descriptors
16158        if (intent != null && intent.hasFileDescriptors() == true) {
16159            throw new IllegalArgumentException("File descriptors passed in Intent");
16160        }
16161
16162        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16163                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16164
16165        synchronized(this) {
16166            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16167                    != PackageManager.PERMISSION_GRANTED) {
16168                String msg = "Permission Denial: unbroadcastIntent() from pid="
16169                        + Binder.getCallingPid()
16170                        + ", uid=" + Binder.getCallingUid()
16171                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16172                Slog.w(TAG, msg);
16173                throw new SecurityException(msg);
16174            }
16175            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16176            if (stickies != null) {
16177                ArrayList<Intent> list = stickies.get(intent.getAction());
16178                if (list != null) {
16179                    int N = list.size();
16180                    int i;
16181                    for (i=0; i<N; i++) {
16182                        if (intent.filterEquals(list.get(i))) {
16183                            list.remove(i);
16184                            break;
16185                        }
16186                    }
16187                    if (list.size() <= 0) {
16188                        stickies.remove(intent.getAction());
16189                    }
16190                }
16191                if (stickies.size() <= 0) {
16192                    mStickyBroadcasts.remove(userId);
16193                }
16194            }
16195        }
16196    }
16197
16198    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16199            String resultData, Bundle resultExtras, boolean resultAbort) {
16200        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16201        if (r == null) {
16202            Slog.w(TAG, "finishReceiver called but not found on queue");
16203            return false;
16204        }
16205
16206        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16207    }
16208
16209    void backgroundServicesFinishedLocked(int userId) {
16210        for (BroadcastQueue queue : mBroadcastQueues) {
16211            queue.backgroundServicesFinishedLocked(userId);
16212        }
16213    }
16214
16215    public void finishReceiver(IBinder who, int resultCode, String resultData,
16216            Bundle resultExtras, boolean resultAbort) {
16217        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16218
16219        // Refuse possible leaked file descriptors
16220        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16221            throw new IllegalArgumentException("File descriptors passed in Bundle");
16222        }
16223
16224        final long origId = Binder.clearCallingIdentity();
16225        try {
16226            boolean doNext = false;
16227            BroadcastRecord r;
16228
16229            synchronized(this) {
16230                r = broadcastRecordForReceiverLocked(who);
16231                if (r != null) {
16232                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16233                        resultData, resultExtras, resultAbort, true);
16234                }
16235            }
16236
16237            if (doNext) {
16238                r.queue.processNextBroadcast(false);
16239            }
16240            trimApplications();
16241        } finally {
16242            Binder.restoreCallingIdentity(origId);
16243        }
16244    }
16245
16246    // =========================================================
16247    // INSTRUMENTATION
16248    // =========================================================
16249
16250    public boolean startInstrumentation(ComponentName className,
16251            String profileFile, int flags, Bundle arguments,
16252            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16253            int userId, String abiOverride) {
16254        enforceNotIsolatedCaller("startInstrumentation");
16255        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16256                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16257        // Refuse possible leaked file descriptors
16258        if (arguments != null && arguments.hasFileDescriptors()) {
16259            throw new IllegalArgumentException("File descriptors passed in Bundle");
16260        }
16261
16262        synchronized(this) {
16263            InstrumentationInfo ii = null;
16264            ApplicationInfo ai = null;
16265            try {
16266                ii = mContext.getPackageManager().getInstrumentationInfo(
16267                    className, STOCK_PM_FLAGS);
16268                ai = AppGlobals.getPackageManager().getApplicationInfo(
16269                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16270            } catch (PackageManager.NameNotFoundException e) {
16271            } catch (RemoteException e) {
16272            }
16273            if (ii == null) {
16274                reportStartInstrumentationFailure(watcher, className,
16275                        "Unable to find instrumentation info for: " + className);
16276                return false;
16277            }
16278            if (ai == null) {
16279                reportStartInstrumentationFailure(watcher, className,
16280                        "Unable to find instrumentation target package: " + ii.targetPackage);
16281                return false;
16282            }
16283
16284            int match = mContext.getPackageManager().checkSignatures(
16285                    ii.targetPackage, ii.packageName);
16286            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16287                String msg = "Permission Denial: starting instrumentation "
16288                        + className + " from pid="
16289                        + Binder.getCallingPid()
16290                        + ", uid=" + Binder.getCallingPid()
16291                        + " not allowed because package " + ii.packageName
16292                        + " does not have a signature matching the target "
16293                        + ii.targetPackage;
16294                reportStartInstrumentationFailure(watcher, className, msg);
16295                throw new SecurityException(msg);
16296            }
16297
16298            final long origId = Binder.clearCallingIdentity();
16299            // Instrumentation can kill and relaunch even persistent processes
16300            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16301                    "start instr");
16302            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16303            app.instrumentationClass = className;
16304            app.instrumentationInfo = ai;
16305            app.instrumentationProfileFile = profileFile;
16306            app.instrumentationArguments = arguments;
16307            app.instrumentationWatcher = watcher;
16308            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16309            app.instrumentationResultClass = className;
16310            Binder.restoreCallingIdentity(origId);
16311        }
16312
16313        return true;
16314    }
16315
16316    /**
16317     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16318     * error to the logs, but if somebody is watching, send the report there too.  This enables
16319     * the "am" command to report errors with more information.
16320     *
16321     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16322     * @param cn The component name of the instrumentation.
16323     * @param report The error report.
16324     */
16325    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16326            ComponentName cn, String report) {
16327        Slog.w(TAG, report);
16328        try {
16329            if (watcher != null) {
16330                Bundle results = new Bundle();
16331                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16332                results.putString("Error", report);
16333                watcher.instrumentationStatus(cn, -1, results);
16334            }
16335        } catch (RemoteException e) {
16336            Slog.w(TAG, e);
16337        }
16338    }
16339
16340    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16341        if (app.instrumentationWatcher != null) {
16342            try {
16343                // NOTE:  IInstrumentationWatcher *must* be oneway here
16344                app.instrumentationWatcher.instrumentationFinished(
16345                    app.instrumentationClass,
16346                    resultCode,
16347                    results);
16348            } catch (RemoteException e) {
16349            }
16350        }
16351        if (app.instrumentationUiAutomationConnection != null) {
16352            try {
16353                app.instrumentationUiAutomationConnection.shutdown();
16354            } catch (RemoteException re) {
16355                /* ignore */
16356            }
16357            // Only a UiAutomation can set this flag and now that
16358            // it is finished we make sure it is reset to its default.
16359            mUserIsMonkey = false;
16360        }
16361        app.instrumentationWatcher = null;
16362        app.instrumentationUiAutomationConnection = null;
16363        app.instrumentationClass = null;
16364        app.instrumentationInfo = null;
16365        app.instrumentationProfileFile = null;
16366        app.instrumentationArguments = null;
16367
16368        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16369                "finished inst");
16370    }
16371
16372    public void finishInstrumentation(IApplicationThread target,
16373            int resultCode, Bundle results) {
16374        int userId = UserHandle.getCallingUserId();
16375        // Refuse possible leaked file descriptors
16376        if (results != null && results.hasFileDescriptors()) {
16377            throw new IllegalArgumentException("File descriptors passed in Intent");
16378        }
16379
16380        synchronized(this) {
16381            ProcessRecord app = getRecordForAppLocked(target);
16382            if (app == null) {
16383                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16384                return;
16385            }
16386            final long origId = Binder.clearCallingIdentity();
16387            finishInstrumentationLocked(app, resultCode, results);
16388            Binder.restoreCallingIdentity(origId);
16389        }
16390    }
16391
16392    // =========================================================
16393    // CONFIGURATION
16394    // =========================================================
16395
16396    public ConfigurationInfo getDeviceConfigurationInfo() {
16397        ConfigurationInfo config = new ConfigurationInfo();
16398        synchronized (this) {
16399            config.reqTouchScreen = mConfiguration.touchscreen;
16400            config.reqKeyboardType = mConfiguration.keyboard;
16401            config.reqNavigation = mConfiguration.navigation;
16402            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16403                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16404                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16405            }
16406            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16407                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16408                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16409            }
16410            config.reqGlEsVersion = GL_ES_VERSION;
16411        }
16412        return config;
16413    }
16414
16415    ActivityStack getFocusedStack() {
16416        return mStackSupervisor.getFocusedStack();
16417    }
16418
16419    public Configuration getConfiguration() {
16420        Configuration ci;
16421        synchronized(this) {
16422            ci = new Configuration(mConfiguration);
16423        }
16424        return ci;
16425    }
16426
16427    public void updatePersistentConfiguration(Configuration values) {
16428        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16429                "updateConfiguration()");
16430        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16431                "updateConfiguration()");
16432        if (values == null) {
16433            throw new NullPointerException("Configuration must not be null");
16434        }
16435
16436        synchronized(this) {
16437            final long origId = Binder.clearCallingIdentity();
16438            updateConfigurationLocked(values, null, true, false);
16439            Binder.restoreCallingIdentity(origId);
16440        }
16441    }
16442
16443    public void updateConfiguration(Configuration values) {
16444        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16445                "updateConfiguration()");
16446
16447        synchronized(this) {
16448            if (values == null && mWindowManager != null) {
16449                // sentinel: fetch the current configuration from the window manager
16450                values = mWindowManager.computeNewConfiguration();
16451            }
16452
16453            if (mWindowManager != null) {
16454                mProcessList.applyDisplaySize(mWindowManager);
16455            }
16456
16457            final long origId = Binder.clearCallingIdentity();
16458            if (values != null) {
16459                Settings.System.clearConfiguration(values);
16460            }
16461            updateConfigurationLocked(values, null, false, false);
16462            Binder.restoreCallingIdentity(origId);
16463        }
16464    }
16465
16466    /**
16467     * Do either or both things: (1) change the current configuration, and (2)
16468     * make sure the given activity is running with the (now) current
16469     * configuration.  Returns true if the activity has been left running, or
16470     * false if <var>starting</var> is being destroyed to match the new
16471     * configuration.
16472     * @param persistent TODO
16473     */
16474    boolean updateConfigurationLocked(Configuration values,
16475            ActivityRecord starting, boolean persistent, boolean initLocale) {
16476        int changes = 0;
16477
16478        if (values != null) {
16479            Configuration newConfig = new Configuration(mConfiguration);
16480            changes = newConfig.updateFrom(values);
16481            if (changes != 0) {
16482                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16483                    Slog.i(TAG, "Updating configuration to: " + values);
16484                }
16485
16486                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16487
16488                if (values.locale != null && !initLocale) {
16489                    saveLocaleLocked(values.locale,
16490                                     !values.locale.equals(mConfiguration.locale),
16491                                     values.userSetLocale);
16492                }
16493
16494                mConfigurationSeq++;
16495                if (mConfigurationSeq <= 0) {
16496                    mConfigurationSeq = 1;
16497                }
16498                newConfig.seq = mConfigurationSeq;
16499                mConfiguration = newConfig;
16500                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16501                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16502                //mUsageStatsService.noteStartConfig(newConfig);
16503
16504                final Configuration configCopy = new Configuration(mConfiguration);
16505
16506                // TODO: If our config changes, should we auto dismiss any currently
16507                // showing dialogs?
16508                mShowDialogs = shouldShowDialogs(newConfig);
16509
16510                AttributeCache ac = AttributeCache.instance();
16511                if (ac != null) {
16512                    ac.updateConfiguration(configCopy);
16513                }
16514
16515                // Make sure all resources in our process are updated
16516                // right now, so that anyone who is going to retrieve
16517                // resource values after we return will be sure to get
16518                // the new ones.  This is especially important during
16519                // boot, where the first config change needs to guarantee
16520                // all resources have that config before following boot
16521                // code is executed.
16522                mSystemThread.applyConfigurationToResources(configCopy);
16523
16524                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16525                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16526                    msg.obj = new Configuration(configCopy);
16527                    mHandler.sendMessage(msg);
16528                }
16529
16530                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16531                    ProcessRecord app = mLruProcesses.get(i);
16532                    try {
16533                        if (app.thread != null) {
16534                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16535                                    + app.processName + " new config " + mConfiguration);
16536                            app.thread.scheduleConfigurationChanged(configCopy);
16537                        }
16538                    } catch (Exception e) {
16539                    }
16540                }
16541                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16542                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16543                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16544                        | Intent.FLAG_RECEIVER_FOREGROUND);
16545                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16546                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16547                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16548                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16549                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16550                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16551                    broadcastIntentLocked(null, null, intent,
16552                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16553                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16554                }
16555            }
16556        }
16557
16558        boolean kept = true;
16559        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16560        // mainStack is null during startup.
16561        if (mainStack != null) {
16562            if (changes != 0 && starting == null) {
16563                // If the configuration changed, and the caller is not already
16564                // in the process of starting an activity, then find the top
16565                // activity to check if its configuration needs to change.
16566                starting = mainStack.topRunningActivityLocked(null);
16567            }
16568
16569            if (starting != null) {
16570                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16571                // And we need to make sure at this point that all other activities
16572                // are made visible with the correct configuration.
16573                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16574            }
16575        }
16576
16577        if (values != null && mWindowManager != null) {
16578            mWindowManager.setNewConfiguration(mConfiguration);
16579        }
16580
16581        return kept;
16582    }
16583
16584    /**
16585     * Decide based on the configuration whether we should shouw the ANR,
16586     * crash, etc dialogs.  The idea is that if there is no affordnace to
16587     * press the on-screen buttons, we shouldn't show the dialog.
16588     *
16589     * A thought: SystemUI might also want to get told about this, the Power
16590     * dialog / global actions also might want different behaviors.
16591     */
16592    private static final boolean shouldShowDialogs(Configuration config) {
16593        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16594                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16595    }
16596
16597    /**
16598     * Save the locale.  You must be inside a synchronized (this) block.
16599     */
16600    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16601        if(isDiff) {
16602            SystemProperties.set("user.language", l.getLanguage());
16603            SystemProperties.set("user.region", l.getCountry());
16604        }
16605
16606        if(isPersist) {
16607            SystemProperties.set("persist.sys.language", l.getLanguage());
16608            SystemProperties.set("persist.sys.country", l.getCountry());
16609            SystemProperties.set("persist.sys.localevar", l.getVariant());
16610
16611            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16612        }
16613    }
16614
16615    @Override
16616    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16617        synchronized (this) {
16618            ActivityRecord srec = ActivityRecord.forToken(token);
16619            if (srec.task != null && srec.task.stack != null) {
16620                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16621            }
16622        }
16623        return false;
16624    }
16625
16626    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16627            Intent resultData) {
16628
16629        synchronized (this) {
16630            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16631            if (stack != null) {
16632                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16633            }
16634            return false;
16635        }
16636    }
16637
16638    public int getLaunchedFromUid(IBinder activityToken) {
16639        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16640        if (srec == null) {
16641            return -1;
16642        }
16643        return srec.launchedFromUid;
16644    }
16645
16646    public String getLaunchedFromPackage(IBinder activityToken) {
16647        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16648        if (srec == null) {
16649            return null;
16650        }
16651        return srec.launchedFromPackage;
16652    }
16653
16654    // =========================================================
16655    // LIFETIME MANAGEMENT
16656    // =========================================================
16657
16658    // Returns which broadcast queue the app is the current [or imminent] receiver
16659    // on, or 'null' if the app is not an active broadcast recipient.
16660    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16661        BroadcastRecord r = app.curReceiver;
16662        if (r != null) {
16663            return r.queue;
16664        }
16665
16666        // It's not the current receiver, but it might be starting up to become one
16667        synchronized (this) {
16668            for (BroadcastQueue queue : mBroadcastQueues) {
16669                r = queue.mPendingBroadcast;
16670                if (r != null && r.curApp == app) {
16671                    // found it; report which queue it's in
16672                    return queue;
16673                }
16674            }
16675        }
16676
16677        return null;
16678    }
16679
16680    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16681            boolean doingAll, long now) {
16682        if (mAdjSeq == app.adjSeq) {
16683            // This adjustment has already been computed.
16684            return app.curRawAdj;
16685        }
16686
16687        if (app.thread == null) {
16688            app.adjSeq = mAdjSeq;
16689            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16690            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16691            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16692        }
16693
16694        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16695        app.adjSource = null;
16696        app.adjTarget = null;
16697        app.empty = false;
16698        app.cached = false;
16699
16700        final int activitiesSize = app.activities.size();
16701
16702        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16703            // The max adjustment doesn't allow this app to be anything
16704            // below foreground, so it is not worth doing work for it.
16705            app.adjType = "fixed";
16706            app.adjSeq = mAdjSeq;
16707            app.curRawAdj = app.maxAdj;
16708            app.foregroundActivities = false;
16709            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16710            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16711            // System processes can do UI, and when they do we want to have
16712            // them trim their memory after the user leaves the UI.  To
16713            // facilitate this, here we need to determine whether or not it
16714            // is currently showing UI.
16715            app.systemNoUi = true;
16716            if (app == TOP_APP) {
16717                app.systemNoUi = false;
16718            } else if (activitiesSize > 0) {
16719                for (int j = 0; j < activitiesSize; j++) {
16720                    final ActivityRecord r = app.activities.get(j);
16721                    if (r.visible) {
16722                        app.systemNoUi = false;
16723                    }
16724                }
16725            }
16726            if (!app.systemNoUi) {
16727                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16728            }
16729            return (app.curAdj=app.maxAdj);
16730        }
16731
16732        app.systemNoUi = false;
16733
16734        // Determine the importance of the process, starting with most
16735        // important to least, and assign an appropriate OOM adjustment.
16736        int adj;
16737        int schedGroup;
16738        int procState;
16739        boolean foregroundActivities = false;
16740        BroadcastQueue queue;
16741        if (app == TOP_APP) {
16742            // The last app on the list is the foreground app.
16743            adj = ProcessList.FOREGROUND_APP_ADJ;
16744            schedGroup = Process.THREAD_GROUP_DEFAULT;
16745            app.adjType = "top-activity";
16746            foregroundActivities = true;
16747            procState = ActivityManager.PROCESS_STATE_TOP;
16748        } else if (app.instrumentationClass != null) {
16749            // Don't want to kill running instrumentation.
16750            adj = ProcessList.FOREGROUND_APP_ADJ;
16751            schedGroup = Process.THREAD_GROUP_DEFAULT;
16752            app.adjType = "instrumentation";
16753            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16754        } else if ((queue = isReceivingBroadcast(app)) != null) {
16755            // An app that is currently receiving a broadcast also
16756            // counts as being in the foreground for OOM killer purposes.
16757            // It's placed in a sched group based on the nature of the
16758            // broadcast as reflected by which queue it's active in.
16759            adj = ProcessList.FOREGROUND_APP_ADJ;
16760            schedGroup = (queue == mFgBroadcastQueue)
16761                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16762            app.adjType = "broadcast";
16763            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16764        } else if (app.executingServices.size() > 0) {
16765            // An app that is currently executing a service callback also
16766            // counts as being in the foreground.
16767            adj = ProcessList.FOREGROUND_APP_ADJ;
16768            schedGroup = app.execServicesFg ?
16769                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16770            app.adjType = "exec-service";
16771            procState = ActivityManager.PROCESS_STATE_SERVICE;
16772            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16773        } else {
16774            // As far as we know the process is empty.  We may change our mind later.
16775            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16776            // At this point we don't actually know the adjustment.  Use the cached adj
16777            // value that the caller wants us to.
16778            adj = cachedAdj;
16779            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16780            app.cached = true;
16781            app.empty = true;
16782            app.adjType = "cch-empty";
16783        }
16784
16785        // Examine all activities if not already foreground.
16786        if (!foregroundActivities && activitiesSize > 0) {
16787            for (int j = 0; j < activitiesSize; j++) {
16788                final ActivityRecord r = app.activities.get(j);
16789                if (r.app != app) {
16790                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16791                            + app + "?!?");
16792                    continue;
16793                }
16794                if (r.visible) {
16795                    // App has a visible activity; only upgrade adjustment.
16796                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16797                        adj = ProcessList.VISIBLE_APP_ADJ;
16798                        app.adjType = "visible";
16799                    }
16800                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16801                        procState = ActivityManager.PROCESS_STATE_TOP;
16802                    }
16803                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16804                    app.cached = false;
16805                    app.empty = false;
16806                    foregroundActivities = true;
16807                    break;
16808                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16809                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16810                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16811                        app.adjType = "pausing";
16812                    }
16813                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16814                        procState = ActivityManager.PROCESS_STATE_TOP;
16815                    }
16816                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16817                    app.cached = false;
16818                    app.empty = false;
16819                    foregroundActivities = true;
16820                } else if (r.state == ActivityState.STOPPING) {
16821                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16822                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16823                        app.adjType = "stopping";
16824                    }
16825                    // For the process state, we will at this point consider the
16826                    // process to be cached.  It will be cached either as an activity
16827                    // or empty depending on whether the activity is finishing.  We do
16828                    // this so that we can treat the process as cached for purposes of
16829                    // memory trimming (determing current memory level, trim command to
16830                    // send to process) since there can be an arbitrary number of stopping
16831                    // processes and they should soon all go into the cached state.
16832                    if (!r.finishing) {
16833                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16834                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16835                        }
16836                    }
16837                    app.cached = false;
16838                    app.empty = false;
16839                    foregroundActivities = true;
16840                } else {
16841                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16842                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16843                        app.adjType = "cch-act";
16844                    }
16845                }
16846            }
16847        }
16848
16849        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16850            if (app.foregroundServices) {
16851                // The user is aware of this app, so make it visible.
16852                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16853                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16854                app.cached = false;
16855                app.adjType = "fg-service";
16856                schedGroup = Process.THREAD_GROUP_DEFAULT;
16857            } else if (app.forcingToForeground != null) {
16858                // The user is aware of this app, so make it visible.
16859                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16860                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16861                app.cached = false;
16862                app.adjType = "force-fg";
16863                app.adjSource = app.forcingToForeground;
16864                schedGroup = Process.THREAD_GROUP_DEFAULT;
16865            }
16866        }
16867
16868        if (app == mHeavyWeightProcess) {
16869            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16870                // We don't want to kill the current heavy-weight process.
16871                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16872                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16873                app.cached = false;
16874                app.adjType = "heavy";
16875            }
16876            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16877                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16878            }
16879        }
16880
16881        if (app == mHomeProcess) {
16882            if (adj > ProcessList.HOME_APP_ADJ) {
16883                // This process is hosting what we currently consider to be the
16884                // home app, so we don't want to let it go into the background.
16885                adj = ProcessList.HOME_APP_ADJ;
16886                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16887                app.cached = false;
16888                app.adjType = "home";
16889            }
16890            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16891                procState = ActivityManager.PROCESS_STATE_HOME;
16892            }
16893        }
16894
16895        if (app == mPreviousProcess && app.activities.size() > 0) {
16896            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16897                // This was the previous process that showed UI to the user.
16898                // We want to try to keep it around more aggressively, to give
16899                // a good experience around switching between two apps.
16900                adj = ProcessList.PREVIOUS_APP_ADJ;
16901                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16902                app.cached = false;
16903                app.adjType = "previous";
16904            }
16905            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16906                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16907            }
16908        }
16909
16910        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16911                + " reason=" + app.adjType);
16912
16913        // By default, we use the computed adjustment.  It may be changed if
16914        // there are applications dependent on our services or providers, but
16915        // this gives us a baseline and makes sure we don't get into an
16916        // infinite recursion.
16917        app.adjSeq = mAdjSeq;
16918        app.curRawAdj = adj;
16919        app.hasStartedServices = false;
16920
16921        if (mBackupTarget != null && app == mBackupTarget.app) {
16922            // If possible we want to avoid killing apps while they're being backed up
16923            if (adj > ProcessList.BACKUP_APP_ADJ) {
16924                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16925                adj = ProcessList.BACKUP_APP_ADJ;
16926                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16927                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16928                }
16929                app.adjType = "backup";
16930                app.cached = false;
16931            }
16932            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16933                procState = ActivityManager.PROCESS_STATE_BACKUP;
16934            }
16935        }
16936
16937        boolean mayBeTop = false;
16938
16939        for (int is = app.services.size()-1;
16940                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16941                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16942                        || procState > ActivityManager.PROCESS_STATE_TOP);
16943                is--) {
16944            ServiceRecord s = app.services.valueAt(is);
16945            if (s.startRequested) {
16946                app.hasStartedServices = true;
16947                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16948                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16949                }
16950                if (app.hasShownUi && app != mHomeProcess) {
16951                    // If this process has shown some UI, let it immediately
16952                    // go to the LRU list because it may be pretty heavy with
16953                    // UI stuff.  We'll tag it with a label just to help
16954                    // debug and understand what is going on.
16955                    if (adj > ProcessList.SERVICE_ADJ) {
16956                        app.adjType = "cch-started-ui-services";
16957                    }
16958                } else {
16959                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16960                        // This service has seen some activity within
16961                        // recent memory, so we will keep its process ahead
16962                        // of the background processes.
16963                        if (adj > ProcessList.SERVICE_ADJ) {
16964                            adj = ProcessList.SERVICE_ADJ;
16965                            app.adjType = "started-services";
16966                            app.cached = false;
16967                        }
16968                    }
16969                    // If we have let the service slide into the background
16970                    // state, still have some text describing what it is doing
16971                    // even though the service no longer has an impact.
16972                    if (adj > ProcessList.SERVICE_ADJ) {
16973                        app.adjType = "cch-started-services";
16974                    }
16975                }
16976            }
16977            for (int conni = s.connections.size()-1;
16978                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16979                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16980                            || procState > ActivityManager.PROCESS_STATE_TOP);
16981                    conni--) {
16982                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16983                for (int i = 0;
16984                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16985                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16986                                || procState > ActivityManager.PROCESS_STATE_TOP);
16987                        i++) {
16988                    // XXX should compute this based on the max of
16989                    // all connected clients.
16990                    ConnectionRecord cr = clist.get(i);
16991                    if (cr.binding.client == app) {
16992                        // Binding to ourself is not interesting.
16993                        continue;
16994                    }
16995                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16996                        ProcessRecord client = cr.binding.client;
16997                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16998                                TOP_APP, doingAll, now);
16999                        int clientProcState = client.curProcState;
17000                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17001                            // If the other app is cached for any reason, for purposes here
17002                            // we are going to consider it empty.  The specific cached state
17003                            // doesn't propagate except under certain conditions.
17004                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17005                        }
17006                        String adjType = null;
17007                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17008                            // Not doing bind OOM management, so treat
17009                            // this guy more like a started service.
17010                            if (app.hasShownUi && app != mHomeProcess) {
17011                                // If this process has shown some UI, let it immediately
17012                                // go to the LRU list because it may be pretty heavy with
17013                                // UI stuff.  We'll tag it with a label just to help
17014                                // debug and understand what is going on.
17015                                if (adj > clientAdj) {
17016                                    adjType = "cch-bound-ui-services";
17017                                }
17018                                app.cached = false;
17019                                clientAdj = adj;
17020                                clientProcState = procState;
17021                            } else {
17022                                if (now >= (s.lastActivity
17023                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17024                                    // This service has not seen activity within
17025                                    // recent memory, so allow it to drop to the
17026                                    // LRU list if there is no other reason to keep
17027                                    // it around.  We'll also tag it with a label just
17028                                    // to help debug and undertand what is going on.
17029                                    if (adj > clientAdj) {
17030                                        adjType = "cch-bound-services";
17031                                    }
17032                                    clientAdj = adj;
17033                                }
17034                            }
17035                        }
17036                        if (adj > clientAdj) {
17037                            // If this process has recently shown UI, and
17038                            // the process that is binding to it is less
17039                            // important than being visible, then we don't
17040                            // care about the binding as much as we care
17041                            // about letting this process get into the LRU
17042                            // list to be killed and restarted if needed for
17043                            // memory.
17044                            if (app.hasShownUi && app != mHomeProcess
17045                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17046                                adjType = "cch-bound-ui-services";
17047                            } else {
17048                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17049                                        |Context.BIND_IMPORTANT)) != 0) {
17050                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17051                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17052                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17053                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17054                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17055                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17056                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17057                                    adj = clientAdj;
17058                                } else {
17059                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17060                                        adj = ProcessList.VISIBLE_APP_ADJ;
17061                                    }
17062                                }
17063                                if (!client.cached) {
17064                                    app.cached = false;
17065                                }
17066                                adjType = "service";
17067                            }
17068                        }
17069                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17070                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17071                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17072                            }
17073                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17074                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17075                                    // Special handling of clients who are in the top state.
17076                                    // We *may* want to consider this process to be in the
17077                                    // top state as well, but only if there is not another
17078                                    // reason for it to be running.  Being on the top is a
17079                                    // special state, meaning you are specifically running
17080                                    // for the current top app.  If the process is already
17081                                    // running in the background for some other reason, it
17082                                    // is more important to continue considering it to be
17083                                    // in the background state.
17084                                    mayBeTop = true;
17085                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17086                                } else {
17087                                    // Special handling for above-top states (persistent
17088                                    // processes).  These should not bring the current process
17089                                    // into the top state, since they are not on top.  Instead
17090                                    // give them the best state after that.
17091                                    clientProcState =
17092                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17093                                }
17094                            }
17095                        } else {
17096                            if (clientProcState <
17097                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17098                                clientProcState =
17099                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17100                            }
17101                        }
17102                        if (procState > clientProcState) {
17103                            procState = clientProcState;
17104                        }
17105                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17106                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17107                            app.pendingUiClean = true;
17108                        }
17109                        if (adjType != null) {
17110                            app.adjType = adjType;
17111                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17112                                    .REASON_SERVICE_IN_USE;
17113                            app.adjSource = cr.binding.client;
17114                            app.adjSourceProcState = clientProcState;
17115                            app.adjTarget = s.name;
17116                        }
17117                    }
17118                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17119                        app.treatLikeActivity = true;
17120                    }
17121                    final ActivityRecord a = cr.activity;
17122                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17123                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17124                                (a.visible || a.state == ActivityState.RESUMED
17125                                 || a.state == ActivityState.PAUSING)) {
17126                            adj = ProcessList.FOREGROUND_APP_ADJ;
17127                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17128                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17129                            }
17130                            app.cached = false;
17131                            app.adjType = "service";
17132                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17133                                    .REASON_SERVICE_IN_USE;
17134                            app.adjSource = a;
17135                            app.adjSourceProcState = procState;
17136                            app.adjTarget = s.name;
17137                        }
17138                    }
17139                }
17140            }
17141        }
17142
17143        for (int provi = app.pubProviders.size()-1;
17144                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17145                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17146                        || procState > ActivityManager.PROCESS_STATE_TOP);
17147                provi--) {
17148            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17149            for (int i = cpr.connections.size()-1;
17150                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17151                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17152                            || procState > ActivityManager.PROCESS_STATE_TOP);
17153                    i--) {
17154                ContentProviderConnection conn = cpr.connections.get(i);
17155                ProcessRecord client = conn.client;
17156                if (client == app) {
17157                    // Being our own client is not interesting.
17158                    continue;
17159                }
17160                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17161                int clientProcState = client.curProcState;
17162                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17163                    // If the other app is cached for any reason, for purposes here
17164                    // we are going to consider it empty.
17165                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17166                }
17167                if (adj > clientAdj) {
17168                    if (app.hasShownUi && app != mHomeProcess
17169                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17170                        app.adjType = "cch-ui-provider";
17171                    } else {
17172                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17173                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17174                        app.adjType = "provider";
17175                    }
17176                    app.cached &= client.cached;
17177                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17178                            .REASON_PROVIDER_IN_USE;
17179                    app.adjSource = client;
17180                    app.adjSourceProcState = clientProcState;
17181                    app.adjTarget = cpr.name;
17182                }
17183                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17184                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17185                        // Special handling of clients who are in the top state.
17186                        // We *may* want to consider this process to be in the
17187                        // top state as well, but only if there is not another
17188                        // reason for it to be running.  Being on the top is a
17189                        // special state, meaning you are specifically running
17190                        // for the current top app.  If the process is already
17191                        // running in the background for some other reason, it
17192                        // is more important to continue considering it to be
17193                        // in the background state.
17194                        mayBeTop = true;
17195                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17196                    } else {
17197                        // Special handling for above-top states (persistent
17198                        // processes).  These should not bring the current process
17199                        // into the top state, since they are not on top.  Instead
17200                        // give them the best state after that.
17201                        clientProcState =
17202                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17203                    }
17204                }
17205                if (procState > clientProcState) {
17206                    procState = clientProcState;
17207                }
17208                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17209                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17210                }
17211            }
17212            // If the provider has external (non-framework) process
17213            // dependencies, ensure that its adjustment is at least
17214            // FOREGROUND_APP_ADJ.
17215            if (cpr.hasExternalProcessHandles()) {
17216                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17217                    adj = ProcessList.FOREGROUND_APP_ADJ;
17218                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17219                    app.cached = false;
17220                    app.adjType = "provider";
17221                    app.adjTarget = cpr.name;
17222                }
17223                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17224                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17225                }
17226            }
17227        }
17228
17229        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17230            // A client of one of our services or providers is in the top state.  We
17231            // *may* want to be in the top state, but not if we are already running in
17232            // the background for some other reason.  For the decision here, we are going
17233            // to pick out a few specific states that we want to remain in when a client
17234            // is top (states that tend to be longer-term) and otherwise allow it to go
17235            // to the top state.
17236            switch (procState) {
17237                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17238                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17239                case ActivityManager.PROCESS_STATE_SERVICE:
17240                    // These all are longer-term states, so pull them up to the top
17241                    // of the background states, but not all the way to the top state.
17242                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17243                    break;
17244                default:
17245                    // Otherwise, top is a better choice, so take it.
17246                    procState = ActivityManager.PROCESS_STATE_TOP;
17247                    break;
17248            }
17249        }
17250
17251        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17252            if (app.hasClientActivities) {
17253                // This is a cached process, but with client activities.  Mark it so.
17254                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17255                app.adjType = "cch-client-act";
17256            } else if (app.treatLikeActivity) {
17257                // This is a cached process, but somebody wants us to treat it like it has
17258                // an activity, okay!
17259                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17260                app.adjType = "cch-as-act";
17261            }
17262        }
17263
17264        if (adj == ProcessList.SERVICE_ADJ) {
17265            if (doingAll) {
17266                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17267                mNewNumServiceProcs++;
17268                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17269                if (!app.serviceb) {
17270                    // This service isn't far enough down on the LRU list to
17271                    // normally be a B service, but if we are low on RAM and it
17272                    // is large we want to force it down since we would prefer to
17273                    // keep launcher over it.
17274                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17275                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17276                        app.serviceHighRam = true;
17277                        app.serviceb = true;
17278                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17279                    } else {
17280                        mNewNumAServiceProcs++;
17281                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17282                    }
17283                } else {
17284                    app.serviceHighRam = false;
17285                }
17286            }
17287            if (app.serviceb) {
17288                adj = ProcessList.SERVICE_B_ADJ;
17289            }
17290        }
17291
17292        app.curRawAdj = adj;
17293
17294        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17295        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17296        if (adj > app.maxAdj) {
17297            adj = app.maxAdj;
17298            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17299                schedGroup = Process.THREAD_GROUP_DEFAULT;
17300            }
17301        }
17302
17303        // Do final modification to adj.  Everything we do between here and applying
17304        // the final setAdj must be done in this function, because we will also use
17305        // it when computing the final cached adj later.  Note that we don't need to
17306        // worry about this for max adj above, since max adj will always be used to
17307        // keep it out of the cached vaues.
17308        app.curAdj = app.modifyRawOomAdj(adj);
17309        app.curSchedGroup = schedGroup;
17310        app.curProcState = procState;
17311        app.foregroundActivities = foregroundActivities;
17312
17313        return app.curRawAdj;
17314    }
17315
17316    /**
17317     * Schedule PSS collection of a process.
17318     */
17319    void requestPssLocked(ProcessRecord proc, int procState) {
17320        if (mPendingPssProcesses.contains(proc)) {
17321            return;
17322        }
17323        if (mPendingPssProcesses.size() == 0) {
17324            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17325        }
17326        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17327        proc.pssProcState = procState;
17328        mPendingPssProcesses.add(proc);
17329    }
17330
17331    /**
17332     * Schedule PSS collection of all processes.
17333     */
17334    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17335        if (!always) {
17336            if (now < (mLastFullPssTime +
17337                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17338                return;
17339            }
17340        }
17341        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17342        mLastFullPssTime = now;
17343        mFullPssPending = true;
17344        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17345        mPendingPssProcesses.clear();
17346        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17347            ProcessRecord app = mLruProcesses.get(i);
17348            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17349                app.pssProcState = app.setProcState;
17350                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17351                        isSleeping(), now);
17352                mPendingPssProcesses.add(app);
17353            }
17354        }
17355        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17356    }
17357
17358    /**
17359     * Ask a given process to GC right now.
17360     */
17361    final void performAppGcLocked(ProcessRecord app) {
17362        try {
17363            app.lastRequestedGc = SystemClock.uptimeMillis();
17364            if (app.thread != null) {
17365                if (app.reportLowMemory) {
17366                    app.reportLowMemory = false;
17367                    app.thread.scheduleLowMemory();
17368                } else {
17369                    app.thread.processInBackground();
17370                }
17371            }
17372        } catch (Exception e) {
17373            // whatever.
17374        }
17375    }
17376
17377    /**
17378     * Returns true if things are idle enough to perform GCs.
17379     */
17380    private final boolean canGcNowLocked() {
17381        boolean processingBroadcasts = false;
17382        for (BroadcastQueue q : mBroadcastQueues) {
17383            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17384                processingBroadcasts = true;
17385            }
17386        }
17387        return !processingBroadcasts
17388                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17389    }
17390
17391    /**
17392     * Perform GCs on all processes that are waiting for it, but only
17393     * if things are idle.
17394     */
17395    final void performAppGcsLocked() {
17396        final int N = mProcessesToGc.size();
17397        if (N <= 0) {
17398            return;
17399        }
17400        if (canGcNowLocked()) {
17401            while (mProcessesToGc.size() > 0) {
17402                ProcessRecord proc = mProcessesToGc.remove(0);
17403                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17404                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17405                            <= SystemClock.uptimeMillis()) {
17406                        // To avoid spamming the system, we will GC processes one
17407                        // at a time, waiting a few seconds between each.
17408                        performAppGcLocked(proc);
17409                        scheduleAppGcsLocked();
17410                        return;
17411                    } else {
17412                        // It hasn't been long enough since we last GCed this
17413                        // process...  put it in the list to wait for its time.
17414                        addProcessToGcListLocked(proc);
17415                        break;
17416                    }
17417                }
17418            }
17419
17420            scheduleAppGcsLocked();
17421        }
17422    }
17423
17424    /**
17425     * If all looks good, perform GCs on all processes waiting for them.
17426     */
17427    final void performAppGcsIfAppropriateLocked() {
17428        if (canGcNowLocked()) {
17429            performAppGcsLocked();
17430            return;
17431        }
17432        // Still not idle, wait some more.
17433        scheduleAppGcsLocked();
17434    }
17435
17436    /**
17437     * Schedule the execution of all pending app GCs.
17438     */
17439    final void scheduleAppGcsLocked() {
17440        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17441
17442        if (mProcessesToGc.size() > 0) {
17443            // Schedule a GC for the time to the next process.
17444            ProcessRecord proc = mProcessesToGc.get(0);
17445            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17446
17447            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17448            long now = SystemClock.uptimeMillis();
17449            if (when < (now+GC_TIMEOUT)) {
17450                when = now + GC_TIMEOUT;
17451            }
17452            mHandler.sendMessageAtTime(msg, when);
17453        }
17454    }
17455
17456    /**
17457     * Add a process to the array of processes waiting to be GCed.  Keeps the
17458     * list in sorted order by the last GC time.  The process can't already be
17459     * on the list.
17460     */
17461    final void addProcessToGcListLocked(ProcessRecord proc) {
17462        boolean added = false;
17463        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17464            if (mProcessesToGc.get(i).lastRequestedGc <
17465                    proc.lastRequestedGc) {
17466                added = true;
17467                mProcessesToGc.add(i+1, proc);
17468                break;
17469            }
17470        }
17471        if (!added) {
17472            mProcessesToGc.add(0, proc);
17473        }
17474    }
17475
17476    /**
17477     * Set up to ask a process to GC itself.  This will either do it
17478     * immediately, or put it on the list of processes to gc the next
17479     * time things are idle.
17480     */
17481    final void scheduleAppGcLocked(ProcessRecord app) {
17482        long now = SystemClock.uptimeMillis();
17483        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17484            return;
17485        }
17486        if (!mProcessesToGc.contains(app)) {
17487            addProcessToGcListLocked(app);
17488            scheduleAppGcsLocked();
17489        }
17490    }
17491
17492    final void checkExcessivePowerUsageLocked(boolean doKills) {
17493        updateCpuStatsNow();
17494
17495        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17496        boolean doWakeKills = doKills;
17497        boolean doCpuKills = doKills;
17498        if (mLastPowerCheckRealtime == 0) {
17499            doWakeKills = false;
17500        }
17501        if (mLastPowerCheckUptime == 0) {
17502            doCpuKills = false;
17503        }
17504        if (stats.isScreenOn()) {
17505            doWakeKills = false;
17506        }
17507        final long curRealtime = SystemClock.elapsedRealtime();
17508        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17509        final long curUptime = SystemClock.uptimeMillis();
17510        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17511        mLastPowerCheckRealtime = curRealtime;
17512        mLastPowerCheckUptime = curUptime;
17513        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17514            doWakeKills = false;
17515        }
17516        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17517            doCpuKills = false;
17518        }
17519        int i = mLruProcesses.size();
17520        while (i > 0) {
17521            i--;
17522            ProcessRecord app = mLruProcesses.get(i);
17523            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17524                long wtime;
17525                synchronized (stats) {
17526                    wtime = stats.getProcessWakeTime(app.info.uid,
17527                            app.pid, curRealtime);
17528                }
17529                long wtimeUsed = wtime - app.lastWakeTime;
17530                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17531                if (DEBUG_POWER) {
17532                    StringBuilder sb = new StringBuilder(128);
17533                    sb.append("Wake for ");
17534                    app.toShortString(sb);
17535                    sb.append(": over ");
17536                    TimeUtils.formatDuration(realtimeSince, sb);
17537                    sb.append(" used ");
17538                    TimeUtils.formatDuration(wtimeUsed, sb);
17539                    sb.append(" (");
17540                    sb.append((wtimeUsed*100)/realtimeSince);
17541                    sb.append("%)");
17542                    Slog.i(TAG, sb.toString());
17543                    sb.setLength(0);
17544                    sb.append("CPU for ");
17545                    app.toShortString(sb);
17546                    sb.append(": over ");
17547                    TimeUtils.formatDuration(uptimeSince, sb);
17548                    sb.append(" used ");
17549                    TimeUtils.formatDuration(cputimeUsed, sb);
17550                    sb.append(" (");
17551                    sb.append((cputimeUsed*100)/uptimeSince);
17552                    sb.append("%)");
17553                    Slog.i(TAG, sb.toString());
17554                }
17555                // If a process has held a wake lock for more
17556                // than 50% of the time during this period,
17557                // that sounds bad.  Kill!
17558                if (doWakeKills && realtimeSince > 0
17559                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17560                    synchronized (stats) {
17561                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17562                                realtimeSince, wtimeUsed);
17563                    }
17564                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17565                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17566                } else if (doCpuKills && uptimeSince > 0
17567                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17568                    synchronized (stats) {
17569                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17570                                uptimeSince, cputimeUsed);
17571                    }
17572                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17573                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17574                } else {
17575                    app.lastWakeTime = wtime;
17576                    app.lastCpuTime = app.curCpuTime;
17577                }
17578            }
17579        }
17580    }
17581
17582    private final boolean applyOomAdjLocked(ProcessRecord app,
17583            ProcessRecord TOP_APP, boolean doingAll, long now) {
17584        boolean success = true;
17585
17586        if (app.curRawAdj != app.setRawAdj) {
17587            app.setRawAdj = app.curRawAdj;
17588        }
17589
17590        int changes = 0;
17591
17592        if (app.curAdj != app.setAdj) {
17593            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17594            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17595                TAG, "Set " + app.pid + " " + app.processName +
17596                " adj " + app.curAdj + ": " + app.adjType);
17597            app.setAdj = app.curAdj;
17598        }
17599
17600        if (app.setSchedGroup != app.curSchedGroup) {
17601            app.setSchedGroup = app.curSchedGroup;
17602            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17603                    "Setting process group of " + app.processName
17604                    + " to " + app.curSchedGroup);
17605            if (app.waitingToKill != null &&
17606                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17607                app.kill(app.waitingToKill, true);
17608                success = false;
17609            } else {
17610                if (true) {
17611                    long oldId = Binder.clearCallingIdentity();
17612                    try {
17613                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17614                    } catch (Exception e) {
17615                        Slog.w(TAG, "Failed setting process group of " + app.pid
17616                                + " to " + app.curSchedGroup);
17617                        e.printStackTrace();
17618                    } finally {
17619                        Binder.restoreCallingIdentity(oldId);
17620                    }
17621                } else {
17622                    if (app.thread != null) {
17623                        try {
17624                            app.thread.setSchedulingGroup(app.curSchedGroup);
17625                        } catch (RemoteException e) {
17626                        }
17627                    }
17628                }
17629                Process.setSwappiness(app.pid,
17630                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17631            }
17632        }
17633        if (app.repForegroundActivities != app.foregroundActivities) {
17634            app.repForegroundActivities = app.foregroundActivities;
17635            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17636        }
17637        if (app.repProcState != app.curProcState) {
17638            app.repProcState = app.curProcState;
17639            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17640            if (app.thread != null) {
17641                try {
17642                    if (false) {
17643                        //RuntimeException h = new RuntimeException("here");
17644                        Slog.i(TAG, "Sending new process state " + app.repProcState
17645                                + " to " + app /*, h*/);
17646                    }
17647                    app.thread.setProcessState(app.repProcState);
17648                } catch (RemoteException e) {
17649                }
17650            }
17651        }
17652        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17653                app.setProcState)) {
17654            app.lastStateTime = now;
17655            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17656                    isSleeping(), now);
17657            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17658                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17659                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17660                    + (app.nextPssTime-now) + ": " + app);
17661        } else {
17662            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17663                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17664                requestPssLocked(app, app.setProcState);
17665                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17666                        isSleeping(), now);
17667            } else if (false && DEBUG_PSS) {
17668                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17669            }
17670        }
17671        if (app.setProcState != app.curProcState) {
17672            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17673                    "Proc state change of " + app.processName
17674                    + " to " + app.curProcState);
17675            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17676            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17677            if (setImportant && !curImportant) {
17678                // This app is no longer something we consider important enough to allow to
17679                // use arbitrary amounts of battery power.  Note
17680                // its current wake lock time to later know to kill it if
17681                // it is not behaving well.
17682                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17683                synchronized (stats) {
17684                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17685                            app.pid, SystemClock.elapsedRealtime());
17686                }
17687                app.lastCpuTime = app.curCpuTime;
17688
17689            }
17690            app.setProcState = app.curProcState;
17691            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17692                app.notCachedSinceIdle = false;
17693            }
17694            if (!doingAll) {
17695                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17696            } else {
17697                app.procStateChanged = true;
17698            }
17699        }
17700
17701        if (changes != 0) {
17702            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17703            int i = mPendingProcessChanges.size()-1;
17704            ProcessChangeItem item = null;
17705            while (i >= 0) {
17706                item = mPendingProcessChanges.get(i);
17707                if (item.pid == app.pid) {
17708                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17709                    break;
17710                }
17711                i--;
17712            }
17713            if (i < 0) {
17714                // No existing item in pending changes; need a new one.
17715                final int NA = mAvailProcessChanges.size();
17716                if (NA > 0) {
17717                    item = mAvailProcessChanges.remove(NA-1);
17718                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17719                } else {
17720                    item = new ProcessChangeItem();
17721                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17722                }
17723                item.changes = 0;
17724                item.pid = app.pid;
17725                item.uid = app.info.uid;
17726                if (mPendingProcessChanges.size() == 0) {
17727                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17728                            "*** Enqueueing dispatch processes changed!");
17729                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17730                }
17731                mPendingProcessChanges.add(item);
17732            }
17733            item.changes |= changes;
17734            item.processState = app.repProcState;
17735            item.foregroundActivities = app.repForegroundActivities;
17736            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17737                    + Integer.toHexString(System.identityHashCode(item))
17738                    + " " + app.toShortString() + ": changes=" + item.changes
17739                    + " procState=" + item.processState
17740                    + " foreground=" + item.foregroundActivities
17741                    + " type=" + app.adjType + " source=" + app.adjSource
17742                    + " target=" + app.adjTarget);
17743        }
17744
17745        return success;
17746    }
17747
17748    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17749        if (proc.thread != null) {
17750            if (proc.baseProcessTracker != null) {
17751                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17752            }
17753            if (proc.repProcState >= 0) {
17754                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17755                        proc.repProcState);
17756            }
17757        }
17758    }
17759
17760    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17761            ProcessRecord TOP_APP, boolean doingAll, long now) {
17762        if (app.thread == null) {
17763            return false;
17764        }
17765
17766        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17767
17768        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17769    }
17770
17771    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17772            boolean oomAdj) {
17773        if (isForeground != proc.foregroundServices) {
17774            proc.foregroundServices = isForeground;
17775            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17776                    proc.info.uid);
17777            if (isForeground) {
17778                if (curProcs == null) {
17779                    curProcs = new ArrayList<ProcessRecord>();
17780                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17781                }
17782                if (!curProcs.contains(proc)) {
17783                    curProcs.add(proc);
17784                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17785                            proc.info.packageName, proc.info.uid);
17786                }
17787            } else {
17788                if (curProcs != null) {
17789                    if (curProcs.remove(proc)) {
17790                        mBatteryStatsService.noteEvent(
17791                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17792                                proc.info.packageName, proc.info.uid);
17793                        if (curProcs.size() <= 0) {
17794                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17795                        }
17796                    }
17797                }
17798            }
17799            if (oomAdj) {
17800                updateOomAdjLocked();
17801            }
17802        }
17803    }
17804
17805    private final ActivityRecord resumedAppLocked() {
17806        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17807        String pkg;
17808        int uid;
17809        if (act != null) {
17810            pkg = act.packageName;
17811            uid = act.info.applicationInfo.uid;
17812        } else {
17813            pkg = null;
17814            uid = -1;
17815        }
17816        // Has the UID or resumed package name changed?
17817        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17818                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17819            if (mCurResumedPackage != null) {
17820                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17821                        mCurResumedPackage, mCurResumedUid);
17822            }
17823            mCurResumedPackage = pkg;
17824            mCurResumedUid = uid;
17825            if (mCurResumedPackage != null) {
17826                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17827                        mCurResumedPackage, mCurResumedUid);
17828            }
17829        }
17830        return act;
17831    }
17832
17833    final boolean updateOomAdjLocked(ProcessRecord app) {
17834        final ActivityRecord TOP_ACT = resumedAppLocked();
17835        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17836        final boolean wasCached = app.cached;
17837
17838        mAdjSeq++;
17839
17840        // This is the desired cached adjusment we want to tell it to use.
17841        // If our app is currently cached, we know it, and that is it.  Otherwise,
17842        // we don't know it yet, and it needs to now be cached we will then
17843        // need to do a complete oom adj.
17844        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17845                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17846        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17847                SystemClock.uptimeMillis());
17848        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17849            // Changed to/from cached state, so apps after it in the LRU
17850            // list may also be changed.
17851            updateOomAdjLocked();
17852        }
17853        return success;
17854    }
17855
17856    final void updateOomAdjLocked() {
17857        final ActivityRecord TOP_ACT = resumedAppLocked();
17858        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17859        final long now = SystemClock.uptimeMillis();
17860        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17861        final int N = mLruProcesses.size();
17862
17863        if (false) {
17864            RuntimeException e = new RuntimeException();
17865            e.fillInStackTrace();
17866            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17867        }
17868
17869        mAdjSeq++;
17870        mNewNumServiceProcs = 0;
17871        mNewNumAServiceProcs = 0;
17872
17873        final int emptyProcessLimit;
17874        final int cachedProcessLimit;
17875        if (mProcessLimit <= 0) {
17876            emptyProcessLimit = cachedProcessLimit = 0;
17877        } else if (mProcessLimit == 1) {
17878            emptyProcessLimit = 1;
17879            cachedProcessLimit = 0;
17880        } else {
17881            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17882            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17883        }
17884
17885        // Let's determine how many processes we have running vs.
17886        // how many slots we have for background processes; we may want
17887        // to put multiple processes in a slot of there are enough of
17888        // them.
17889        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17890                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17891        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17892        if (numEmptyProcs > cachedProcessLimit) {
17893            // If there are more empty processes than our limit on cached
17894            // processes, then use the cached process limit for the factor.
17895            // This ensures that the really old empty processes get pushed
17896            // down to the bottom, so if we are running low on memory we will
17897            // have a better chance at keeping around more cached processes
17898            // instead of a gazillion empty processes.
17899            numEmptyProcs = cachedProcessLimit;
17900        }
17901        int emptyFactor = numEmptyProcs/numSlots;
17902        if (emptyFactor < 1) emptyFactor = 1;
17903        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17904        if (cachedFactor < 1) cachedFactor = 1;
17905        int stepCached = 0;
17906        int stepEmpty = 0;
17907        int numCached = 0;
17908        int numEmpty = 0;
17909        int numTrimming = 0;
17910
17911        mNumNonCachedProcs = 0;
17912        mNumCachedHiddenProcs = 0;
17913
17914        // First update the OOM adjustment for each of the
17915        // application processes based on their current state.
17916        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17917        int nextCachedAdj = curCachedAdj+1;
17918        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17919        int nextEmptyAdj = curEmptyAdj+2;
17920        for (int i=N-1; i>=0; i--) {
17921            ProcessRecord app = mLruProcesses.get(i);
17922            if (!app.killedByAm && app.thread != null) {
17923                app.procStateChanged = false;
17924                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17925
17926                // If we haven't yet assigned the final cached adj
17927                // to the process, do that now.
17928                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17929                    switch (app.curProcState) {
17930                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17931                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17932                            // This process is a cached process holding activities...
17933                            // assign it the next cached value for that type, and then
17934                            // step that cached level.
17935                            app.curRawAdj = curCachedAdj;
17936                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17937                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17938                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17939                                    + ")");
17940                            if (curCachedAdj != nextCachedAdj) {
17941                                stepCached++;
17942                                if (stepCached >= cachedFactor) {
17943                                    stepCached = 0;
17944                                    curCachedAdj = nextCachedAdj;
17945                                    nextCachedAdj += 2;
17946                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17947                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17948                                    }
17949                                }
17950                            }
17951                            break;
17952                        default:
17953                            // For everything else, assign next empty cached process
17954                            // level and bump that up.  Note that this means that
17955                            // long-running services that have dropped down to the
17956                            // cached level will be treated as empty (since their process
17957                            // state is still as a service), which is what we want.
17958                            app.curRawAdj = curEmptyAdj;
17959                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17960                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17961                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17962                                    + ")");
17963                            if (curEmptyAdj != nextEmptyAdj) {
17964                                stepEmpty++;
17965                                if (stepEmpty >= emptyFactor) {
17966                                    stepEmpty = 0;
17967                                    curEmptyAdj = nextEmptyAdj;
17968                                    nextEmptyAdj += 2;
17969                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17970                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17971                                    }
17972                                }
17973                            }
17974                            break;
17975                    }
17976                }
17977
17978                applyOomAdjLocked(app, TOP_APP, true, now);
17979
17980                // Count the number of process types.
17981                switch (app.curProcState) {
17982                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17983                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17984                        mNumCachedHiddenProcs++;
17985                        numCached++;
17986                        if (numCached > cachedProcessLimit) {
17987                            app.kill("cached #" + numCached, true);
17988                        }
17989                        break;
17990                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17991                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17992                                && app.lastActivityTime < oldTime) {
17993                            app.kill("empty for "
17994                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17995                                    / 1000) + "s", true);
17996                        } else {
17997                            numEmpty++;
17998                            if (numEmpty > emptyProcessLimit) {
17999                                app.kill("empty #" + numEmpty, true);
18000                            }
18001                        }
18002                        break;
18003                    default:
18004                        mNumNonCachedProcs++;
18005                        break;
18006                }
18007
18008                if (app.isolated && app.services.size() <= 0) {
18009                    // If this is an isolated process, and there are no
18010                    // services running in it, then the process is no longer
18011                    // needed.  We agressively kill these because we can by
18012                    // definition not re-use the same process again, and it is
18013                    // good to avoid having whatever code was running in them
18014                    // left sitting around after no longer needed.
18015                    app.kill("isolated not needed", true);
18016                }
18017
18018                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18019                        && !app.killedByAm) {
18020                    numTrimming++;
18021                }
18022            }
18023        }
18024
18025        mNumServiceProcs = mNewNumServiceProcs;
18026
18027        // Now determine the memory trimming level of background processes.
18028        // Unfortunately we need to start at the back of the list to do this
18029        // properly.  We only do this if the number of background apps we
18030        // are managing to keep around is less than half the maximum we desire;
18031        // if we are keeping a good number around, we'll let them use whatever
18032        // memory they want.
18033        final int numCachedAndEmpty = numCached + numEmpty;
18034        int memFactor;
18035        if (numCached <= ProcessList.TRIM_CACHED_APPS
18036                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18037            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18038                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18039            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18040                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18041            } else {
18042                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18043            }
18044        } else {
18045            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18046        }
18047        // We always allow the memory level to go up (better).  We only allow it to go
18048        // down if we are in a state where that is allowed, *and* the total number of processes
18049        // has gone down since last time.
18050        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18051                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18052                + " last=" + mLastNumProcesses);
18053        if (memFactor > mLastMemoryLevel) {
18054            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18055                memFactor = mLastMemoryLevel;
18056                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18057            }
18058        }
18059        mLastMemoryLevel = memFactor;
18060        mLastNumProcesses = mLruProcesses.size();
18061        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18062        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18063        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18064            if (mLowRamStartTime == 0) {
18065                mLowRamStartTime = now;
18066            }
18067            int step = 0;
18068            int fgTrimLevel;
18069            switch (memFactor) {
18070                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18071                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18072                    break;
18073                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18074                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18075                    break;
18076                default:
18077                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18078                    break;
18079            }
18080            int factor = numTrimming/3;
18081            int minFactor = 2;
18082            if (mHomeProcess != null) minFactor++;
18083            if (mPreviousProcess != null) minFactor++;
18084            if (factor < minFactor) factor = minFactor;
18085            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18086            for (int i=N-1; i>=0; i--) {
18087                ProcessRecord app = mLruProcesses.get(i);
18088                if (allChanged || app.procStateChanged) {
18089                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18090                    app.procStateChanged = false;
18091                }
18092                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18093                        && !app.killedByAm) {
18094                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18095                        try {
18096                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18097                                    "Trimming memory of " + app.processName
18098                                    + " to " + curLevel);
18099                            app.thread.scheduleTrimMemory(curLevel);
18100                        } catch (RemoteException e) {
18101                        }
18102                        if (false) {
18103                            // For now we won't do this; our memory trimming seems
18104                            // to be good enough at this point that destroying
18105                            // activities causes more harm than good.
18106                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18107                                    && app != mHomeProcess && app != mPreviousProcess) {
18108                                // Need to do this on its own message because the stack may not
18109                                // be in a consistent state at this point.
18110                                // For these apps we will also finish their activities
18111                                // to help them free memory.
18112                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18113                            }
18114                        }
18115                    }
18116                    app.trimMemoryLevel = curLevel;
18117                    step++;
18118                    if (step >= factor) {
18119                        step = 0;
18120                        switch (curLevel) {
18121                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18122                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18123                                break;
18124                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18125                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18126                                break;
18127                        }
18128                    }
18129                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18130                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18131                            && app.thread != null) {
18132                        try {
18133                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18134                                    "Trimming memory of heavy-weight " + app.processName
18135                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18136                            app.thread.scheduleTrimMemory(
18137                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18138                        } catch (RemoteException e) {
18139                        }
18140                    }
18141                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18142                } else {
18143                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18144                            || app.systemNoUi) && app.pendingUiClean) {
18145                        // If this application is now in the background and it
18146                        // had done UI, then give it the special trim level to
18147                        // have it free UI resources.
18148                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18149                        if (app.trimMemoryLevel < level && app.thread != null) {
18150                            try {
18151                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18152                                        "Trimming memory of bg-ui " + app.processName
18153                                        + " to " + level);
18154                                app.thread.scheduleTrimMemory(level);
18155                            } catch (RemoteException e) {
18156                            }
18157                        }
18158                        app.pendingUiClean = false;
18159                    }
18160                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18161                        try {
18162                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18163                                    "Trimming memory of fg " + app.processName
18164                                    + " to " + fgTrimLevel);
18165                            app.thread.scheduleTrimMemory(fgTrimLevel);
18166                        } catch (RemoteException e) {
18167                        }
18168                    }
18169                    app.trimMemoryLevel = fgTrimLevel;
18170                }
18171            }
18172        } else {
18173            if (mLowRamStartTime != 0) {
18174                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18175                mLowRamStartTime = 0;
18176            }
18177            for (int i=N-1; i>=0; i--) {
18178                ProcessRecord app = mLruProcesses.get(i);
18179                if (allChanged || app.procStateChanged) {
18180                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18181                    app.procStateChanged = false;
18182                }
18183                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18184                        || app.systemNoUi) && app.pendingUiClean) {
18185                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18186                            && app.thread != null) {
18187                        try {
18188                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18189                                    "Trimming memory of ui hidden " + app.processName
18190                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18191                            app.thread.scheduleTrimMemory(
18192                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18193                        } catch (RemoteException e) {
18194                        }
18195                    }
18196                    app.pendingUiClean = false;
18197                }
18198                app.trimMemoryLevel = 0;
18199            }
18200        }
18201
18202        if (mAlwaysFinishActivities) {
18203            // Need to do this on its own message because the stack may not
18204            // be in a consistent state at this point.
18205            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18206        }
18207
18208        if (allChanged) {
18209            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18210        }
18211
18212        if (mProcessStats.shouldWriteNowLocked(now)) {
18213            mHandler.post(new Runnable() {
18214                @Override public void run() {
18215                    synchronized (ActivityManagerService.this) {
18216                        mProcessStats.writeStateAsyncLocked();
18217                    }
18218                }
18219            });
18220        }
18221
18222        if (DEBUG_OOM_ADJ) {
18223            if (false) {
18224                RuntimeException here = new RuntimeException("here");
18225                here.fillInStackTrace();
18226                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18227            } else {
18228                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18229            }
18230        }
18231    }
18232
18233    final void trimApplications() {
18234        synchronized (this) {
18235            int i;
18236
18237            // First remove any unused application processes whose package
18238            // has been removed.
18239            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18240                final ProcessRecord app = mRemovedProcesses.get(i);
18241                if (app.activities.size() == 0
18242                        && app.curReceiver == null && app.services.size() == 0) {
18243                    Slog.i(
18244                        TAG, "Exiting empty application process "
18245                        + app.processName + " ("
18246                        + (app.thread != null ? app.thread.asBinder() : null)
18247                        + ")\n");
18248                    if (app.pid > 0 && app.pid != MY_PID) {
18249                        app.kill("empty", false);
18250                    } else {
18251                        try {
18252                            app.thread.scheduleExit();
18253                        } catch (Exception e) {
18254                            // Ignore exceptions.
18255                        }
18256                    }
18257                    cleanUpApplicationRecordLocked(app, false, true, -1);
18258                    mRemovedProcesses.remove(i);
18259
18260                    if (app.persistent) {
18261                        addAppLocked(app.info, false, null /* ABI override */);
18262                    }
18263                }
18264            }
18265
18266            // Now update the oom adj for all processes.
18267            updateOomAdjLocked();
18268        }
18269    }
18270
18271    /** This method sends the specified signal to each of the persistent apps */
18272    public void signalPersistentProcesses(int sig) throws RemoteException {
18273        if (sig != Process.SIGNAL_USR1) {
18274            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18275        }
18276
18277        synchronized (this) {
18278            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18279                    != PackageManager.PERMISSION_GRANTED) {
18280                throw new SecurityException("Requires permission "
18281                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18282            }
18283
18284            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18285                ProcessRecord r = mLruProcesses.get(i);
18286                if (r.thread != null && r.persistent) {
18287                    Process.sendSignal(r.pid, sig);
18288                }
18289            }
18290        }
18291    }
18292
18293    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18294        if (proc == null || proc == mProfileProc) {
18295            proc = mProfileProc;
18296            profileType = mProfileType;
18297            clearProfilerLocked();
18298        }
18299        if (proc == null) {
18300            return;
18301        }
18302        try {
18303            proc.thread.profilerControl(false, null, profileType);
18304        } catch (RemoteException e) {
18305            throw new IllegalStateException("Process disappeared");
18306        }
18307    }
18308
18309    private void clearProfilerLocked() {
18310        if (mProfileFd != null) {
18311            try {
18312                mProfileFd.close();
18313            } catch (IOException e) {
18314            }
18315        }
18316        mProfileApp = null;
18317        mProfileProc = null;
18318        mProfileFile = null;
18319        mProfileType = 0;
18320        mAutoStopProfiler = false;
18321        mSamplingInterval = 0;
18322    }
18323
18324    public boolean profileControl(String process, int userId, boolean start,
18325            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18326
18327        try {
18328            synchronized (this) {
18329                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18330                // its own permission.
18331                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18332                        != PackageManager.PERMISSION_GRANTED) {
18333                    throw new SecurityException("Requires permission "
18334                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18335                }
18336
18337                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18338                    throw new IllegalArgumentException("null profile info or fd");
18339                }
18340
18341                ProcessRecord proc = null;
18342                if (process != null) {
18343                    proc = findProcessLocked(process, userId, "profileControl");
18344                }
18345
18346                if (start && (proc == null || proc.thread == null)) {
18347                    throw new IllegalArgumentException("Unknown process: " + process);
18348                }
18349
18350                if (start) {
18351                    stopProfilerLocked(null, 0);
18352                    setProfileApp(proc.info, proc.processName, profilerInfo);
18353                    mProfileProc = proc;
18354                    mProfileType = profileType;
18355                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18356                    try {
18357                        fd = fd.dup();
18358                    } catch (IOException e) {
18359                        fd = null;
18360                    }
18361                    profilerInfo.profileFd = fd;
18362                    proc.thread.profilerControl(start, profilerInfo, profileType);
18363                    fd = null;
18364                    mProfileFd = null;
18365                } else {
18366                    stopProfilerLocked(proc, profileType);
18367                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18368                        try {
18369                            profilerInfo.profileFd.close();
18370                        } catch (IOException e) {
18371                        }
18372                    }
18373                }
18374
18375                return true;
18376            }
18377        } catch (RemoteException e) {
18378            throw new IllegalStateException("Process disappeared");
18379        } finally {
18380            if (profilerInfo != null && profilerInfo.profileFd != null) {
18381                try {
18382                    profilerInfo.profileFd.close();
18383                } catch (IOException e) {
18384                }
18385            }
18386        }
18387    }
18388
18389    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18390        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18391                userId, true, ALLOW_FULL_ONLY, callName, null);
18392        ProcessRecord proc = null;
18393        try {
18394            int pid = Integer.parseInt(process);
18395            synchronized (mPidsSelfLocked) {
18396                proc = mPidsSelfLocked.get(pid);
18397            }
18398        } catch (NumberFormatException e) {
18399        }
18400
18401        if (proc == null) {
18402            ArrayMap<String, SparseArray<ProcessRecord>> all
18403                    = mProcessNames.getMap();
18404            SparseArray<ProcessRecord> procs = all.get(process);
18405            if (procs != null && procs.size() > 0) {
18406                proc = procs.valueAt(0);
18407                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18408                    for (int i=1; i<procs.size(); i++) {
18409                        ProcessRecord thisProc = procs.valueAt(i);
18410                        if (thisProc.userId == userId) {
18411                            proc = thisProc;
18412                            break;
18413                        }
18414                    }
18415                }
18416            }
18417        }
18418
18419        return proc;
18420    }
18421
18422    public boolean dumpHeap(String process, int userId, boolean managed,
18423            String path, ParcelFileDescriptor fd) throws RemoteException {
18424
18425        try {
18426            synchronized (this) {
18427                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18428                // its own permission (same as profileControl).
18429                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18430                        != PackageManager.PERMISSION_GRANTED) {
18431                    throw new SecurityException("Requires permission "
18432                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18433                }
18434
18435                if (fd == null) {
18436                    throw new IllegalArgumentException("null fd");
18437                }
18438
18439                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18440                if (proc == null || proc.thread == null) {
18441                    throw new IllegalArgumentException("Unknown process: " + process);
18442                }
18443
18444                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18445                if (!isDebuggable) {
18446                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18447                        throw new SecurityException("Process not debuggable: " + proc);
18448                    }
18449                }
18450
18451                proc.thread.dumpHeap(managed, path, fd);
18452                fd = null;
18453                return true;
18454            }
18455        } catch (RemoteException e) {
18456            throw new IllegalStateException("Process disappeared");
18457        } finally {
18458            if (fd != null) {
18459                try {
18460                    fd.close();
18461                } catch (IOException e) {
18462                }
18463            }
18464        }
18465    }
18466
18467    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18468    public void monitor() {
18469        synchronized (this) { }
18470    }
18471
18472    void onCoreSettingsChange(Bundle settings) {
18473        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18474            ProcessRecord processRecord = mLruProcesses.get(i);
18475            try {
18476                if (processRecord.thread != null) {
18477                    processRecord.thread.setCoreSettings(settings);
18478                }
18479            } catch (RemoteException re) {
18480                /* ignore */
18481            }
18482        }
18483    }
18484
18485    // Multi-user methods
18486
18487    /**
18488     * Start user, if its not already running, but don't bring it to foreground.
18489     */
18490    @Override
18491    public boolean startUserInBackground(final int userId) {
18492        return startUser(userId, /* foreground */ false);
18493    }
18494
18495    /**
18496     * Start user, if its not already running, and bring it to foreground.
18497     */
18498    boolean startUserInForeground(final int userId, Dialog dlg) {
18499        boolean result = startUser(userId, /* foreground */ true);
18500        dlg.dismiss();
18501        return result;
18502    }
18503
18504    /**
18505     * Refreshes the list of users related to the current user when either a
18506     * user switch happens or when a new related user is started in the
18507     * background.
18508     */
18509    private void updateCurrentProfileIdsLocked() {
18510        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18511                mCurrentUserId, false /* enabledOnly */);
18512        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18513        for (int i = 0; i < currentProfileIds.length; i++) {
18514            currentProfileIds[i] = profiles.get(i).id;
18515        }
18516        mCurrentProfileIds = currentProfileIds;
18517
18518        synchronized (mUserProfileGroupIdsSelfLocked) {
18519            mUserProfileGroupIdsSelfLocked.clear();
18520            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18521            for (int i = 0; i < users.size(); i++) {
18522                UserInfo user = users.get(i);
18523                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18524                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18525                }
18526            }
18527        }
18528    }
18529
18530    private Set getProfileIdsLocked(int userId) {
18531        Set userIds = new HashSet<Integer>();
18532        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18533                userId, false /* enabledOnly */);
18534        for (UserInfo user : profiles) {
18535            userIds.add(Integer.valueOf(user.id));
18536        }
18537        return userIds;
18538    }
18539
18540    @Override
18541    public boolean switchUser(final int userId) {
18542        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18543        String userName;
18544        synchronized (this) {
18545            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18546            if (userInfo == null) {
18547                Slog.w(TAG, "No user info for user #" + userId);
18548                return false;
18549            }
18550            if (userInfo.isManagedProfile()) {
18551                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18552                return false;
18553            }
18554            userName = userInfo.name;
18555            mTargetUserId = userId;
18556        }
18557        mHandler.removeMessages(START_USER_SWITCH_MSG);
18558        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18559        return true;
18560    }
18561
18562    private void showUserSwitchDialog(int userId, String userName) {
18563        // The dialog will show and then initiate the user switch by calling startUserInForeground
18564        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18565                true /* above system */);
18566        d.show();
18567    }
18568
18569    private boolean startUser(final int userId, final boolean foreground) {
18570        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18571                != PackageManager.PERMISSION_GRANTED) {
18572            String msg = "Permission Denial: switchUser() from pid="
18573                    + Binder.getCallingPid()
18574                    + ", uid=" + Binder.getCallingUid()
18575                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18576            Slog.w(TAG, msg);
18577            throw new SecurityException(msg);
18578        }
18579
18580        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18581
18582        final long ident = Binder.clearCallingIdentity();
18583        try {
18584            synchronized (this) {
18585                final int oldUserId = mCurrentUserId;
18586                if (oldUserId == userId) {
18587                    return true;
18588                }
18589
18590                mStackSupervisor.setLockTaskModeLocked(null, false);
18591
18592                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18593                if (userInfo == null) {
18594                    Slog.w(TAG, "No user info for user #" + userId);
18595                    return false;
18596                }
18597                if (foreground && userInfo.isManagedProfile()) {
18598                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18599                    return false;
18600                }
18601
18602                if (foreground) {
18603                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18604                            R.anim.screen_user_enter);
18605                }
18606
18607                boolean needStart = false;
18608
18609                // If the user we are switching to is not currently started, then
18610                // we need to start it now.
18611                if (mStartedUsers.get(userId) == null) {
18612                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18613                    updateStartedUserArrayLocked();
18614                    needStart = true;
18615                }
18616
18617                final Integer userIdInt = Integer.valueOf(userId);
18618                mUserLru.remove(userIdInt);
18619                mUserLru.add(userIdInt);
18620
18621                if (foreground) {
18622                    mCurrentUserId = userId;
18623                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18624                    updateCurrentProfileIdsLocked();
18625                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18626                    // Once the internal notion of the active user has switched, we lock the device
18627                    // with the option to show the user switcher on the keyguard.
18628                    mWindowManager.lockNow(null);
18629                } else {
18630                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18631                    updateCurrentProfileIdsLocked();
18632                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18633                    mUserLru.remove(currentUserIdInt);
18634                    mUserLru.add(currentUserIdInt);
18635                }
18636
18637                final UserStartedState uss = mStartedUsers.get(userId);
18638
18639                // Make sure user is in the started state.  If it is currently
18640                // stopping, we need to knock that off.
18641                if (uss.mState == UserStartedState.STATE_STOPPING) {
18642                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18643                    // so we can just fairly silently bring the user back from
18644                    // the almost-dead.
18645                    uss.mState = UserStartedState.STATE_RUNNING;
18646                    updateStartedUserArrayLocked();
18647                    needStart = true;
18648                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18649                    // This means ACTION_SHUTDOWN has been sent, so we will
18650                    // need to treat this as a new boot of the user.
18651                    uss.mState = UserStartedState.STATE_BOOTING;
18652                    updateStartedUserArrayLocked();
18653                    needStart = true;
18654                }
18655
18656                if (uss.mState == UserStartedState.STATE_BOOTING) {
18657                    // Booting up a new user, need to tell system services about it.
18658                    // Note that this is on the same handler as scheduling of broadcasts,
18659                    // which is important because it needs to go first.
18660                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18661                }
18662
18663                if (foreground) {
18664                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18665                            oldUserId));
18666                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18667                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18668                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18669                            oldUserId, userId, uss));
18670                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18671                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18672                }
18673
18674                if (needStart) {
18675                    // Send USER_STARTED broadcast
18676                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18677                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18678                            | Intent.FLAG_RECEIVER_FOREGROUND);
18679                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18680                    broadcastIntentLocked(null, null, intent,
18681                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18682                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18683                }
18684
18685                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18686                    if (userId != UserHandle.USER_OWNER) {
18687                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18688                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18689                        broadcastIntentLocked(null, null, intent, null,
18690                                new IIntentReceiver.Stub() {
18691                                    public void performReceive(Intent intent, int resultCode,
18692                                            String data, Bundle extras, boolean ordered,
18693                                            boolean sticky, int sendingUser) {
18694                                        onUserInitialized(uss, foreground, oldUserId, userId);
18695                                    }
18696                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18697                                true, false, MY_PID, Process.SYSTEM_UID,
18698                                userId);
18699                        uss.initializing = true;
18700                    } else {
18701                        getUserManagerLocked().makeInitialized(userInfo.id);
18702                    }
18703                }
18704
18705                if (foreground) {
18706                    if (!uss.initializing) {
18707                        moveUserToForeground(uss, oldUserId, userId);
18708                    }
18709                } else {
18710                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18711                }
18712
18713                if (needStart) {
18714                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18715                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18716                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18717                    broadcastIntentLocked(null, null, intent,
18718                            null, new IIntentReceiver.Stub() {
18719                                @Override
18720                                public void performReceive(Intent intent, int resultCode, String data,
18721                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18722                                        throws RemoteException {
18723                                }
18724                            }, 0, null, null,
18725                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18726                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18727                }
18728            }
18729        } finally {
18730            Binder.restoreCallingIdentity(ident);
18731        }
18732
18733        return true;
18734    }
18735
18736    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18737        long ident = Binder.clearCallingIdentity();
18738        try {
18739            Intent intent;
18740            if (oldUserId >= 0) {
18741                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18742                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18743                int count = profiles.size();
18744                for (int i = 0; i < count; i++) {
18745                    int profileUserId = profiles.get(i).id;
18746                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18747                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18748                            | Intent.FLAG_RECEIVER_FOREGROUND);
18749                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18750                    broadcastIntentLocked(null, null, intent,
18751                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18752                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18753                }
18754            }
18755            if (newUserId >= 0) {
18756                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18757                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18758                int count = profiles.size();
18759                for (int i = 0; i < count; i++) {
18760                    int profileUserId = profiles.get(i).id;
18761                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18762                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18763                            | Intent.FLAG_RECEIVER_FOREGROUND);
18764                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18765                    broadcastIntentLocked(null, null, intent,
18766                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18767                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18768                }
18769                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18770                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18771                        | Intent.FLAG_RECEIVER_FOREGROUND);
18772                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18773                broadcastIntentLocked(null, null, intent,
18774                        null, null, 0, null, null,
18775                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18776                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18777            }
18778        } finally {
18779            Binder.restoreCallingIdentity(ident);
18780        }
18781    }
18782
18783    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18784            final int newUserId) {
18785        final int N = mUserSwitchObservers.beginBroadcast();
18786        if (N > 0) {
18787            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18788                int mCount = 0;
18789                @Override
18790                public void sendResult(Bundle data) throws RemoteException {
18791                    synchronized (ActivityManagerService.this) {
18792                        if (mCurUserSwitchCallback == this) {
18793                            mCount++;
18794                            if (mCount == N) {
18795                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18796                            }
18797                        }
18798                    }
18799                }
18800            };
18801            synchronized (this) {
18802                uss.switching = true;
18803                mCurUserSwitchCallback = callback;
18804            }
18805            for (int i=0; i<N; i++) {
18806                try {
18807                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18808                            newUserId, callback);
18809                } catch (RemoteException e) {
18810                }
18811            }
18812        } else {
18813            synchronized (this) {
18814                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18815            }
18816        }
18817        mUserSwitchObservers.finishBroadcast();
18818    }
18819
18820    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18821        synchronized (this) {
18822            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18823            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18824        }
18825    }
18826
18827    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18828        mCurUserSwitchCallback = null;
18829        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18830        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18831                oldUserId, newUserId, uss));
18832    }
18833
18834    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18835        synchronized (this) {
18836            if (foreground) {
18837                moveUserToForeground(uss, oldUserId, newUserId);
18838            }
18839        }
18840
18841        completeSwitchAndInitalize(uss, newUserId, true, false);
18842    }
18843
18844    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18845        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18846        if (homeInFront) {
18847            startHomeActivityLocked(newUserId);
18848        } else {
18849            mStackSupervisor.resumeTopActivitiesLocked();
18850        }
18851        EventLogTags.writeAmSwitchUser(newUserId);
18852        getUserManagerLocked().userForeground(newUserId);
18853        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18854    }
18855
18856    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18857        completeSwitchAndInitalize(uss, newUserId, false, true);
18858    }
18859
18860    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18861            boolean clearInitializing, boolean clearSwitching) {
18862        boolean unfrozen = false;
18863        synchronized (this) {
18864            if (clearInitializing) {
18865                uss.initializing = false;
18866                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18867            }
18868            if (clearSwitching) {
18869                uss.switching = false;
18870            }
18871            if (!uss.switching && !uss.initializing) {
18872                mWindowManager.stopFreezingScreen();
18873                unfrozen = true;
18874            }
18875        }
18876        if (unfrozen) {
18877            final int N = mUserSwitchObservers.beginBroadcast();
18878            for (int i=0; i<N; i++) {
18879                try {
18880                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18881                } catch (RemoteException e) {
18882                }
18883            }
18884            mUserSwitchObservers.finishBroadcast();
18885        }
18886    }
18887
18888    void scheduleStartProfilesLocked() {
18889        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18890            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18891                    DateUtils.SECOND_IN_MILLIS);
18892        }
18893    }
18894
18895    void startProfilesLocked() {
18896        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18897        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18898                mCurrentUserId, false /* enabledOnly */);
18899        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18900        for (UserInfo user : profiles) {
18901            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18902                    && user.id != mCurrentUserId) {
18903                toStart.add(user);
18904            }
18905        }
18906        final int n = toStart.size();
18907        int i = 0;
18908        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18909            startUserInBackground(toStart.get(i).id);
18910        }
18911        if (i < n) {
18912            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18913        }
18914    }
18915
18916    void finishUserBoot(UserStartedState uss) {
18917        synchronized (this) {
18918            if (uss.mState == UserStartedState.STATE_BOOTING
18919                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18920                uss.mState = UserStartedState.STATE_RUNNING;
18921                final int userId = uss.mHandle.getIdentifier();
18922                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18923                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18924                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18925                broadcastIntentLocked(null, null, intent,
18926                        null, null, 0, null, null,
18927                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18928                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18929            }
18930        }
18931    }
18932
18933    void finishUserSwitch(UserStartedState uss) {
18934        synchronized (this) {
18935            finishUserBoot(uss);
18936
18937            startProfilesLocked();
18938
18939            int num = mUserLru.size();
18940            int i = 0;
18941            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18942                Integer oldUserId = mUserLru.get(i);
18943                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18944                if (oldUss == null) {
18945                    // Shouldn't happen, but be sane if it does.
18946                    mUserLru.remove(i);
18947                    num--;
18948                    continue;
18949                }
18950                if (oldUss.mState == UserStartedState.STATE_STOPPING
18951                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18952                    // This user is already stopping, doesn't count.
18953                    num--;
18954                    i++;
18955                    continue;
18956                }
18957                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18958                    // Owner and current can't be stopped, but count as running.
18959                    i++;
18960                    continue;
18961                }
18962                // This is a user to be stopped.
18963                stopUserLocked(oldUserId, null);
18964                num--;
18965                i++;
18966            }
18967        }
18968    }
18969
18970    @Override
18971    public int stopUser(final int userId, final IStopUserCallback callback) {
18972        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18973                != PackageManager.PERMISSION_GRANTED) {
18974            String msg = "Permission Denial: switchUser() from pid="
18975                    + Binder.getCallingPid()
18976                    + ", uid=" + Binder.getCallingUid()
18977                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18978            Slog.w(TAG, msg);
18979            throw new SecurityException(msg);
18980        }
18981        if (userId <= 0) {
18982            throw new IllegalArgumentException("Can't stop primary user " + userId);
18983        }
18984        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18985        synchronized (this) {
18986            return stopUserLocked(userId, callback);
18987        }
18988    }
18989
18990    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18991        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18992        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18993            return ActivityManager.USER_OP_IS_CURRENT;
18994        }
18995
18996        final UserStartedState uss = mStartedUsers.get(userId);
18997        if (uss == null) {
18998            // User is not started, nothing to do...  but we do need to
18999            // callback if requested.
19000            if (callback != null) {
19001                mHandler.post(new Runnable() {
19002                    @Override
19003                    public void run() {
19004                        try {
19005                            callback.userStopped(userId);
19006                        } catch (RemoteException e) {
19007                        }
19008                    }
19009                });
19010            }
19011            return ActivityManager.USER_OP_SUCCESS;
19012        }
19013
19014        if (callback != null) {
19015            uss.mStopCallbacks.add(callback);
19016        }
19017
19018        if (uss.mState != UserStartedState.STATE_STOPPING
19019                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19020            uss.mState = UserStartedState.STATE_STOPPING;
19021            updateStartedUserArrayLocked();
19022
19023            long ident = Binder.clearCallingIdentity();
19024            try {
19025                // We are going to broadcast ACTION_USER_STOPPING and then
19026                // once that is done send a final ACTION_SHUTDOWN and then
19027                // stop the user.
19028                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19029                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19030                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19031                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19032                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19033                // This is the result receiver for the final shutdown broadcast.
19034                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19035                    @Override
19036                    public void performReceive(Intent intent, int resultCode, String data,
19037                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19038                        finishUserStop(uss);
19039                    }
19040                };
19041                // This is the result receiver for the initial stopping broadcast.
19042                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19043                    @Override
19044                    public void performReceive(Intent intent, int resultCode, String data,
19045                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19046                        // On to the next.
19047                        synchronized (ActivityManagerService.this) {
19048                            if (uss.mState != UserStartedState.STATE_STOPPING) {
19049                                // Whoops, we are being started back up.  Abort, abort!
19050                                return;
19051                            }
19052                            uss.mState = UserStartedState.STATE_SHUTDOWN;
19053                        }
19054                        mBatteryStatsService.noteEvent(
19055                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19056                                Integer.toString(userId), userId);
19057                        mSystemServiceManager.stopUser(userId);
19058                        broadcastIntentLocked(null, null, shutdownIntent,
19059                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19060                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19061                    }
19062                };
19063                // Kick things off.
19064                broadcastIntentLocked(null, null, stoppingIntent,
19065                        null, stoppingReceiver, 0, null, null,
19066                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19067                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19068            } finally {
19069                Binder.restoreCallingIdentity(ident);
19070            }
19071        }
19072
19073        return ActivityManager.USER_OP_SUCCESS;
19074    }
19075
19076    void finishUserStop(UserStartedState uss) {
19077        final int userId = uss.mHandle.getIdentifier();
19078        boolean stopped;
19079        ArrayList<IStopUserCallback> callbacks;
19080        synchronized (this) {
19081            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19082            if (mStartedUsers.get(userId) != uss) {
19083                stopped = false;
19084            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19085                stopped = false;
19086            } else {
19087                stopped = true;
19088                // User can no longer run.
19089                mStartedUsers.remove(userId);
19090                mUserLru.remove(Integer.valueOf(userId));
19091                updateStartedUserArrayLocked();
19092
19093                // Clean up all state and processes associated with the user.
19094                // Kill all the processes for the user.
19095                forceStopUserLocked(userId, "finish user");
19096            }
19097
19098            // Explicitly remove the old information in mRecentTasks.
19099            removeRecentTasksForUserLocked(userId);
19100        }
19101
19102        for (int i=0; i<callbacks.size(); i++) {
19103            try {
19104                if (stopped) callbacks.get(i).userStopped(userId);
19105                else callbacks.get(i).userStopAborted(userId);
19106            } catch (RemoteException e) {
19107            }
19108        }
19109
19110        if (stopped) {
19111            mSystemServiceManager.cleanupUser(userId);
19112            synchronized (this) {
19113                mStackSupervisor.removeUserLocked(userId);
19114            }
19115        }
19116    }
19117
19118    @Override
19119    public UserInfo getCurrentUser() {
19120        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19121                != PackageManager.PERMISSION_GRANTED) && (
19122                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19123                != PackageManager.PERMISSION_GRANTED)) {
19124            String msg = "Permission Denial: getCurrentUser() from pid="
19125                    + Binder.getCallingPid()
19126                    + ", uid=" + Binder.getCallingUid()
19127                    + " requires " + INTERACT_ACROSS_USERS;
19128            Slog.w(TAG, msg);
19129            throw new SecurityException(msg);
19130        }
19131        synchronized (this) {
19132            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19133            return getUserManagerLocked().getUserInfo(userId);
19134        }
19135    }
19136
19137    int getCurrentUserIdLocked() {
19138        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19139    }
19140
19141    @Override
19142    public boolean isUserRunning(int userId, boolean orStopped) {
19143        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19144                != PackageManager.PERMISSION_GRANTED) {
19145            String msg = "Permission Denial: isUserRunning() from pid="
19146                    + Binder.getCallingPid()
19147                    + ", uid=" + Binder.getCallingUid()
19148                    + " requires " + INTERACT_ACROSS_USERS;
19149            Slog.w(TAG, msg);
19150            throw new SecurityException(msg);
19151        }
19152        synchronized (this) {
19153            return isUserRunningLocked(userId, orStopped);
19154        }
19155    }
19156
19157    boolean isUserRunningLocked(int userId, boolean orStopped) {
19158        UserStartedState state = mStartedUsers.get(userId);
19159        if (state == null) {
19160            return false;
19161        }
19162        if (orStopped) {
19163            return true;
19164        }
19165        return state.mState != UserStartedState.STATE_STOPPING
19166                && state.mState != UserStartedState.STATE_SHUTDOWN;
19167    }
19168
19169    @Override
19170    public int[] getRunningUserIds() {
19171        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19172                != PackageManager.PERMISSION_GRANTED) {
19173            String msg = "Permission Denial: isUserRunning() from pid="
19174                    + Binder.getCallingPid()
19175                    + ", uid=" + Binder.getCallingUid()
19176                    + " requires " + INTERACT_ACROSS_USERS;
19177            Slog.w(TAG, msg);
19178            throw new SecurityException(msg);
19179        }
19180        synchronized (this) {
19181            return mStartedUserArray;
19182        }
19183    }
19184
19185    private void updateStartedUserArrayLocked() {
19186        int num = 0;
19187        for (int i=0; i<mStartedUsers.size();  i++) {
19188            UserStartedState uss = mStartedUsers.valueAt(i);
19189            // This list does not include stopping users.
19190            if (uss.mState != UserStartedState.STATE_STOPPING
19191                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19192                num++;
19193            }
19194        }
19195        mStartedUserArray = new int[num];
19196        num = 0;
19197        for (int i=0; i<mStartedUsers.size();  i++) {
19198            UserStartedState uss = mStartedUsers.valueAt(i);
19199            if (uss.mState != UserStartedState.STATE_STOPPING
19200                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19201                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19202                num++;
19203            }
19204        }
19205    }
19206
19207    @Override
19208    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19209        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19210                != PackageManager.PERMISSION_GRANTED) {
19211            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19212                    + Binder.getCallingPid()
19213                    + ", uid=" + Binder.getCallingUid()
19214                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19215            Slog.w(TAG, msg);
19216            throw new SecurityException(msg);
19217        }
19218
19219        mUserSwitchObservers.register(observer);
19220    }
19221
19222    @Override
19223    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19224        mUserSwitchObservers.unregister(observer);
19225    }
19226
19227    private boolean userExists(int userId) {
19228        if (userId == 0) {
19229            return true;
19230        }
19231        UserManagerService ums = getUserManagerLocked();
19232        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19233    }
19234
19235    int[] getUsersLocked() {
19236        UserManagerService ums = getUserManagerLocked();
19237        return ums != null ? ums.getUserIds() : new int[] { 0 };
19238    }
19239
19240    UserManagerService getUserManagerLocked() {
19241        if (mUserManager == null) {
19242            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19243            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19244        }
19245        return mUserManager;
19246    }
19247
19248    private int applyUserId(int uid, int userId) {
19249        return UserHandle.getUid(userId, uid);
19250    }
19251
19252    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19253        if (info == null) return null;
19254        ApplicationInfo newInfo = new ApplicationInfo(info);
19255        newInfo.uid = applyUserId(info.uid, userId);
19256        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19257                + info.packageName;
19258        return newInfo;
19259    }
19260
19261    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19262        if (aInfo == null
19263                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19264            return aInfo;
19265        }
19266
19267        ActivityInfo info = new ActivityInfo(aInfo);
19268        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19269        return info;
19270    }
19271
19272    private final class LocalService extends ActivityManagerInternal {
19273        @Override
19274        public void onWakefulnessChanged(int wakefulness) {
19275            ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19276        }
19277
19278        @Override
19279        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19280                String processName, String abiOverride, int uid, Runnable crashHandler) {
19281            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19282                    processName, abiOverride, uid, crashHandler);
19283        }
19284    }
19285
19286    /**
19287     * An implementation of IAppTask, that allows an app to manage its own tasks via
19288     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19289     * only the process that calls getAppTasks() can call the AppTask methods.
19290     */
19291    class AppTaskImpl extends IAppTask.Stub {
19292        private int mTaskId;
19293        private int mCallingUid;
19294
19295        public AppTaskImpl(int taskId, int callingUid) {
19296            mTaskId = taskId;
19297            mCallingUid = callingUid;
19298        }
19299
19300        private void checkCaller() {
19301            if (mCallingUid != Binder.getCallingUid()) {
19302                throw new SecurityException("Caller " + mCallingUid
19303                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19304            }
19305        }
19306
19307        @Override
19308        public void finishAndRemoveTask() {
19309            checkCaller();
19310
19311            synchronized (ActivityManagerService.this) {
19312                long origId = Binder.clearCallingIdentity();
19313                try {
19314                    if (!removeTaskByIdLocked(mTaskId, false)) {
19315                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19316                    }
19317                } finally {
19318                    Binder.restoreCallingIdentity(origId);
19319                }
19320            }
19321        }
19322
19323        @Override
19324        public ActivityManager.RecentTaskInfo getTaskInfo() {
19325            checkCaller();
19326
19327            synchronized (ActivityManagerService.this) {
19328                long origId = Binder.clearCallingIdentity();
19329                try {
19330                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19331                    if (tr == null) {
19332                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19333                    }
19334                    return createRecentTaskInfoFromTaskRecord(tr);
19335                } finally {
19336                    Binder.restoreCallingIdentity(origId);
19337                }
19338            }
19339        }
19340
19341        @Override
19342        public void moveToFront() {
19343            checkCaller();
19344
19345            final TaskRecord tr;
19346            synchronized (ActivityManagerService.this) {
19347                tr = recentTaskForIdLocked(mTaskId);
19348                if (tr == null) {
19349                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19350                }
19351                if (tr.getRootActivity() != null) {
19352                    moveTaskToFrontLocked(tr.taskId, 0, null);
19353                    return;
19354                }
19355            }
19356
19357            startActivityFromRecentsInner(tr.taskId, null);
19358        }
19359
19360        @Override
19361        public int startActivity(IBinder whoThread, String callingPackage,
19362                Intent intent, String resolvedType, Bundle options) {
19363            checkCaller();
19364
19365            int callingUser = UserHandle.getCallingUserId();
19366            TaskRecord tr;
19367            IApplicationThread appThread;
19368            synchronized (ActivityManagerService.this) {
19369                tr = recentTaskForIdLocked(mTaskId);
19370                if (tr == null) {
19371                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19372                }
19373                appThread = ApplicationThreadNative.asInterface(whoThread);
19374                if (appThread == null) {
19375                    throw new IllegalArgumentException("Bad app thread " + appThread);
19376                }
19377            }
19378            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19379                    resolvedType, null, null, null, null, 0, 0, null, null,
19380                    null, options, callingUser, null, tr);
19381        }
19382
19383        @Override
19384        public void setExcludeFromRecents(boolean exclude) {
19385            checkCaller();
19386
19387            synchronized (ActivityManagerService.this) {
19388                long origId = Binder.clearCallingIdentity();
19389                try {
19390                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19391                    if (tr == null) {
19392                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19393                    }
19394                    Intent intent = tr.getBaseIntent();
19395                    if (exclude) {
19396                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19397                    } else {
19398                        intent.setFlags(intent.getFlags()
19399                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19400                    }
19401                } finally {
19402                    Binder.restoreCallingIdentity(origId);
19403                }
19404            }
19405        }
19406    }
19407}
19408