ActivityManagerService.java revision 9c76a7b3e85ce7056071ac8627c8d675cc5c1599
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;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.Installer;
85import com.android.server.pm.UserManagerService;
86import com.android.server.statusbar.StatusBarManagerInternal;
87import com.android.server.wm.AppTransition;
88import com.android.server.wm.WindowManagerService;
89import com.google.android.collect.Lists;
90import com.google.android.collect.Maps;
91
92import libcore.io.IoUtils;
93
94import org.xmlpull.v1.XmlPullParser;
95import org.xmlpull.v1.XmlPullParserException;
96import org.xmlpull.v1.XmlSerializer;
97
98import android.app.Activity;
99import android.app.ActivityManager;
100import android.app.ActivityManager.RunningTaskInfo;
101import android.app.ActivityManager.StackInfo;
102import android.app.ActivityManagerInternal;
103import android.app.ActivityManagerNative;
104import android.app.ActivityOptions;
105import android.app.ActivityThread;
106import android.app.AlertDialog;
107import android.app.AppGlobals;
108import android.app.ApplicationErrorReport;
109import android.app.Dialog;
110import android.app.IActivityController;
111import android.app.IApplicationThread;
112import android.app.IInstrumentationWatcher;
113import android.app.INotificationManager;
114import android.app.IProcessObserver;
115import android.app.IServiceConnection;
116import android.app.IStopUserCallback;
117import android.app.IUiAutomationConnection;
118import android.app.IUserSwitchObserver;
119import android.app.Instrumentation;
120import android.app.Notification;
121import android.app.NotificationManager;
122import android.app.PendingIntent;
123import android.app.backup.IBackupManager;
124import android.content.ActivityNotFoundException;
125import android.content.BroadcastReceiver;
126import android.content.ClipData;
127import android.content.ComponentCallbacks2;
128import android.content.ComponentName;
129import android.content.ContentProvider;
130import android.content.ContentResolver;
131import android.content.Context;
132import android.content.DialogInterface;
133import android.content.IContentProvider;
134import android.content.IIntentReceiver;
135import android.content.IIntentSender;
136import android.content.Intent;
137import android.content.IntentFilter;
138import android.content.IntentSender;
139import android.content.pm.ActivityInfo;
140import android.content.pm.ApplicationInfo;
141import android.content.pm.ConfigurationInfo;
142import android.content.pm.IPackageDataObserver;
143import android.content.pm.IPackageManager;
144import android.content.pm.InstrumentationInfo;
145import android.content.pm.PackageInfo;
146import android.content.pm.PackageManager;
147import android.content.pm.ParceledListSlice;
148import android.content.pm.UserInfo;
149import android.content.pm.PackageManager.NameNotFoundException;
150import android.content.pm.PathPermission;
151import android.content.pm.ProviderInfo;
152import android.content.pm.ResolveInfo;
153import android.content.pm.ServiceInfo;
154import android.content.res.CompatibilityInfo;
155import android.content.res.Configuration;
156import android.net.Proxy;
157import android.net.ProxyInfo;
158import android.net.Uri;
159import android.os.Binder;
160import android.os.Build;
161import android.os.Bundle;
162import android.os.Debug;
163import android.os.DropBoxManager;
164import android.os.Environment;
165import android.os.FactoryTest;
166import android.os.FileObserver;
167import android.os.FileUtils;
168import android.os.Handler;
169import android.os.IBinder;
170import android.os.IPermissionController;
171import android.os.IRemoteCallback;
172import android.os.IUserManager;
173import android.os.Looper;
174import android.os.Message;
175import android.os.Parcel;
176import android.os.ParcelFileDescriptor;
177import android.os.Process;
178import android.os.RemoteCallbackList;
179import android.os.RemoteException;
180import android.os.SELinux;
181import android.os.ServiceManager;
182import android.os.StrictMode;
183import android.os.SystemClock;
184import android.os.SystemProperties;
185import android.os.UpdateLock;
186import android.os.UserHandle;
187import android.os.UserManager;
188import android.provider.Settings;
189import android.text.format.DateUtils;
190import android.text.format.Time;
191import android.util.AtomicFile;
192import android.util.EventLog;
193import android.util.Log;
194import android.util.Pair;
195import android.util.PrintWriterPrinter;
196import android.util.Slog;
197import android.util.SparseArray;
198import android.util.TimeUtils;
199import android.util.Xml;
200import android.view.Gravity;
201import android.view.LayoutInflater;
202import android.view.View;
203import android.view.WindowManager;
204
205import dalvik.system.VMRuntime;
206
207import java.io.BufferedInputStream;
208import java.io.BufferedOutputStream;
209import java.io.DataInputStream;
210import java.io.DataOutputStream;
211import java.io.File;
212import java.io.FileDescriptor;
213import java.io.FileInputStream;
214import java.io.FileNotFoundException;
215import java.io.FileOutputStream;
216import java.io.IOException;
217import java.io.InputStreamReader;
218import java.io.PrintWriter;
219import java.io.StringWriter;
220import java.lang.ref.WeakReference;
221import java.util.ArrayList;
222import java.util.Arrays;
223import java.util.Collections;
224import java.util.Comparator;
225import java.util.HashMap;
226import java.util.HashSet;
227import java.util.Iterator;
228import java.util.List;
229import java.util.Locale;
230import java.util.Map;
231import java.util.Set;
232import java.util.concurrent.atomic.AtomicBoolean;
233import java.util.concurrent.atomic.AtomicLong;
234
235public final class ActivityManagerService extends ActivityManagerNative
236        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
237
238    private static final String USER_DATA_DIR = "/data/user/";
239    // File that stores last updated system version and called preboot receivers
240    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
241
242    static final String TAG = "ActivityManager";
243    static final String TAG_MU = "ActivityManagerServiceMU";
244    static final boolean DEBUG = false;
245    static final boolean localLOGV = DEBUG;
246    static final boolean DEBUG_BACKUP = localLOGV || false;
247    static final boolean DEBUG_BROADCAST = localLOGV || false;
248    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
249    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
250    static final boolean DEBUG_CLEANUP = localLOGV || false;
251    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
252    static final boolean DEBUG_FOCUS = false;
253    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
254    static final boolean DEBUG_MU = localLOGV || false;
255    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
256    static final boolean DEBUG_LRU = localLOGV || false;
257    static final boolean DEBUG_PAUSE = localLOGV || false;
258    static final boolean DEBUG_POWER = localLOGV || false;
259    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
260    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
261    static final boolean DEBUG_PROCESSES = localLOGV || false;
262    static final boolean DEBUG_PROVIDER = localLOGV || false;
263    static final boolean DEBUG_RESULTS = localLOGV || false;
264    static final boolean DEBUG_SERVICE = localLOGV || false;
265    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
266    static final boolean DEBUG_STACK = localLOGV || false;
267    static final boolean DEBUG_SWITCH = localLOGV || false;
268    static final boolean DEBUG_TASKS = localLOGV || false;
269    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
270    static final boolean DEBUG_TRANSITION = localLOGV || false;
271    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
272    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
273    static final boolean DEBUG_VISBILITY = localLOGV || false;
274    static final boolean DEBUG_PSS = localLOGV || false;
275    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
276    static final boolean DEBUG_RECENTS = localLOGV || false;
277    static final boolean VALIDATE_TOKENS = false;
278    static final boolean SHOW_ACTIVITY_START_TIME = true;
279
280    // Control over CPU and battery monitoring.
281    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
282    static final boolean MONITOR_CPU_USAGE = true;
283    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
284    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
285    static final boolean MONITOR_THREAD_CPU_USAGE = false;
286
287    // The flags that are set for all calls we make to the package manager.
288    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
289
290    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
291
292    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
293
294    // Maximum number recent bitmaps to keep in memory.
295    static final int MAX_RECENT_BITMAPS = 5;
296
297    // Amount of time after a call to stopAppSwitches() during which we will
298    // prevent further untrusted switches from happening.
299    static final long APP_SWITCH_DELAY_TIME = 5*1000;
300
301    // How long we wait for a launched process to attach to the activity manager
302    // before we decide it's never going to come up for real.
303    static final int PROC_START_TIMEOUT = 10*1000;
304
305    // How long we wait for a launched process to attach to the activity manager
306    // before we decide it's never going to come up for real, when the process was
307    // started with a wrapper for instrumentation (such as Valgrind) because it
308    // could take much longer than usual.
309    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
310
311    // How long to wait after going idle before forcing apps to GC.
312    static final int GC_TIMEOUT = 5*1000;
313
314    // The minimum amount of time between successive GC requests for a process.
315    static final int GC_MIN_INTERVAL = 60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process.
318    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
319
320    // The minimum amount of time between successive PSS requests for a process
321    // when the request is due to the memory state being lowered.
322    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
323
324    // The rate at which we check for apps using excessive power -- 15 mins.
325    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
326
327    // The minimum sample duration we will allow before deciding we have
328    // enough data on wake locks to start killing things.
329    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
330
331    // The minimum sample duration we will allow before deciding we have
332    // enough data on CPU usage to start killing things.
333    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
334
335    // How long we allow a receiver to run before giving up on it.
336    static final int BROADCAST_FG_TIMEOUT = 10*1000;
337    static final int BROADCAST_BG_TIMEOUT = 60*1000;
338
339    // How long we wait until we timeout on key dispatching.
340    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
341
342    // How long we wait until we timeout on key dispatching during instrumentation.
343    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
344
345    // Amount of time we wait for observers to handle a user switch before
346    // giving up on them and unfreezing the screen.
347    static final int USER_SWITCH_TIMEOUT = 2*1000;
348
349    // Maximum number of users we allow to be running at a time.
350    static final int MAX_RUNNING_USERS = 3;
351
352    // How long to wait in getAssistContextExtras for the activity and foreground services
353    // to respond with the result.
354    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
355
356    // Maximum number of persisted Uri grants a package is allowed
357    static final int MAX_PERSISTED_URI_GRANTS = 128;
358
359    static final int MY_PID = Process.myPid();
360
361    static final String[] EMPTY_STRING_ARRAY = new String[0];
362
363    // How many bytes to write into the dropbox log before truncating
364    static final int DROPBOX_MAX_SIZE = 256 * 1024;
365
366    // Access modes for handleIncomingUser.
367    static final int ALLOW_NON_FULL = 0;
368    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
369    static final int ALLOW_FULL_ONLY = 2;
370
371    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
372
373    /** All system services */
374    SystemServiceManager mSystemServiceManager;
375
376    private Installer mInstaller;
377
378    /** Run all ActivityStacks through this */
379    ActivityStackSupervisor mStackSupervisor;
380
381    public IntentFirewall mIntentFirewall;
382
383    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
384    // default actuion automatically.  Important for devices without direct input
385    // devices.
386    private boolean mShowDialogs = true;
387
388    BroadcastQueue mFgBroadcastQueue;
389    BroadcastQueue mBgBroadcastQueue;
390    // Convenient for easy iteration over the queues. Foreground is first
391    // so that dispatch of foreground broadcasts gets precedence.
392    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
393
394    BroadcastQueue broadcastQueueForIntent(Intent intent) {
395        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
396        if (DEBUG_BACKGROUND_BROADCAST) {
397            Slog.i(TAG, "Broadcast intent " + intent + " on "
398                    + (isFg ? "foreground" : "background")
399                    + " queue");
400        }
401        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
402    }
403
404    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
405        for (BroadcastQueue queue : mBroadcastQueues) {
406            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
407            if (r != null) {
408                return r;
409            }
410        }
411        return null;
412    }
413
414    /**
415     * Activity we have told the window manager to have key focus.
416     */
417    ActivityRecord mFocusedActivity = null;
418
419    /**
420     * List of intents that were used to start the most recent tasks.
421     */
422    ArrayList<TaskRecord> mRecentTasks;
423    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
424
425    /**
426     * For addAppTask: cached of the last activity component that was added.
427     */
428    ComponentName mLastAddedTaskComponent;
429
430    /**
431     * For addAppTask: cached of the last activity uid that was added.
432     */
433    int mLastAddedTaskUid;
434
435    /**
436     * For addAppTask: cached of the last ActivityInfo that was added.
437     */
438    ActivityInfo mLastAddedTaskActivity;
439
440    public class PendingAssistExtras extends Binder implements Runnable {
441        public final ActivityRecord activity;
442        public final Bundle extras;
443        public final Intent intent;
444        public final String hint;
445        public final int userHandle;
446        public boolean haveResult = false;
447        public Bundle result = null;
448        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
449                String _hint, int _userHandle) {
450            activity = _activity;
451            extras = _extras;
452            intent = _intent;
453            hint = _hint;
454            userHandle = _userHandle;
455        }
456        @Override
457        public void run() {
458            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
459            synchronized (this) {
460                haveResult = true;
461                notifyAll();
462            }
463        }
464    }
465
466    final ArrayList<PendingAssistExtras> mPendingAssistExtras
467            = new ArrayList<PendingAssistExtras>();
468
469    /**
470     * Process management.
471     */
472    final ProcessList mProcessList = new ProcessList();
473
474    /**
475     * All of the applications we currently have running organized by name.
476     * The keys are strings of the application package name (as
477     * returned by the package manager), and the keys are ApplicationRecord
478     * objects.
479     */
480    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
481
482    /**
483     * Tracking long-term execution of processes to look for abuse and other
484     * bad app behavior.
485     */
486    final ProcessStatsService mProcessStats;
487
488    /**
489     * The currently running isolated processes.
490     */
491    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
492
493    /**
494     * Counter for assigning isolated process uids, to avoid frequently reusing the
495     * same ones.
496     */
497    int mNextIsolatedProcessUid = 0;
498
499    /**
500     * The currently running heavy-weight process, if any.
501     */
502    ProcessRecord mHeavyWeightProcess = null;
503
504    /**
505     * The last time that various processes have crashed.
506     */
507    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
508
509    /**
510     * Information about a process that is currently marked as bad.
511     */
512    static final class BadProcessInfo {
513        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
514            this.time = time;
515            this.shortMsg = shortMsg;
516            this.longMsg = longMsg;
517            this.stack = stack;
518        }
519
520        final long time;
521        final String shortMsg;
522        final String longMsg;
523        final String stack;
524    }
525
526    /**
527     * Set of applications that we consider to be bad, and will reject
528     * incoming broadcasts from (which the user has no control over).
529     * Processes are added to this set when they have crashed twice within
530     * a minimum amount of time; they are removed from it when they are
531     * later restarted (hopefully due to some user action).  The value is the
532     * time it was added to the list.
533     */
534    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
535
536    /**
537     * All of the processes we currently have running organized by pid.
538     * The keys are the pid running the application.
539     *
540     * <p>NOTE: This object is protected by its own lock, NOT the global
541     * activity manager lock!
542     */
543    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
544
545    /**
546     * All of the processes that have been forced to be foreground.  The key
547     * is the pid of the caller who requested it (we hold a death
548     * link on it).
549     */
550    abstract class ForegroundToken implements IBinder.DeathRecipient {
551        int pid;
552        IBinder token;
553    }
554    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
555
556    /**
557     * List of records for processes that someone had tried to start before the
558     * system was ready.  We don't start them at that point, but ensure they
559     * are started by the time booting is complete.
560     */
561    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
562
563    /**
564     * List of persistent applications that are in the process
565     * of being started.
566     */
567    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * Processes that are being forcibly torn down.
571     */
572    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
573
574    /**
575     * List of running applications, sorted by recent usage.
576     * The first entry in the list is the least recently used.
577     */
578    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
579
580    /**
581     * Where in mLruProcesses that the processes hosting activities start.
582     */
583    int mLruProcessActivityStart = 0;
584
585    /**
586     * Where in mLruProcesses that the processes hosting services start.
587     * This is after (lower index) than mLruProcessesActivityStart.
588     */
589    int mLruProcessServiceStart = 0;
590
591    /**
592     * List of processes that should gc as soon as things are idle.
593     */
594    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
595
596    /**
597     * Processes we want to collect PSS data from.
598     */
599    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
600
601    /**
602     * Last time we requested PSS data of all processes.
603     */
604    long mLastFullPssTime = SystemClock.uptimeMillis();
605
606    /**
607     * If set, the next time we collect PSS data we should do a full collection
608     * with data from native processes and the kernel.
609     */
610    boolean mFullPssPending = false;
611
612    /**
613     * This is the process holding what we currently consider to be
614     * the "home" activity.
615     */
616    ProcessRecord mHomeProcess;
617
618    /**
619     * This is the process holding the activity the user last visited that
620     * is in a different process from the one they are currently in.
621     */
622    ProcessRecord mPreviousProcess;
623
624    /**
625     * The time at which the previous process was last visible.
626     */
627    long mPreviousProcessVisibleTime;
628
629    /**
630     * Which uses have been started, so are allowed to run code.
631     */
632    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
633
634    /**
635     * LRU list of history of current users.  Most recently current is at the end.
636     */
637    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
638
639    /**
640     * Constant array of the users that are currently started.
641     */
642    int[] mStartedUserArray = new int[] { 0 };
643
644    /**
645     * Registered observers of the user switching mechanics.
646     */
647    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
648            = new RemoteCallbackList<IUserSwitchObserver>();
649
650    /**
651     * Currently active user switch.
652     */
653    Object mCurUserSwitchCallback;
654
655    /**
656     * Packages that the user has asked to have run in screen size
657     * compatibility mode instead of filling the screen.
658     */
659    final CompatModePackages mCompatModePackages;
660
661    /**
662     * Set of IntentSenderRecord objects that are currently active.
663     */
664    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
665            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
666
667    /**
668     * Fingerprints (hashCode()) of stack traces that we've
669     * already logged DropBox entries for.  Guarded by itself.  If
670     * something (rogue user app) forces this over
671     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
672     */
673    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
674    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
675
676    /**
677     * Strict Mode background batched logging state.
678     *
679     * The string buffer is guarded by itself, and its lock is also
680     * used to determine if another batched write is already
681     * in-flight.
682     */
683    private final StringBuilder mStrictModeBuffer = new StringBuilder();
684
685    /**
686     * Keeps track of all IIntentReceivers that have been registered for
687     * broadcasts.  Hash keys are the receiver IBinder, hash value is
688     * a ReceiverList.
689     */
690    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
691            new HashMap<IBinder, ReceiverList>();
692
693    /**
694     * Resolver for broadcast intents to registered receivers.
695     * Holds BroadcastFilter (subclass of IntentFilter).
696     */
697    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
698            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
699        @Override
700        protected boolean allowFilterResult(
701                BroadcastFilter filter, List<BroadcastFilter> dest) {
702            IBinder target = filter.receiverList.receiver.asBinder();
703            for (int i=dest.size()-1; i>=0; i--) {
704                if (dest.get(i).receiverList.receiver.asBinder() == target) {
705                    return false;
706                }
707            }
708            return true;
709        }
710
711        @Override
712        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
713            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
714                    || userId == filter.owningUserId) {
715                return super.newResult(filter, match, userId);
716            }
717            return null;
718        }
719
720        @Override
721        protected BroadcastFilter[] newArray(int size) {
722            return new BroadcastFilter[size];
723        }
724
725        @Override
726        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
727            return packageName.equals(filter.packageName);
728        }
729    };
730
731    /**
732     * State of all active sticky broadcasts per user.  Keys are the action of the
733     * sticky Intent, values are an ArrayList of all broadcasted intents with
734     * that action (which should usually be one).  The SparseArray is keyed
735     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
736     * for stickies that are sent to all users.
737     */
738    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
739            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
740
741    final ActiveServices mServices;
742
743    /**
744     * Backup/restore process management
745     */
746    String mBackupAppName = null;
747    BackupRecord mBackupTarget = null;
748
749    final ProviderMap mProviderMap;
750
751    /**
752     * List of content providers who have clients waiting for them.  The
753     * application is currently being launched and the provider will be
754     * removed from this list once it is published.
755     */
756    final ArrayList<ContentProviderRecord> mLaunchingProviders
757            = new ArrayList<ContentProviderRecord>();
758
759    /**
760     * File storing persisted {@link #mGrantedUriPermissions}.
761     */
762    private final AtomicFile mGrantFile;
763
764    /** XML constants used in {@link #mGrantFile} */
765    private static final String TAG_URI_GRANTS = "uri-grants";
766    private static final String TAG_URI_GRANT = "uri-grant";
767    private static final String ATTR_USER_HANDLE = "userHandle";
768    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
769    private static final String ATTR_TARGET_USER_ID = "targetUserId";
770    private static final String ATTR_SOURCE_PKG = "sourcePkg";
771    private static final String ATTR_TARGET_PKG = "targetPkg";
772    private static final String ATTR_URI = "uri";
773    private static final String ATTR_MODE_FLAGS = "modeFlags";
774    private static final String ATTR_CREATED_TIME = "createdTime";
775    private static final String ATTR_PREFIX = "prefix";
776
777    /**
778     * Global set of specific {@link Uri} permissions that have been granted.
779     * This optimized lookup structure maps from {@link UriPermission#targetUid}
780     * to {@link UriPermission#uri} to {@link UriPermission}.
781     */
782    @GuardedBy("this")
783    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
784            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
785
786    public static class GrantUri {
787        public final int sourceUserId;
788        public final Uri uri;
789        public boolean prefix;
790
791        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
792            this.sourceUserId = sourceUserId;
793            this.uri = uri;
794            this.prefix = prefix;
795        }
796
797        @Override
798        public int hashCode() {
799            return toString().hashCode();
800        }
801
802        @Override
803        public boolean equals(Object o) {
804            if (o instanceof GrantUri) {
805                GrantUri other = (GrantUri) o;
806                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
807                        && prefix == other.prefix;
808            }
809            return false;
810        }
811
812        @Override
813        public String toString() {
814            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
815            if (prefix) result += " [prefix]";
816            return result;
817        }
818
819        public String toSafeString() {
820            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
821            if (prefix) result += " [prefix]";
822            return result;
823        }
824
825        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
826            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
827                    ContentProvider.getUriWithoutUserId(uri), false);
828        }
829    }
830
831    CoreSettingsObserver mCoreSettingsObserver;
832
833    /**
834     * Thread-local storage used to carry caller permissions over through
835     * indirect content-provider access.
836     */
837    private class Identity {
838        public int pid;
839        public int uid;
840
841        Identity(int _pid, int _uid) {
842            pid = _pid;
843            uid = _uid;
844        }
845    }
846
847    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
848
849    /**
850     * All information we have collected about the runtime performance of
851     * any user id that can impact battery performance.
852     */
853    final BatteryStatsService mBatteryStatsService;
854
855    /**
856     * Information about component usage
857     */
858    UsageStatsManagerInternal mUsageStatsService;
859
860    /**
861     * Information about and control over application operations
862     */
863    final AppOpsService mAppOpsService;
864
865    /**
866     * Save recent tasks information across reboots.
867     */
868    final TaskPersister mTaskPersister;
869
870    /**
871     * Current configuration information.  HistoryRecord objects are given
872     * a reference to this object to indicate which configuration they are
873     * currently running in, so this object must be kept immutable.
874     */
875    Configuration mConfiguration = new Configuration();
876
877    /**
878     * Current sequencing integer of the configuration, for skipping old
879     * configurations.
880     */
881    int mConfigurationSeq = 0;
882
883    /**
884     * Hardware-reported OpenGLES version.
885     */
886    final int GL_ES_VERSION;
887
888    /**
889     * List of initialization arguments to pass to all processes when binding applications to them.
890     * For example, references to the commonly used services.
891     */
892    HashMap<String, IBinder> mAppBindArgs;
893
894    /**
895     * Temporary to avoid allocations.  Protected by main lock.
896     */
897    final StringBuilder mStringBuilder = new StringBuilder(256);
898
899    /**
900     * Used to control how we initialize the service.
901     */
902    ComponentName mTopComponent;
903    String mTopAction = Intent.ACTION_MAIN;
904    String mTopData;
905    boolean mProcessesReady = false;
906    boolean mSystemReady = false;
907    boolean mBooting = false;
908    boolean mCallFinishBooting = false;
909    boolean mBootAnimationComplete = false;
910    boolean mWaitingUpdate = false;
911    boolean mDidUpdate = false;
912    boolean mOnBattery = false;
913    boolean mLaunchWarningShown = false;
914
915    Context mContext;
916
917    int mFactoryTest;
918
919    boolean mCheckedForSetup;
920
921    /**
922     * The time at which we will allow normal application switches again,
923     * after a call to {@link #stopAppSwitches()}.
924     */
925    long mAppSwitchesAllowedTime;
926
927    /**
928     * This is set to true after the first switch after mAppSwitchesAllowedTime
929     * is set; any switches after that will clear the time.
930     */
931    boolean mDidAppSwitch;
932
933    /**
934     * Last time (in realtime) at which we checked for power usage.
935     */
936    long mLastPowerCheckRealtime;
937
938    /**
939     * Last time (in uptime) at which we checked for power usage.
940     */
941    long mLastPowerCheckUptime;
942
943    /**
944     * Set while we are wanting to sleep, to prevent any
945     * activities from being started/resumed.
946     */
947    private boolean mSleeping = false;
948
949    /**
950     * Set while we are running a voice interaction.  This overrides
951     * sleeping while it is active.
952     */
953    private boolean mRunningVoice = false;
954
955    /**
956     * State of external calls telling us if the device is asleep.
957     */
958    private boolean mWentToSleep = false;
959
960    static final int LOCK_SCREEN_HIDDEN = 0;
961    static final int LOCK_SCREEN_LEAVING = 1;
962    static final int LOCK_SCREEN_SHOWN = 2;
963    /**
964     * State of external call telling us if the lock screen is shown.
965     */
966    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
967
968    /**
969     * Set if we are shutting down the system, similar to sleeping.
970     */
971    boolean mShuttingDown = false;
972
973    /**
974     * Current sequence id for oom_adj computation traversal.
975     */
976    int mAdjSeq = 0;
977
978    /**
979     * Current sequence id for process LRU updating.
980     */
981    int mLruSeq = 0;
982
983    /**
984     * Keep track of the non-cached/empty process we last found, to help
985     * determine how to distribute cached/empty processes next time.
986     */
987    int mNumNonCachedProcs = 0;
988
989    /**
990     * Keep track of the number of cached hidden procs, to balance oom adj
991     * distribution between those and empty procs.
992     */
993    int mNumCachedHiddenProcs = 0;
994
995    /**
996     * Keep track of the number of service processes we last found, to
997     * determine on the next iteration which should be B services.
998     */
999    int mNumServiceProcs = 0;
1000    int mNewNumAServiceProcs = 0;
1001    int mNewNumServiceProcs = 0;
1002
1003    /**
1004     * Allow the current computed overall memory level of the system to go down?
1005     * This is set to false when we are killing processes for reasons other than
1006     * memory management, so that the now smaller process list will not be taken as
1007     * an indication that memory is tighter.
1008     */
1009    boolean mAllowLowerMemLevel = false;
1010
1011    /**
1012     * The last computed memory level, for holding when we are in a state that
1013     * processes are going away for other reasons.
1014     */
1015    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1016
1017    /**
1018     * The last total number of process we have, to determine if changes actually look
1019     * like a shrinking number of process due to lower RAM.
1020     */
1021    int mLastNumProcesses;
1022
1023    /**
1024     * The uptime of the last time we performed idle maintenance.
1025     */
1026    long mLastIdleTime = SystemClock.uptimeMillis();
1027
1028    /**
1029     * Total time spent with RAM that has been added in the past since the last idle time.
1030     */
1031    long mLowRamTimeSinceLastIdle = 0;
1032
1033    /**
1034     * If RAM is currently low, when that horrible situation started.
1035     */
1036    long mLowRamStartTime = 0;
1037
1038    /**
1039     * For reporting to battery stats the current top application.
1040     */
1041    private String mCurResumedPackage = null;
1042    private int mCurResumedUid = -1;
1043
1044    /**
1045     * For reporting to battery stats the apps currently running foreground
1046     * service.  The ProcessMap is package/uid tuples; each of these contain
1047     * an array of the currently foreground processes.
1048     */
1049    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1050            = new ProcessMap<ArrayList<ProcessRecord>>();
1051
1052    /**
1053     * This is set if we had to do a delayed dexopt of an app before launching
1054     * it, to increase the ANR timeouts in that case.
1055     */
1056    boolean mDidDexOpt;
1057
1058    /**
1059     * Set if the systemServer made a call to enterSafeMode.
1060     */
1061    boolean mSafeMode;
1062
1063    String mDebugApp = null;
1064    boolean mWaitForDebugger = false;
1065    boolean mDebugTransient = false;
1066    String mOrigDebugApp = null;
1067    boolean mOrigWaitForDebugger = false;
1068    boolean mAlwaysFinishActivities = false;
1069    IActivityController mController = null;
1070    String mProfileApp = null;
1071    ProcessRecord mProfileProc = null;
1072    String mProfileFile;
1073    ParcelFileDescriptor mProfileFd;
1074    int mSamplingInterval = 0;
1075    boolean mAutoStopProfiler = false;
1076    int mProfileType = 0;
1077    String mOpenGlTraceApp = null;
1078
1079    static class ProcessChangeItem {
1080        static final int CHANGE_ACTIVITIES = 1<<0;
1081        static final int CHANGE_PROCESS_STATE = 1<<1;
1082        int changes;
1083        int uid;
1084        int pid;
1085        int processState;
1086        boolean foregroundActivities;
1087    }
1088
1089    final RemoteCallbackList<IProcessObserver> mProcessObservers
1090            = new RemoteCallbackList<IProcessObserver>();
1091    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1092
1093    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1094            = new ArrayList<ProcessChangeItem>();
1095    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1096            = new ArrayList<ProcessChangeItem>();
1097
1098    /**
1099     * Runtime CPU use collection thread.  This object's lock is used to
1100     * perform synchronization with the thread (notifying it to run).
1101     */
1102    final Thread mProcessCpuThread;
1103
1104    /**
1105     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1106     * Must acquire this object's lock when accessing it.
1107     * NOTE: this lock will be held while doing long operations (trawling
1108     * through all processes in /proc), so it should never be acquired by
1109     * any critical paths such as when holding the main activity manager lock.
1110     */
1111    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1112            MONITOR_THREAD_CPU_USAGE);
1113    final AtomicLong mLastCpuTime = new AtomicLong(0);
1114    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1115
1116    long mLastWriteTime = 0;
1117
1118    /**
1119     * Used to retain an update lock when the foreground activity is in
1120     * immersive mode.
1121     */
1122    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1123
1124    /**
1125     * Set to true after the system has finished booting.
1126     */
1127    boolean mBooted = false;
1128
1129    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1130    int mProcessLimitOverride = -1;
1131
1132    WindowManagerService mWindowManager;
1133
1134    final ActivityThread mSystemThread;
1135
1136    // Holds the current foreground user's id
1137    int mCurrentUserId = 0;
1138    // Holds the target user's id during a user switch
1139    int mTargetUserId = UserHandle.USER_NULL;
1140    // If there are multiple profiles for the current user, their ids are here
1141    // Currently only the primary user can have managed profiles
1142    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1143
1144    /**
1145     * Mapping from each known user ID to the profile group ID it is associated with.
1146     */
1147    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1148
1149    private UserManagerService mUserManager;
1150
1151    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1152        final ProcessRecord mApp;
1153        final int mPid;
1154        final IApplicationThread mAppThread;
1155
1156        AppDeathRecipient(ProcessRecord app, int pid,
1157                IApplicationThread thread) {
1158            if (localLOGV) Slog.v(
1159                TAG, "New death recipient " + this
1160                + " for thread " + thread.asBinder());
1161            mApp = app;
1162            mPid = pid;
1163            mAppThread = thread;
1164        }
1165
1166        @Override
1167        public void binderDied() {
1168            if (localLOGV) Slog.v(
1169                TAG, "Death received in " + this
1170                + " for thread " + mAppThread.asBinder());
1171            synchronized(ActivityManagerService.this) {
1172                appDiedLocked(mApp, mPid, mAppThread);
1173            }
1174        }
1175    }
1176
1177    static final int SHOW_ERROR_MSG = 1;
1178    static final int SHOW_NOT_RESPONDING_MSG = 2;
1179    static final int SHOW_FACTORY_ERROR_MSG = 3;
1180    static final int UPDATE_CONFIGURATION_MSG = 4;
1181    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1182    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1183    static final int SERVICE_TIMEOUT_MSG = 12;
1184    static final int UPDATE_TIME_ZONE = 13;
1185    static final int SHOW_UID_ERROR_MSG = 14;
1186    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1187    static final int PROC_START_TIMEOUT_MSG = 20;
1188    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1189    static final int KILL_APPLICATION_MSG = 22;
1190    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1191    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1192    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1193    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1194    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1195    static final int CLEAR_DNS_CACHE_MSG = 28;
1196    static final int UPDATE_HTTP_PROXY_MSG = 29;
1197    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1198    static final int DISPATCH_PROCESSES_CHANGED = 31;
1199    static final int DISPATCH_PROCESS_DIED = 32;
1200    static final int REPORT_MEM_USAGE_MSG = 33;
1201    static final int REPORT_USER_SWITCH_MSG = 34;
1202    static final int CONTINUE_USER_SWITCH_MSG = 35;
1203    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1204    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1205    static final int PERSIST_URI_GRANTS_MSG = 38;
1206    static final int REQUEST_ALL_PSS_MSG = 39;
1207    static final int START_PROFILES_MSG = 40;
1208    static final int UPDATE_TIME = 41;
1209    static final int SYSTEM_USER_START_MSG = 42;
1210    static final int SYSTEM_USER_CURRENT_MSG = 43;
1211    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1212    static final int FINISH_BOOTING_MSG = 45;
1213    static final int START_USER_SWITCH_MSG = 46;
1214    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1215    static final int DISMISS_DIALOG_MSG = 48;
1216
1217    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1218    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1219    static final int FIRST_COMPAT_MODE_MSG = 300;
1220    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1221
1222    CompatModeDialog mCompatModeDialog;
1223    long mLastMemUsageReportTime = 0;
1224
1225    /**
1226     * Flag whether the current user is a "monkey", i.e. whether
1227     * the UI is driven by a UI automation tool.
1228     */
1229    private boolean mUserIsMonkey;
1230
1231    /** Flag whether the device has a Recents UI */
1232    boolean mHasRecents;
1233
1234    /** The dimensions of the thumbnails in the Recents UI. */
1235    int mThumbnailWidth;
1236    int mThumbnailHeight;
1237
1238    final ServiceThread mHandlerThread;
1239    final MainHandler mHandler;
1240
1241    final class MainHandler extends Handler {
1242        public MainHandler(Looper looper) {
1243            super(looper, null, true);
1244        }
1245
1246        @Override
1247        public void handleMessage(Message msg) {
1248            switch (msg.what) {
1249            case SHOW_ERROR_MSG: {
1250                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1251                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1252                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1253                synchronized (ActivityManagerService.this) {
1254                    ProcessRecord proc = (ProcessRecord)data.get("app");
1255                    AppErrorResult res = (AppErrorResult) data.get("result");
1256                    if (proc != null && proc.crashDialog != null) {
1257                        Slog.e(TAG, "App already has crash dialog: " + proc);
1258                        if (res != null) {
1259                            res.set(0);
1260                        }
1261                        return;
1262                    }
1263                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1264                            >= Process.FIRST_APPLICATION_UID
1265                            && proc.pid != MY_PID);
1266                    for (int userId : mCurrentProfileIds) {
1267                        isBackground &= (proc.userId != userId);
1268                    }
1269                    if (isBackground && !showBackground) {
1270                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1271                        if (res != null) {
1272                            res.set(0);
1273                        }
1274                        return;
1275                    }
1276                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1277                        Dialog d = new AppErrorDialog(mContext,
1278                                ActivityManagerService.this, res, proc);
1279                        d.show();
1280                        proc.crashDialog = d;
1281                    } else {
1282                        // The device is asleep, so just pretend that the user
1283                        // saw a crash dialog and hit "force quit".
1284                        if (res != null) {
1285                            res.set(0);
1286                        }
1287                    }
1288                }
1289
1290                ensureBootCompleted();
1291            } break;
1292            case SHOW_NOT_RESPONDING_MSG: {
1293                synchronized (ActivityManagerService.this) {
1294                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1295                    ProcessRecord proc = (ProcessRecord)data.get("app");
1296                    if (proc != null && proc.anrDialog != null) {
1297                        Slog.e(TAG, "App already has anr dialog: " + proc);
1298                        return;
1299                    }
1300
1301                    Intent intent = new Intent("android.intent.action.ANR");
1302                    if (!mProcessesReady) {
1303                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1304                                | Intent.FLAG_RECEIVER_FOREGROUND);
1305                    }
1306                    broadcastIntentLocked(null, null, intent,
1307                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1308                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1309
1310                    if (mShowDialogs) {
1311                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1312                                mContext, proc, (ActivityRecord)data.get("activity"),
1313                                msg.arg1 != 0);
1314                        d.show();
1315                        proc.anrDialog = d;
1316                    } else {
1317                        // Just kill the app if there is no dialog to be shown.
1318                        killAppAtUsersRequest(proc, null);
1319                    }
1320                }
1321
1322                ensureBootCompleted();
1323            } break;
1324            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1325                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1326                synchronized (ActivityManagerService.this) {
1327                    ProcessRecord proc = (ProcessRecord) data.get("app");
1328                    if (proc == null) {
1329                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1330                        break;
1331                    }
1332                    if (proc.crashDialog != null) {
1333                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1334                        return;
1335                    }
1336                    AppErrorResult res = (AppErrorResult) data.get("result");
1337                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1338                        Dialog d = new StrictModeViolationDialog(mContext,
1339                                ActivityManagerService.this, res, proc);
1340                        d.show();
1341                        proc.crashDialog = d;
1342                    } else {
1343                        // The device is asleep, so just pretend that the user
1344                        // saw a crash dialog and hit "force quit".
1345                        res.set(0);
1346                    }
1347                }
1348                ensureBootCompleted();
1349            } break;
1350            case SHOW_FACTORY_ERROR_MSG: {
1351                Dialog d = new FactoryErrorDialog(
1352                    mContext, msg.getData().getCharSequence("msg"));
1353                d.show();
1354                ensureBootCompleted();
1355            } break;
1356            case UPDATE_CONFIGURATION_MSG: {
1357                final ContentResolver resolver = mContext.getContentResolver();
1358                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1359            } break;
1360            case GC_BACKGROUND_PROCESSES_MSG: {
1361                synchronized (ActivityManagerService.this) {
1362                    performAppGcsIfAppropriateLocked();
1363                }
1364            } break;
1365            case WAIT_FOR_DEBUGGER_MSG: {
1366                synchronized (ActivityManagerService.this) {
1367                    ProcessRecord app = (ProcessRecord)msg.obj;
1368                    if (msg.arg1 != 0) {
1369                        if (!app.waitedForDebugger) {
1370                            Dialog d = new AppWaitingForDebuggerDialog(
1371                                    ActivityManagerService.this,
1372                                    mContext, app);
1373                            app.waitDialog = d;
1374                            app.waitedForDebugger = true;
1375                            d.show();
1376                        }
1377                    } else {
1378                        if (app.waitDialog != null) {
1379                            app.waitDialog.dismiss();
1380                            app.waitDialog = null;
1381                        }
1382                    }
1383                }
1384            } break;
1385            case SERVICE_TIMEOUT_MSG: {
1386                if (mDidDexOpt) {
1387                    mDidDexOpt = false;
1388                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1389                    nmsg.obj = msg.obj;
1390                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1391                    return;
1392                }
1393                mServices.serviceTimeout((ProcessRecord)msg.obj);
1394            } break;
1395            case UPDATE_TIME_ZONE: {
1396                synchronized (ActivityManagerService.this) {
1397                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1398                        ProcessRecord r = mLruProcesses.get(i);
1399                        if (r.thread != null) {
1400                            try {
1401                                r.thread.updateTimeZone();
1402                            } catch (RemoteException ex) {
1403                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1404                            }
1405                        }
1406                    }
1407                }
1408            } break;
1409            case CLEAR_DNS_CACHE_MSG: {
1410                synchronized (ActivityManagerService.this) {
1411                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1412                        ProcessRecord r = mLruProcesses.get(i);
1413                        if (r.thread != null) {
1414                            try {
1415                                r.thread.clearDnsCache();
1416                            } catch (RemoteException ex) {
1417                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1418                            }
1419                        }
1420                    }
1421                }
1422            } break;
1423            case UPDATE_HTTP_PROXY_MSG: {
1424                ProxyInfo proxy = (ProxyInfo)msg.obj;
1425                String host = "";
1426                String port = "";
1427                String exclList = "";
1428                Uri pacFileUrl = Uri.EMPTY;
1429                if (proxy != null) {
1430                    host = proxy.getHost();
1431                    port = Integer.toString(proxy.getPort());
1432                    exclList = proxy.getExclusionListAsString();
1433                    pacFileUrl = proxy.getPacFileUrl();
1434                }
1435                synchronized (ActivityManagerService.this) {
1436                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1437                        ProcessRecord r = mLruProcesses.get(i);
1438                        if (r.thread != null) {
1439                            try {
1440                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1441                            } catch (RemoteException ex) {
1442                                Slog.w(TAG, "Failed to update http proxy for: " +
1443                                        r.info.processName);
1444                            }
1445                        }
1446                    }
1447                }
1448            } break;
1449            case SHOW_UID_ERROR_MSG: {
1450                if (mShowDialogs) {
1451                    AlertDialog d = new BaseErrorDialog(mContext);
1452                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1453                    d.setCancelable(false);
1454                    d.setTitle(mContext.getText(R.string.android_system_label));
1455                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1456                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1457                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1458                    d.show();
1459                }
1460            } break;
1461            case SHOW_FINGERPRINT_ERROR_MSG: {
1462                if (mShowDialogs) {
1463                    AlertDialog d = new BaseErrorDialog(mContext);
1464                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1465                    d.setCancelable(false);
1466                    d.setTitle(mContext.getText(R.string.android_system_label));
1467                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1468                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1469                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1470                    d.show();
1471                }
1472            } break;
1473            case PROC_START_TIMEOUT_MSG: {
1474                if (mDidDexOpt) {
1475                    mDidDexOpt = false;
1476                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1477                    nmsg.obj = msg.obj;
1478                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1479                    return;
1480                }
1481                ProcessRecord app = (ProcessRecord)msg.obj;
1482                synchronized (ActivityManagerService.this) {
1483                    processStartTimedOutLocked(app);
1484                }
1485            } break;
1486            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1487                synchronized (ActivityManagerService.this) {
1488                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1489                }
1490            } break;
1491            case KILL_APPLICATION_MSG: {
1492                synchronized (ActivityManagerService.this) {
1493                    int appid = msg.arg1;
1494                    boolean restart = (msg.arg2 == 1);
1495                    Bundle bundle = (Bundle)msg.obj;
1496                    String pkg = bundle.getString("pkg");
1497                    String reason = bundle.getString("reason");
1498                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1499                            false, UserHandle.USER_ALL, reason);
1500                }
1501            } break;
1502            case FINALIZE_PENDING_INTENT_MSG: {
1503                ((PendingIntentRecord)msg.obj).completeFinalize();
1504            } break;
1505            case POST_HEAVY_NOTIFICATION_MSG: {
1506                INotificationManager inm = NotificationManager.getService();
1507                if (inm == null) {
1508                    return;
1509                }
1510
1511                ActivityRecord root = (ActivityRecord)msg.obj;
1512                ProcessRecord process = root.app;
1513                if (process == null) {
1514                    return;
1515                }
1516
1517                try {
1518                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1519                    String text = mContext.getString(R.string.heavy_weight_notification,
1520                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1521                    Notification notification = new Notification();
1522                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1523                    notification.when = 0;
1524                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1525                    notification.tickerText = text;
1526                    notification.defaults = 0; // please be quiet
1527                    notification.sound = null;
1528                    notification.vibrate = null;
1529                    notification.color = mContext.getResources().getColor(
1530                            com.android.internal.R.color.system_notification_accent_color);
1531                    notification.setLatestEventInfo(context, text,
1532                            mContext.getText(R.string.heavy_weight_notification_detail),
1533                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1534                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1535                                    new UserHandle(root.userId)));
1536
1537                    try {
1538                        int[] outId = new int[1];
1539                        inm.enqueueNotificationWithTag("android", "android", null,
1540                                R.string.heavy_weight_notification,
1541                                notification, outId, root.userId);
1542                    } catch (RuntimeException e) {
1543                        Slog.w(ActivityManagerService.TAG,
1544                                "Error showing notification for heavy-weight app", e);
1545                    } catch (RemoteException e) {
1546                    }
1547                } catch (NameNotFoundException e) {
1548                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1549                }
1550            } break;
1551            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1552                INotificationManager inm = NotificationManager.getService();
1553                if (inm == null) {
1554                    return;
1555                }
1556                try {
1557                    inm.cancelNotificationWithTag("android", null,
1558                            R.string.heavy_weight_notification,  msg.arg1);
1559                } catch (RuntimeException e) {
1560                    Slog.w(ActivityManagerService.TAG,
1561                            "Error canceling notification for service", e);
1562                } catch (RemoteException e) {
1563                }
1564            } break;
1565            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1566                synchronized (ActivityManagerService.this) {
1567                    checkExcessivePowerUsageLocked(true);
1568                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1569                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1570                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1571                }
1572            } break;
1573            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1574                synchronized (ActivityManagerService.this) {
1575                    ActivityRecord ar = (ActivityRecord)msg.obj;
1576                    if (mCompatModeDialog != null) {
1577                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1578                                ar.info.applicationInfo.packageName)) {
1579                            return;
1580                        }
1581                        mCompatModeDialog.dismiss();
1582                        mCompatModeDialog = null;
1583                    }
1584                    if (ar != null && false) {
1585                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1586                                ar.packageName)) {
1587                            int mode = mCompatModePackages.computeCompatModeLocked(
1588                                    ar.info.applicationInfo);
1589                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1590                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1591                                mCompatModeDialog = new CompatModeDialog(
1592                                        ActivityManagerService.this, mContext,
1593                                        ar.info.applicationInfo);
1594                                mCompatModeDialog.show();
1595                            }
1596                        }
1597                    }
1598                }
1599                break;
1600            }
1601            case DISPATCH_PROCESSES_CHANGED: {
1602                dispatchProcessesChanged();
1603                break;
1604            }
1605            case DISPATCH_PROCESS_DIED: {
1606                final int pid = msg.arg1;
1607                final int uid = msg.arg2;
1608                dispatchProcessDied(pid, uid);
1609                break;
1610            }
1611            case REPORT_MEM_USAGE_MSG: {
1612                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1613                Thread thread = new Thread() {
1614                    @Override public void run() {
1615                        reportMemUsage(memInfos);
1616                    }
1617                };
1618                thread.start();
1619                break;
1620            }
1621            case START_USER_SWITCH_MSG: {
1622                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1623                break;
1624            }
1625            case REPORT_USER_SWITCH_MSG: {
1626                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1627                break;
1628            }
1629            case CONTINUE_USER_SWITCH_MSG: {
1630                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1631                break;
1632            }
1633            case USER_SWITCH_TIMEOUT_MSG: {
1634                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1635                break;
1636            }
1637            case IMMERSIVE_MODE_LOCK_MSG: {
1638                final boolean nextState = (msg.arg1 != 0);
1639                if (mUpdateLock.isHeld() != nextState) {
1640                    if (DEBUG_IMMERSIVE) {
1641                        final ActivityRecord r = (ActivityRecord) msg.obj;
1642                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1643                    }
1644                    if (nextState) {
1645                        mUpdateLock.acquire();
1646                    } else {
1647                        mUpdateLock.release();
1648                    }
1649                }
1650                break;
1651            }
1652            case PERSIST_URI_GRANTS_MSG: {
1653                writeGrantedUriPermissions();
1654                break;
1655            }
1656            case REQUEST_ALL_PSS_MSG: {
1657                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1658                break;
1659            }
1660            case START_PROFILES_MSG: {
1661                synchronized (ActivityManagerService.this) {
1662                    startProfilesLocked();
1663                }
1664                break;
1665            }
1666            case UPDATE_TIME: {
1667                synchronized (ActivityManagerService.this) {
1668                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1669                        ProcessRecord r = mLruProcesses.get(i);
1670                        if (r.thread != null) {
1671                            try {
1672                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1673                            } catch (RemoteException ex) {
1674                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1675                            }
1676                        }
1677                    }
1678                }
1679                break;
1680            }
1681            case SYSTEM_USER_START_MSG: {
1682                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1683                        Integer.toString(msg.arg1), msg.arg1);
1684                mSystemServiceManager.startUser(msg.arg1);
1685                break;
1686            }
1687            case SYSTEM_USER_CURRENT_MSG: {
1688                mBatteryStatsService.noteEvent(
1689                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1690                        Integer.toString(msg.arg2), msg.arg2);
1691                mBatteryStatsService.noteEvent(
1692                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1693                        Integer.toString(msg.arg1), msg.arg1);
1694                mSystemServiceManager.switchUser(msg.arg1);
1695                break;
1696            }
1697            case ENTER_ANIMATION_COMPLETE_MSG: {
1698                synchronized (ActivityManagerService.this) {
1699                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1700                    if (r != null && r.app != null && r.app.thread != null) {
1701                        try {
1702                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1703                        } catch (RemoteException e) {
1704                        }
1705                    }
1706                }
1707                break;
1708            }
1709            case FINISH_BOOTING_MSG: {
1710                if (msg.arg1 != 0) {
1711                    finishBooting();
1712                }
1713                if (msg.arg2 != 0) {
1714                    enableScreenAfterBoot();
1715                }
1716                break;
1717            }
1718            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1719                try {
1720                    Locale l = (Locale) msg.obj;
1721                    IBinder service = ServiceManager.getService("mount");
1722                    IMountService mountService = IMountService.Stub.asInterface(service);
1723                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1724                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1725                } catch (RemoteException e) {
1726                    Log.e(TAG, "Error storing locale for decryption UI", e);
1727                }
1728                break;
1729            }
1730            case DISMISS_DIALOG_MSG: {
1731                final Dialog d = (Dialog) msg.obj;
1732                d.dismiss();
1733                break;
1734            }
1735            }
1736        }
1737    };
1738
1739    static final int COLLECT_PSS_BG_MSG = 1;
1740
1741    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1742        @Override
1743        public void handleMessage(Message msg) {
1744            switch (msg.what) {
1745            case COLLECT_PSS_BG_MSG: {
1746                long start = SystemClock.uptimeMillis();
1747                MemInfoReader memInfo = null;
1748                synchronized (ActivityManagerService.this) {
1749                    if (mFullPssPending) {
1750                        mFullPssPending = false;
1751                        memInfo = new MemInfoReader();
1752                    }
1753                }
1754                if (memInfo != null) {
1755                    updateCpuStatsNow();
1756                    long nativeTotalPss = 0;
1757                    synchronized (mProcessCpuTracker) {
1758                        final int N = mProcessCpuTracker.countStats();
1759                        for (int j=0; j<N; j++) {
1760                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1761                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1762                                // This is definitely an application process; skip it.
1763                                continue;
1764                            }
1765                            synchronized (mPidsSelfLocked) {
1766                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1767                                    // This is one of our own processes; skip it.
1768                                    continue;
1769                                }
1770                            }
1771                            nativeTotalPss += Debug.getPss(st.pid, null);
1772                        }
1773                    }
1774                    memInfo.readMemInfo();
1775                    synchronized (ActivityManagerService.this) {
1776                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1777                                + (SystemClock.uptimeMillis()-start) + "ms");
1778                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1779                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1780                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1781                    }
1782                }
1783
1784                int i = 0;
1785                int num = 0;
1786                long[] tmp = new long[1];
1787                do {
1788                    ProcessRecord proc;
1789                    int procState;
1790                    int pid;
1791                    synchronized (ActivityManagerService.this) {
1792                        if (i >= mPendingPssProcesses.size()) {
1793                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1794                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1795                            mPendingPssProcesses.clear();
1796                            return;
1797                        }
1798                        proc = mPendingPssProcesses.get(i);
1799                        procState = proc.pssProcState;
1800                        if (proc.thread != null && procState == proc.setProcState) {
1801                            pid = proc.pid;
1802                        } else {
1803                            proc = null;
1804                            pid = 0;
1805                        }
1806                        i++;
1807                    }
1808                    if (proc != null) {
1809                        long pss = Debug.getPss(pid, tmp);
1810                        synchronized (ActivityManagerService.this) {
1811                            if (proc.thread != null && proc.setProcState == procState
1812                                    && proc.pid == pid) {
1813                                num++;
1814                                proc.lastPssTime = SystemClock.uptimeMillis();
1815                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1816                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1817                                        + ": " + pss + " lastPss=" + proc.lastPss
1818                                        + " state=" + ProcessList.makeProcStateString(procState));
1819                                if (proc.initialIdlePss == 0) {
1820                                    proc.initialIdlePss = pss;
1821                                }
1822                                proc.lastPss = pss;
1823                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1824                                    proc.lastCachedPss = pss;
1825                                }
1826                            }
1827                        }
1828                    }
1829                } while (true);
1830            }
1831            }
1832        }
1833    };
1834
1835    /**
1836     * Monitor for package changes and update our internal state.
1837     */
1838    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1839        @Override
1840        public void onPackageRemoved(String packageName, int uid) {
1841            // Remove all tasks with activities in the specified package from the list of recent tasks
1842            final int eventUserId = getChangingUserId();
1843            synchronized (ActivityManagerService.this) {
1844                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1845                    TaskRecord tr = mRecentTasks.get(i);
1846                    if (tr.userId != eventUserId) continue;
1847
1848                    ComponentName cn = tr.intent.getComponent();
1849                    if (cn != null && cn.getPackageName().equals(packageName)) {
1850                        // If the package name matches, remove the task
1851                        removeTaskByIdLocked(tr.taskId, true);
1852                    }
1853                }
1854            }
1855        }
1856
1857        @Override
1858        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1859            onPackageModified(packageName);
1860            return true;
1861        }
1862
1863        @Override
1864        public void onPackageModified(String packageName) {
1865            final int eventUserId = getChangingUserId();
1866            final IPackageManager pm = AppGlobals.getPackageManager();
1867            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1868                    new ArrayList<Pair<Intent, Integer>>();
1869            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1870            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1871            // Copy the list of recent tasks so that we don't hold onto the lock on
1872            // ActivityManagerService for long periods while checking if components exist.
1873            synchronized (ActivityManagerService.this) {
1874                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1875                    TaskRecord tr = mRecentTasks.get(i);
1876                    if (tr.userId != eventUserId) continue;
1877
1878                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1879                }
1880            }
1881            // Check the recent tasks and filter out all tasks with components that no longer exist.
1882            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1883                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1884                ComponentName cn = p.first.getComponent();
1885                if (cn != null && cn.getPackageName().equals(packageName)) {
1886                    if (componentsKnownToExist.contains(cn)) {
1887                        // If we know that the component still exists in the package, then skip
1888                        continue;
1889                    }
1890                    try {
1891                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1892                        if (info != null) {
1893                            componentsKnownToExist.add(cn);
1894                        } else {
1895                            tasksToRemove.add(p.second);
1896                        }
1897                    } catch (RemoteException e) {
1898                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1899                    }
1900                }
1901            }
1902            // Prune all the tasks with removed components from the list of recent tasks
1903            synchronized (ActivityManagerService.this) {
1904                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1905                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1906                }
1907            }
1908        }
1909
1910        @Override
1911        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1912            // Force stop the specified packages
1913            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1914            if (packages != null) {
1915                for (String pkg : packages) {
1916                    synchronized (ActivityManagerService.this) {
1917                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1918                                userId, "finished booting")) {
1919                            return true;
1920                        }
1921                    }
1922                }
1923            }
1924            return false;
1925        }
1926    };
1927
1928    public void setSystemProcess() {
1929        try {
1930            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1931            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1932            ServiceManager.addService("meminfo", new MemBinder(this));
1933            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1934            ServiceManager.addService("dbinfo", new DbBinder(this));
1935            if (MONITOR_CPU_USAGE) {
1936                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1937            }
1938            ServiceManager.addService("permission", new PermissionController(this));
1939
1940            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1941                    "android", STOCK_PM_FLAGS);
1942            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1943
1944            synchronized (this) {
1945                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1946                app.persistent = true;
1947                app.pid = MY_PID;
1948                app.maxAdj = ProcessList.SYSTEM_ADJ;
1949                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1950                mProcessNames.put(app.processName, app.uid, app);
1951                synchronized (mPidsSelfLocked) {
1952                    mPidsSelfLocked.put(app.pid, app);
1953                }
1954                updateLruProcessLocked(app, false, null);
1955                updateOomAdjLocked();
1956            }
1957        } catch (PackageManager.NameNotFoundException e) {
1958            throw new RuntimeException(
1959                    "Unable to find android system package", e);
1960        }
1961    }
1962
1963    public void setWindowManager(WindowManagerService wm) {
1964        mWindowManager = wm;
1965        mStackSupervisor.setWindowManager(wm);
1966    }
1967
1968    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1969        mUsageStatsService = usageStatsManager;
1970    }
1971
1972    public void startObservingNativeCrashes() {
1973        final NativeCrashListener ncl = new NativeCrashListener(this);
1974        ncl.start();
1975    }
1976
1977    public IAppOpsService getAppOpsService() {
1978        return mAppOpsService;
1979    }
1980
1981    static class MemBinder extends Binder {
1982        ActivityManagerService mActivityManagerService;
1983        MemBinder(ActivityManagerService activityManagerService) {
1984            mActivityManagerService = activityManagerService;
1985        }
1986
1987        @Override
1988        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1989            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1990                    != PackageManager.PERMISSION_GRANTED) {
1991                pw.println("Permission Denial: can't dump meminfo from from pid="
1992                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1993                        + " without permission " + android.Manifest.permission.DUMP);
1994                return;
1995            }
1996
1997            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1998        }
1999    }
2000
2001    static class GraphicsBinder extends Binder {
2002        ActivityManagerService mActivityManagerService;
2003        GraphicsBinder(ActivityManagerService activityManagerService) {
2004            mActivityManagerService = activityManagerService;
2005        }
2006
2007        @Override
2008        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2009            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2010                    != PackageManager.PERMISSION_GRANTED) {
2011                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2012                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2013                        + " without permission " + android.Manifest.permission.DUMP);
2014                return;
2015            }
2016
2017            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2018        }
2019    }
2020
2021    static class DbBinder extends Binder {
2022        ActivityManagerService mActivityManagerService;
2023        DbBinder(ActivityManagerService activityManagerService) {
2024            mActivityManagerService = activityManagerService;
2025        }
2026
2027        @Override
2028        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2029            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2030                    != PackageManager.PERMISSION_GRANTED) {
2031                pw.println("Permission Denial: can't dump dbinfo from from pid="
2032                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2033                        + " without permission " + android.Manifest.permission.DUMP);
2034                return;
2035            }
2036
2037            mActivityManagerService.dumpDbInfo(fd, pw, args);
2038        }
2039    }
2040
2041    static class CpuBinder extends Binder {
2042        ActivityManagerService mActivityManagerService;
2043        CpuBinder(ActivityManagerService activityManagerService) {
2044            mActivityManagerService = activityManagerService;
2045        }
2046
2047        @Override
2048        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2049            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2050                    != PackageManager.PERMISSION_GRANTED) {
2051                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2052                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2053                        + " without permission " + android.Manifest.permission.DUMP);
2054                return;
2055            }
2056
2057            synchronized (mActivityManagerService.mProcessCpuTracker) {
2058                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2059                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2060                        SystemClock.uptimeMillis()));
2061            }
2062        }
2063    }
2064
2065    public static final class Lifecycle extends SystemService {
2066        private final ActivityManagerService mService;
2067
2068        public Lifecycle(Context context) {
2069            super(context);
2070            mService = new ActivityManagerService(context);
2071        }
2072
2073        @Override
2074        public void onStart() {
2075            mService.start();
2076        }
2077
2078        public ActivityManagerService getService() {
2079            return mService;
2080        }
2081    }
2082
2083    // Note: This method is invoked on the main thread but may need to attach various
2084    // handlers to other threads.  So take care to be explicit about the looper.
2085    public ActivityManagerService(Context systemContext) {
2086        mContext = systemContext;
2087        mFactoryTest = FactoryTest.getMode();
2088        mSystemThread = ActivityThread.currentActivityThread();
2089
2090        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2091
2092        mHandlerThread = new ServiceThread(TAG,
2093                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2094        mHandlerThread.start();
2095        mHandler = new MainHandler(mHandlerThread.getLooper());
2096
2097        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2098                "foreground", BROADCAST_FG_TIMEOUT, false);
2099        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2100                "background", BROADCAST_BG_TIMEOUT, true);
2101        mBroadcastQueues[0] = mFgBroadcastQueue;
2102        mBroadcastQueues[1] = mBgBroadcastQueue;
2103
2104        mServices = new ActiveServices(this);
2105        mProviderMap = new ProviderMap(this);
2106
2107        // TODO: Move creation of battery stats service outside of activity manager service.
2108        File dataDir = Environment.getDataDirectory();
2109        File systemDir = new File(dataDir, "system");
2110        systemDir.mkdirs();
2111        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2112        mBatteryStatsService.getActiveStatistics().readLocked();
2113        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2114        mOnBattery = DEBUG_POWER ? true
2115                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2116        mBatteryStatsService.getActiveStatistics().setCallback(this);
2117
2118        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2119
2120        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2121
2122        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2123
2124        // User 0 is the first and only user that runs at boot.
2125        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2126        mUserLru.add(Integer.valueOf(0));
2127        updateStartedUserArrayLocked();
2128
2129        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2130            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2131
2132        mConfiguration.setToDefaults();
2133        mConfiguration.setLocale(Locale.getDefault());
2134
2135        mConfigurationSeq = mConfiguration.seq = 1;
2136        mProcessCpuTracker.init();
2137
2138        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2139        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2140        mStackSupervisor = new ActivityStackSupervisor(this);
2141        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2142
2143        mProcessCpuThread = new Thread("CpuTracker") {
2144            @Override
2145            public void run() {
2146                while (true) {
2147                    try {
2148                        try {
2149                            synchronized(this) {
2150                                final long now = SystemClock.uptimeMillis();
2151                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2152                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2153                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2154                                //        + ", write delay=" + nextWriteDelay);
2155                                if (nextWriteDelay < nextCpuDelay) {
2156                                    nextCpuDelay = nextWriteDelay;
2157                                }
2158                                if (nextCpuDelay > 0) {
2159                                    mProcessCpuMutexFree.set(true);
2160                                    this.wait(nextCpuDelay);
2161                                }
2162                            }
2163                        } catch (InterruptedException e) {
2164                        }
2165                        updateCpuStatsNow();
2166                    } catch (Exception e) {
2167                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2168                    }
2169                }
2170            }
2171        };
2172
2173        Watchdog.getInstance().addMonitor(this);
2174        Watchdog.getInstance().addThread(mHandler);
2175    }
2176
2177    public void setSystemServiceManager(SystemServiceManager mgr) {
2178        mSystemServiceManager = mgr;
2179    }
2180
2181    public void setInstaller(Installer installer) {
2182        mInstaller = installer;
2183    }
2184
2185    private void start() {
2186        Process.removeAllProcessGroups();
2187        mProcessCpuThread.start();
2188
2189        mBatteryStatsService.publish(mContext);
2190        mAppOpsService.publish(mContext);
2191        Slog.d("AppOps", "AppOpsService published");
2192        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2193    }
2194
2195    public void initPowerManagement() {
2196        mStackSupervisor.initPowerManagement();
2197        mBatteryStatsService.initPowerManagement();
2198    }
2199
2200    @Override
2201    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2202            throws RemoteException {
2203        if (code == SYSPROPS_TRANSACTION) {
2204            // We need to tell all apps about the system property change.
2205            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2206            synchronized(this) {
2207                final int NP = mProcessNames.getMap().size();
2208                for (int ip=0; ip<NP; ip++) {
2209                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2210                    final int NA = apps.size();
2211                    for (int ia=0; ia<NA; ia++) {
2212                        ProcessRecord app = apps.valueAt(ia);
2213                        if (app.thread != null) {
2214                            procs.add(app.thread.asBinder());
2215                        }
2216                    }
2217                }
2218            }
2219
2220            int N = procs.size();
2221            for (int i=0; i<N; i++) {
2222                Parcel data2 = Parcel.obtain();
2223                try {
2224                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2225                } catch (RemoteException e) {
2226                }
2227                data2.recycle();
2228            }
2229        }
2230        try {
2231            return super.onTransact(code, data, reply, flags);
2232        } catch (RuntimeException e) {
2233            // The activity manager only throws security exceptions, so let's
2234            // log all others.
2235            if (!(e instanceof SecurityException)) {
2236                Slog.wtf(TAG, "Activity Manager Crash", e);
2237            }
2238            throw e;
2239        }
2240    }
2241
2242    void updateCpuStats() {
2243        final long now = SystemClock.uptimeMillis();
2244        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2245            return;
2246        }
2247        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2248            synchronized (mProcessCpuThread) {
2249                mProcessCpuThread.notify();
2250            }
2251        }
2252    }
2253
2254    void updateCpuStatsNow() {
2255        synchronized (mProcessCpuTracker) {
2256            mProcessCpuMutexFree.set(false);
2257            final long now = SystemClock.uptimeMillis();
2258            boolean haveNewCpuStats = false;
2259
2260            if (MONITOR_CPU_USAGE &&
2261                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2262                mLastCpuTime.set(now);
2263                haveNewCpuStats = true;
2264                mProcessCpuTracker.update();
2265                //Slog.i(TAG, mProcessCpu.printCurrentState());
2266                //Slog.i(TAG, "Total CPU usage: "
2267                //        + mProcessCpu.getTotalCpuPercent() + "%");
2268
2269                // Slog the cpu usage if the property is set.
2270                if ("true".equals(SystemProperties.get("events.cpu"))) {
2271                    int user = mProcessCpuTracker.getLastUserTime();
2272                    int system = mProcessCpuTracker.getLastSystemTime();
2273                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2274                    int irq = mProcessCpuTracker.getLastIrqTime();
2275                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2276                    int idle = mProcessCpuTracker.getLastIdleTime();
2277
2278                    int total = user + system + iowait + irq + softIrq + idle;
2279                    if (total == 0) total = 1;
2280
2281                    EventLog.writeEvent(EventLogTags.CPU,
2282                            ((user+system+iowait+irq+softIrq) * 100) / total,
2283                            (user * 100) / total,
2284                            (system * 100) / total,
2285                            (iowait * 100) / total,
2286                            (irq * 100) / total,
2287                            (softIrq * 100) / total);
2288                }
2289            }
2290
2291            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2292            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2293            synchronized(bstats) {
2294                synchronized(mPidsSelfLocked) {
2295                    if (haveNewCpuStats) {
2296                        if (mOnBattery) {
2297                            int perc = bstats.startAddingCpuLocked();
2298                            int totalUTime = 0;
2299                            int totalSTime = 0;
2300                            final int N = mProcessCpuTracker.countStats();
2301                            for (int i=0; i<N; i++) {
2302                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2303                                if (!st.working) {
2304                                    continue;
2305                                }
2306                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2307                                int otherUTime = (st.rel_utime*perc)/100;
2308                                int otherSTime = (st.rel_stime*perc)/100;
2309                                totalUTime += otherUTime;
2310                                totalSTime += otherSTime;
2311                                if (pr != null) {
2312                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2313                                    if (ps == null || !ps.isActive()) {
2314                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2315                                                pr.info.uid, pr.processName);
2316                                    }
2317                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2318                                            st.rel_stime-otherSTime);
2319                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2320                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2321                                } else {
2322                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2323                                    if (ps == null || !ps.isActive()) {
2324                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2325                                                bstats.mapUid(st.uid), st.name);
2326                                    }
2327                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2328                                            st.rel_stime-otherSTime);
2329                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2330                                }
2331                            }
2332                            bstats.finishAddingCpuLocked(perc, totalUTime,
2333                                    totalSTime, cpuSpeedTimes);
2334                        }
2335                    }
2336                }
2337
2338                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2339                    mLastWriteTime = now;
2340                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2341                }
2342            }
2343        }
2344    }
2345
2346    @Override
2347    public void batteryNeedsCpuUpdate() {
2348        updateCpuStatsNow();
2349    }
2350
2351    @Override
2352    public void batteryPowerChanged(boolean onBattery) {
2353        // When plugging in, update the CPU stats first before changing
2354        // the plug state.
2355        updateCpuStatsNow();
2356        synchronized (this) {
2357            synchronized(mPidsSelfLocked) {
2358                mOnBattery = DEBUG_POWER ? true : onBattery;
2359            }
2360        }
2361    }
2362
2363    /**
2364     * Initialize the application bind args. These are passed to each
2365     * process when the bindApplication() IPC is sent to the process. They're
2366     * lazily setup to make sure the services are running when they're asked for.
2367     */
2368    private HashMap<String, IBinder> getCommonServicesLocked() {
2369        if (mAppBindArgs == null) {
2370            mAppBindArgs = new HashMap<String, IBinder>();
2371
2372            // Setup the application init args
2373            mAppBindArgs.put("package", ServiceManager.getService("package"));
2374            mAppBindArgs.put("window", ServiceManager.getService("window"));
2375            mAppBindArgs.put(Context.ALARM_SERVICE,
2376                    ServiceManager.getService(Context.ALARM_SERVICE));
2377        }
2378        return mAppBindArgs;
2379    }
2380
2381    final void setFocusedActivityLocked(ActivityRecord r) {
2382        if (mFocusedActivity != r) {
2383            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2384            mFocusedActivity = r;
2385            if (r.task != null && r.task.voiceInteractor != null) {
2386                startRunningVoiceLocked();
2387            } else {
2388                finishRunningVoiceLocked();
2389            }
2390            mStackSupervisor.setFocusedStack(r);
2391            if (r != null) {
2392                mWindowManager.setFocusedApp(r.appToken, true);
2393            }
2394            applyUpdateLockStateLocked(r);
2395        }
2396    }
2397
2398    final void clearFocusedActivity(ActivityRecord r) {
2399        if (mFocusedActivity == r) {
2400            mFocusedActivity = null;
2401        }
2402    }
2403
2404    @Override
2405    public void setFocusedStack(int stackId) {
2406        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2407        synchronized (ActivityManagerService.this) {
2408            ActivityStack stack = mStackSupervisor.getStack(stackId);
2409            if (stack != null) {
2410                ActivityRecord r = stack.topRunningActivityLocked(null);
2411                if (r != null) {
2412                    setFocusedActivityLocked(r);
2413                }
2414            }
2415        }
2416    }
2417
2418    @Override
2419    public void notifyActivityDrawn(IBinder token) {
2420        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2421        synchronized (this) {
2422            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2423            if (r != null) {
2424                r.task.stack.notifyActivityDrawnLocked(r);
2425            }
2426        }
2427    }
2428
2429    final void applyUpdateLockStateLocked(ActivityRecord r) {
2430        // Modifications to the UpdateLock state are done on our handler, outside
2431        // the activity manager's locks.  The new state is determined based on the
2432        // state *now* of the relevant activity record.  The object is passed to
2433        // the handler solely for logging detail, not to be consulted/modified.
2434        final boolean nextState = r != null && r.immersive;
2435        mHandler.sendMessage(
2436                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2437    }
2438
2439    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2440        Message msg = Message.obtain();
2441        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2442        msg.obj = r.task.askedCompatMode ? null : r;
2443        mHandler.sendMessage(msg);
2444    }
2445
2446    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2447            String what, Object obj, ProcessRecord srcApp) {
2448        app.lastActivityTime = now;
2449
2450        if (app.activities.size() > 0) {
2451            // Don't want to touch dependent processes that are hosting activities.
2452            return index;
2453        }
2454
2455        int lrui = mLruProcesses.lastIndexOf(app);
2456        if (lrui < 0) {
2457            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2458                    + what + " " + obj + " from " + srcApp);
2459            return index;
2460        }
2461
2462        if (lrui >= index) {
2463            // Don't want to cause this to move dependent processes *back* in the
2464            // list as if they were less frequently used.
2465            return index;
2466        }
2467
2468        if (lrui >= mLruProcessActivityStart) {
2469            // Don't want to touch dependent processes that are hosting activities.
2470            return index;
2471        }
2472
2473        mLruProcesses.remove(lrui);
2474        if (index > 0) {
2475            index--;
2476        }
2477        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2478                + " in LRU list: " + app);
2479        mLruProcesses.add(index, app);
2480        return index;
2481    }
2482
2483    final void removeLruProcessLocked(ProcessRecord app) {
2484        int lrui = mLruProcesses.lastIndexOf(app);
2485        if (lrui >= 0) {
2486            if (!app.killed) {
2487                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2488                Process.killProcessQuiet(app.pid);
2489                Process.killProcessGroup(app.info.uid, app.pid);
2490            }
2491            if (lrui <= mLruProcessActivityStart) {
2492                mLruProcessActivityStart--;
2493            }
2494            if (lrui <= mLruProcessServiceStart) {
2495                mLruProcessServiceStart--;
2496            }
2497            mLruProcesses.remove(lrui);
2498        }
2499    }
2500
2501    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2502            ProcessRecord client) {
2503        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2504                || app.treatLikeActivity;
2505        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2506        if (!activityChange && hasActivity) {
2507            // The process has activities, so we are only allowing activity-based adjustments
2508            // to move it.  It should be kept in the front of the list with other
2509            // processes that have activities, and we don't want those to change their
2510            // order except due to activity operations.
2511            return;
2512        }
2513
2514        mLruSeq++;
2515        final long now = SystemClock.uptimeMillis();
2516        app.lastActivityTime = now;
2517
2518        // First a quick reject: if the app is already at the position we will
2519        // put it, then there is nothing to do.
2520        if (hasActivity) {
2521            final int N = mLruProcesses.size();
2522            if (N > 0 && mLruProcesses.get(N-1) == app) {
2523                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2524                return;
2525            }
2526        } else {
2527            if (mLruProcessServiceStart > 0
2528                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2529                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2530                return;
2531            }
2532        }
2533
2534        int lrui = mLruProcesses.lastIndexOf(app);
2535
2536        if (app.persistent && lrui >= 0) {
2537            // We don't care about the position of persistent processes, as long as
2538            // they are in the list.
2539            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2540            return;
2541        }
2542
2543        /* In progress: compute new position first, so we can avoid doing work
2544           if the process is not actually going to move.  Not yet working.
2545        int addIndex;
2546        int nextIndex;
2547        boolean inActivity = false, inService = false;
2548        if (hasActivity) {
2549            // Process has activities, put it at the very tipsy-top.
2550            addIndex = mLruProcesses.size();
2551            nextIndex = mLruProcessServiceStart;
2552            inActivity = true;
2553        } else if (hasService) {
2554            // Process has services, put it at the top of the service list.
2555            addIndex = mLruProcessActivityStart;
2556            nextIndex = mLruProcessServiceStart;
2557            inActivity = true;
2558            inService = true;
2559        } else  {
2560            // Process not otherwise of interest, it goes to the top of the non-service area.
2561            addIndex = mLruProcessServiceStart;
2562            if (client != null) {
2563                int clientIndex = mLruProcesses.lastIndexOf(client);
2564                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2565                        + app);
2566                if (clientIndex >= 0 && addIndex > clientIndex) {
2567                    addIndex = clientIndex;
2568                }
2569            }
2570            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2571        }
2572
2573        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2574                + mLruProcessActivityStart + "): " + app);
2575        */
2576
2577        if (lrui >= 0) {
2578            if (lrui < mLruProcessActivityStart) {
2579                mLruProcessActivityStart--;
2580            }
2581            if (lrui < mLruProcessServiceStart) {
2582                mLruProcessServiceStart--;
2583            }
2584            /*
2585            if (addIndex > lrui) {
2586                addIndex--;
2587            }
2588            if (nextIndex > lrui) {
2589                nextIndex--;
2590            }
2591            */
2592            mLruProcesses.remove(lrui);
2593        }
2594
2595        /*
2596        mLruProcesses.add(addIndex, app);
2597        if (inActivity) {
2598            mLruProcessActivityStart++;
2599        }
2600        if (inService) {
2601            mLruProcessActivityStart++;
2602        }
2603        */
2604
2605        int nextIndex;
2606        if (hasActivity) {
2607            final int N = mLruProcesses.size();
2608            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2609                // Process doesn't have activities, but has clients with
2610                // activities...  move it up, but one below the top (the top
2611                // should always have a real activity).
2612                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2613                mLruProcesses.add(N-1, app);
2614                // To keep it from spamming the LRU list (by making a bunch of clients),
2615                // we will push down any other entries owned by the app.
2616                final int uid = app.info.uid;
2617                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2618                    ProcessRecord subProc = mLruProcesses.get(i);
2619                    if (subProc.info.uid == uid) {
2620                        // We want to push this one down the list.  If the process after
2621                        // it is for the same uid, however, don't do so, because we don't
2622                        // want them internally to be re-ordered.
2623                        if (mLruProcesses.get(i-1).info.uid != uid) {
2624                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2625                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2626                            ProcessRecord tmp = mLruProcesses.get(i);
2627                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2628                            mLruProcesses.set(i-1, tmp);
2629                            i--;
2630                        }
2631                    } else {
2632                        // A gap, we can stop here.
2633                        break;
2634                    }
2635                }
2636            } else {
2637                // Process has activities, put it at the very tipsy-top.
2638                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2639                mLruProcesses.add(app);
2640            }
2641            nextIndex = mLruProcessServiceStart;
2642        } else if (hasService) {
2643            // Process has services, put it at the top of the service list.
2644            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2645            mLruProcesses.add(mLruProcessActivityStart, app);
2646            nextIndex = mLruProcessServiceStart;
2647            mLruProcessActivityStart++;
2648        } else  {
2649            // Process not otherwise of interest, it goes to the top of the non-service area.
2650            int index = mLruProcessServiceStart;
2651            if (client != null) {
2652                // If there is a client, don't allow the process to be moved up higher
2653                // in the list than that client.
2654                int clientIndex = mLruProcesses.lastIndexOf(client);
2655                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2656                        + " when updating " + app);
2657                if (clientIndex <= lrui) {
2658                    // Don't allow the client index restriction to push it down farther in the
2659                    // list than it already is.
2660                    clientIndex = lrui;
2661                }
2662                if (clientIndex >= 0 && index > clientIndex) {
2663                    index = clientIndex;
2664                }
2665            }
2666            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2667            mLruProcesses.add(index, app);
2668            nextIndex = index-1;
2669            mLruProcessActivityStart++;
2670            mLruProcessServiceStart++;
2671        }
2672
2673        // If the app is currently using a content provider or service,
2674        // bump those processes as well.
2675        for (int j=app.connections.size()-1; j>=0; j--) {
2676            ConnectionRecord cr = app.connections.valueAt(j);
2677            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2678                    && cr.binding.service.app != null
2679                    && cr.binding.service.app.lruSeq != mLruSeq
2680                    && !cr.binding.service.app.persistent) {
2681                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2682                        "service connection", cr, app);
2683            }
2684        }
2685        for (int j=app.conProviders.size()-1; j>=0; j--) {
2686            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2687            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2688                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2689                        "provider reference", cpr, app);
2690            }
2691        }
2692    }
2693
2694    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2695        if (uid == Process.SYSTEM_UID) {
2696            // The system gets to run in any process.  If there are multiple
2697            // processes with the same uid, just pick the first (this
2698            // should never happen).
2699            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2700            if (procs == null) return null;
2701            final int N = procs.size();
2702            for (int i = 0; i < N; i++) {
2703                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2704            }
2705        }
2706        ProcessRecord proc = mProcessNames.get(processName, uid);
2707        if (false && proc != null && !keepIfLarge
2708                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2709                && proc.lastCachedPss >= 4000) {
2710            // Turn this condition on to cause killing to happen regularly, for testing.
2711            if (proc.baseProcessTracker != null) {
2712                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2713            }
2714            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2715        } else if (proc != null && !keepIfLarge
2716                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2717                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2718            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2719            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2720                if (proc.baseProcessTracker != null) {
2721                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2722                }
2723                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2724            }
2725        }
2726        return proc;
2727    }
2728
2729    void ensurePackageDexOpt(String packageName) {
2730        IPackageManager pm = AppGlobals.getPackageManager();
2731        try {
2732            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2733                mDidDexOpt = true;
2734            }
2735        } catch (RemoteException e) {
2736        }
2737    }
2738
2739    boolean isNextTransitionForward() {
2740        int transit = mWindowManager.getPendingAppTransition();
2741        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2742                || transit == AppTransition.TRANSIT_TASK_OPEN
2743                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2744    }
2745
2746    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2747            String processName, String abiOverride, int uid, Runnable crashHandler) {
2748        synchronized(this) {
2749            ApplicationInfo info = new ApplicationInfo();
2750            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2751            // For isolated processes, the former contains the parent's uid and the latter the
2752            // actual uid of the isolated process.
2753            // In the special case introduced by this method (which is, starting an isolated
2754            // process directly from the SystemServer without an actual parent app process) the
2755            // closest thing to a parent's uid is SYSTEM_UID.
2756            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2757            // the |isolated| logic in the ProcessRecord constructor.
2758            info.uid = Process.SYSTEM_UID;
2759            info.processName = processName;
2760            info.className = entryPoint;
2761            info.packageName = "android";
2762            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2763                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2764                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2765                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2766                    crashHandler);
2767            return proc != null ? proc.pid : 0;
2768        }
2769    }
2770
2771    final ProcessRecord startProcessLocked(String processName,
2772            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2773            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2774            boolean isolated, boolean keepIfLarge) {
2775        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2776                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2777                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2778                null /* crashHandler */);
2779    }
2780
2781    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2782            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2783            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2784            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2785        long startTime = SystemClock.elapsedRealtime();
2786        ProcessRecord app;
2787        if (!isolated) {
2788            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2789            checkTime(startTime, "startProcess: after getProcessRecord");
2790        } else {
2791            // If this is an isolated process, it can't re-use an existing process.
2792            app = null;
2793        }
2794        // We don't have to do anything more if:
2795        // (1) There is an existing application record; and
2796        // (2) The caller doesn't think it is dead, OR there is no thread
2797        //     object attached to it so we know it couldn't have crashed; and
2798        // (3) There is a pid assigned to it, so it is either starting or
2799        //     already running.
2800        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2801                + " app=" + app + " knownToBeDead=" + knownToBeDead
2802                + " thread=" + (app != null ? app.thread : null)
2803                + " pid=" + (app != null ? app.pid : -1));
2804        if (app != null && app.pid > 0) {
2805            if (!knownToBeDead || app.thread == null) {
2806                // We already have the app running, or are waiting for it to
2807                // come up (we have a pid but not yet its thread), so keep it.
2808                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2809                // If this is a new package in the process, add the package to the list
2810                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2811                checkTime(startTime, "startProcess: done, added package to proc");
2812                return app;
2813            }
2814
2815            // An application record is attached to a previous process,
2816            // clean it up now.
2817            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2818            checkTime(startTime, "startProcess: bad proc running, killing");
2819            Process.killProcessGroup(app.info.uid, app.pid);
2820            handleAppDiedLocked(app, true, true);
2821            checkTime(startTime, "startProcess: done killing old proc");
2822        }
2823
2824        String hostingNameStr = hostingName != null
2825                ? hostingName.flattenToShortString() : null;
2826
2827        if (!isolated) {
2828            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2829                // If we are in the background, then check to see if this process
2830                // is bad.  If so, we will just silently fail.
2831                if (mBadProcesses.get(info.processName, info.uid) != null) {
2832                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2833                            + "/" + info.processName);
2834                    return null;
2835                }
2836            } else {
2837                // When the user is explicitly starting a process, then clear its
2838                // crash count so that we won't make it bad until they see at
2839                // least one crash dialog again, and make the process good again
2840                // if it had been bad.
2841                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2842                        + "/" + info.processName);
2843                mProcessCrashTimes.remove(info.processName, info.uid);
2844                if (mBadProcesses.get(info.processName, info.uid) != null) {
2845                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2846                            UserHandle.getUserId(info.uid), info.uid,
2847                            info.processName);
2848                    mBadProcesses.remove(info.processName, info.uid);
2849                    if (app != null) {
2850                        app.bad = false;
2851                    }
2852                }
2853            }
2854        }
2855
2856        if (app == null) {
2857            checkTime(startTime, "startProcess: creating new process record");
2858            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2859            app.crashHandler = crashHandler;
2860            if (app == null) {
2861                Slog.w(TAG, "Failed making new process record for "
2862                        + processName + "/" + info.uid + " isolated=" + isolated);
2863                return null;
2864            }
2865            mProcessNames.put(processName, app.uid, app);
2866            if (isolated) {
2867                mIsolatedProcesses.put(app.uid, app);
2868            }
2869            checkTime(startTime, "startProcess: done creating new process record");
2870        } else {
2871            // If this is a new package in the process, add the package to the list
2872            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2873            checkTime(startTime, "startProcess: added package to existing proc");
2874        }
2875
2876        // If the system is not ready yet, then hold off on starting this
2877        // process until it is.
2878        if (!mProcessesReady
2879                && !isAllowedWhileBooting(info)
2880                && !allowWhileBooting) {
2881            if (!mProcessesOnHold.contains(app)) {
2882                mProcessesOnHold.add(app);
2883            }
2884            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2885            checkTime(startTime, "startProcess: returning with proc on hold");
2886            return app;
2887        }
2888
2889        checkTime(startTime, "startProcess: stepping in to startProcess");
2890        startProcessLocked(
2891                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2892        checkTime(startTime, "startProcess: done starting proc!");
2893        return (app.pid != 0) ? app : null;
2894    }
2895
2896    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2897        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2898    }
2899
2900    private final void startProcessLocked(ProcessRecord app,
2901            String hostingType, String hostingNameStr) {
2902        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2903                null /* entryPoint */, null /* entryPointArgs */);
2904    }
2905
2906    private final void startProcessLocked(ProcessRecord app, String hostingType,
2907            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2908        long startTime = SystemClock.elapsedRealtime();
2909        if (app.pid > 0 && app.pid != MY_PID) {
2910            checkTime(startTime, "startProcess: removing from pids map");
2911            synchronized (mPidsSelfLocked) {
2912                mPidsSelfLocked.remove(app.pid);
2913                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2914            }
2915            checkTime(startTime, "startProcess: done removing from pids map");
2916            app.setPid(0);
2917        }
2918
2919        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2920                "startProcessLocked removing on hold: " + app);
2921        mProcessesOnHold.remove(app);
2922
2923        checkTime(startTime, "startProcess: starting to update cpu stats");
2924        updateCpuStats();
2925        checkTime(startTime, "startProcess: done updating cpu stats");
2926
2927        try {
2928            int uid = app.uid;
2929
2930            int[] gids = null;
2931            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2932            if (!app.isolated) {
2933                int[] permGids = null;
2934                try {
2935                    checkTime(startTime, "startProcess: getting gids from package manager");
2936                    final PackageManager pm = mContext.getPackageManager();
2937                    permGids = pm.getPackageGids(app.info.packageName);
2938
2939                    if (Environment.isExternalStorageEmulated()) {
2940                        checkTime(startTime, "startProcess: checking external storage perm");
2941                        if (pm.checkPermission(
2942                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2943                                app.info.packageName) == PERMISSION_GRANTED) {
2944                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2945                        } else {
2946                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2947                        }
2948                    }
2949                } catch (PackageManager.NameNotFoundException e) {
2950                    Slog.w(TAG, "Unable to retrieve gids", e);
2951                }
2952
2953                /*
2954                 * Add shared application and profile GIDs so applications can share some
2955                 * resources like shared libraries and access user-wide resources
2956                 */
2957                if (permGids == null) {
2958                    gids = new int[2];
2959                } else {
2960                    gids = new int[permGids.length + 2];
2961                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2962                }
2963                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2964                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2965            }
2966            checkTime(startTime, "startProcess: building args");
2967            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2968                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2969                        && mTopComponent != null
2970                        && app.processName.equals(mTopComponent.getPackageName())) {
2971                    uid = 0;
2972                }
2973                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2974                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2975                    uid = 0;
2976                }
2977            }
2978            int debugFlags = 0;
2979            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2980                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2981                // Also turn on CheckJNI for debuggable apps. It's quite
2982                // awkward to turn on otherwise.
2983                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2984            }
2985            // Run the app in safe mode if its manifest requests so or the
2986            // system is booted in safe mode.
2987            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2988                mSafeMode == true) {
2989                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2990            }
2991            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2992                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2993            }
2994            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2995                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2996            }
2997            if ("1".equals(SystemProperties.get("debug.assert"))) {
2998                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2999            }
3000
3001            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3002            if (requiredAbi == null) {
3003                requiredAbi = Build.SUPPORTED_ABIS[0];
3004            }
3005
3006            String instructionSet = null;
3007            if (app.info.primaryCpuAbi != null) {
3008                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3009            }
3010
3011            // Start the process.  It will either succeed and return a result containing
3012            // the PID of the new process, or else throw a RuntimeException.
3013            boolean isActivityProcess = (entryPoint == null);
3014            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3015            checkTime(startTime, "startProcess: asking zygote to start proc");
3016            Process.ProcessStartResult startResult = Process.start(entryPoint,
3017                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3018                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3019                    app.info.dataDir, entryPointArgs);
3020            checkTime(startTime, "startProcess: returned from zygote!");
3021
3022            if (app.isolated) {
3023                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3024            }
3025            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3026            checkTime(startTime, "startProcess: done updating battery stats");
3027
3028            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3029                    UserHandle.getUserId(uid), startResult.pid, uid,
3030                    app.processName, hostingType,
3031                    hostingNameStr != null ? hostingNameStr : "");
3032
3033            if (app.persistent) {
3034                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3035            }
3036
3037            checkTime(startTime, "startProcess: building log message");
3038            StringBuilder buf = mStringBuilder;
3039            buf.setLength(0);
3040            buf.append("Start proc ");
3041            buf.append(app.processName);
3042            if (!isActivityProcess) {
3043                buf.append(" [");
3044                buf.append(entryPoint);
3045                buf.append("]");
3046            }
3047            buf.append(" for ");
3048            buf.append(hostingType);
3049            if (hostingNameStr != null) {
3050                buf.append(" ");
3051                buf.append(hostingNameStr);
3052            }
3053            buf.append(": pid=");
3054            buf.append(startResult.pid);
3055            buf.append(" uid=");
3056            buf.append(uid);
3057            buf.append(" gids={");
3058            if (gids != null) {
3059                for (int gi=0; gi<gids.length; gi++) {
3060                    if (gi != 0) buf.append(", ");
3061                    buf.append(gids[gi]);
3062
3063                }
3064            }
3065            buf.append("}");
3066            if (requiredAbi != null) {
3067                buf.append(" abi=");
3068                buf.append(requiredAbi);
3069            }
3070            Slog.i(TAG, buf.toString());
3071            app.setPid(startResult.pid);
3072            app.usingWrapper = startResult.usingWrapper;
3073            app.removed = false;
3074            app.killed = false;
3075            app.killedByAm = false;
3076            checkTime(startTime, "startProcess: starting to update pids map");
3077            synchronized (mPidsSelfLocked) {
3078                this.mPidsSelfLocked.put(startResult.pid, app);
3079                if (isActivityProcess) {
3080                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3081                    msg.obj = app;
3082                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3083                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3084                }
3085            }
3086            checkTime(startTime, "startProcess: done updating pids map");
3087        } catch (RuntimeException e) {
3088            // XXX do better error recovery.
3089            app.setPid(0);
3090            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3091            if (app.isolated) {
3092                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3093            }
3094            Slog.e(TAG, "Failure starting process " + app.processName, e);
3095        }
3096    }
3097
3098    void updateUsageStats(ActivityRecord component, boolean resumed) {
3099        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3100        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3101        if (resumed) {
3102            if (mUsageStatsService != null) {
3103                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3104                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3105            }
3106            synchronized (stats) {
3107                stats.noteActivityResumedLocked(component.app.uid);
3108            }
3109        } else {
3110            if (mUsageStatsService != null) {
3111                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3112                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3113            }
3114            synchronized (stats) {
3115                stats.noteActivityPausedLocked(component.app.uid);
3116            }
3117        }
3118    }
3119
3120    Intent getHomeIntent() {
3121        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3122        intent.setComponent(mTopComponent);
3123        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3124            intent.addCategory(Intent.CATEGORY_HOME);
3125        }
3126        return intent;
3127    }
3128
3129    boolean startHomeActivityLocked(int userId) {
3130        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3131                && mTopAction == null) {
3132            // We are running in factory test mode, but unable to find
3133            // the factory test app, so just sit around displaying the
3134            // error message and don't try to start anything.
3135            return false;
3136        }
3137        Intent intent = getHomeIntent();
3138        ActivityInfo aInfo =
3139            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3140        if (aInfo != null) {
3141            intent.setComponent(new ComponentName(
3142                    aInfo.applicationInfo.packageName, aInfo.name));
3143            // Don't do this if the home app is currently being
3144            // instrumented.
3145            aInfo = new ActivityInfo(aInfo);
3146            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3147            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3148                    aInfo.applicationInfo.uid, true);
3149            if (app == null || app.instrumentationClass == null) {
3150                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3151                mStackSupervisor.startHomeActivity(intent, aInfo);
3152            }
3153        }
3154
3155        return true;
3156    }
3157
3158    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3159        ActivityInfo ai = null;
3160        ComponentName comp = intent.getComponent();
3161        try {
3162            if (comp != null) {
3163                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3164            } else {
3165                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3166                        intent,
3167                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3168                            flags, userId);
3169
3170                if (info != null) {
3171                    ai = info.activityInfo;
3172                }
3173            }
3174        } catch (RemoteException e) {
3175            // ignore
3176        }
3177
3178        return ai;
3179    }
3180
3181    /**
3182     * Starts the "new version setup screen" if appropriate.
3183     */
3184    void startSetupActivityLocked() {
3185        // Only do this once per boot.
3186        if (mCheckedForSetup) {
3187            return;
3188        }
3189
3190        // We will show this screen if the current one is a different
3191        // version than the last one shown, and we are not running in
3192        // low-level factory test mode.
3193        final ContentResolver resolver = mContext.getContentResolver();
3194        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3195                Settings.Global.getInt(resolver,
3196                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3197            mCheckedForSetup = true;
3198
3199            // See if we should be showing the platform update setup UI.
3200            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3201            List<ResolveInfo> ris = mContext.getPackageManager()
3202                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3203
3204            // We don't allow third party apps to replace this.
3205            ResolveInfo ri = null;
3206            for (int i=0; ris != null && i<ris.size(); i++) {
3207                if ((ris.get(i).activityInfo.applicationInfo.flags
3208                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3209                    ri = ris.get(i);
3210                    break;
3211                }
3212            }
3213
3214            if (ri != null) {
3215                String vers = ri.activityInfo.metaData != null
3216                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3217                        : null;
3218                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3219                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3220                            Intent.METADATA_SETUP_VERSION);
3221                }
3222                String lastVers = Settings.Secure.getString(
3223                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3224                if (vers != null && !vers.equals(lastVers)) {
3225                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3226                    intent.setComponent(new ComponentName(
3227                            ri.activityInfo.packageName, ri.activityInfo.name));
3228                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3229                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3230                            null);
3231                }
3232            }
3233        }
3234    }
3235
3236    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3237        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3238    }
3239
3240    void enforceNotIsolatedCaller(String caller) {
3241        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3242            throw new SecurityException("Isolated process not allowed to call " + caller);
3243        }
3244    }
3245
3246    void enforceShellRestriction(String restriction, int userHandle) {
3247        if (Binder.getCallingUid() == Process.SHELL_UID) {
3248            if (userHandle < 0
3249                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3250                throw new SecurityException("Shell does not have permission to access user "
3251                        + userHandle);
3252            }
3253        }
3254    }
3255
3256    @Override
3257    public int getFrontActivityScreenCompatMode() {
3258        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3259        synchronized (this) {
3260            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3261        }
3262    }
3263
3264    @Override
3265    public void setFrontActivityScreenCompatMode(int mode) {
3266        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3267                "setFrontActivityScreenCompatMode");
3268        synchronized (this) {
3269            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3270        }
3271    }
3272
3273    @Override
3274    public int getPackageScreenCompatMode(String packageName) {
3275        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3276        synchronized (this) {
3277            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3278        }
3279    }
3280
3281    @Override
3282    public void setPackageScreenCompatMode(String packageName, int mode) {
3283        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3284                "setPackageScreenCompatMode");
3285        synchronized (this) {
3286            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3287        }
3288    }
3289
3290    @Override
3291    public boolean getPackageAskScreenCompat(String packageName) {
3292        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3293        synchronized (this) {
3294            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3295        }
3296    }
3297
3298    @Override
3299    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3300        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3301                "setPackageAskScreenCompat");
3302        synchronized (this) {
3303            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3304        }
3305    }
3306
3307    private void dispatchProcessesChanged() {
3308        int N;
3309        synchronized (this) {
3310            N = mPendingProcessChanges.size();
3311            if (mActiveProcessChanges.length < N) {
3312                mActiveProcessChanges = new ProcessChangeItem[N];
3313            }
3314            mPendingProcessChanges.toArray(mActiveProcessChanges);
3315            mAvailProcessChanges.addAll(mPendingProcessChanges);
3316            mPendingProcessChanges.clear();
3317            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3318        }
3319
3320        int i = mProcessObservers.beginBroadcast();
3321        while (i > 0) {
3322            i--;
3323            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3324            if (observer != null) {
3325                try {
3326                    for (int j=0; j<N; j++) {
3327                        ProcessChangeItem item = mActiveProcessChanges[j];
3328                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3329                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3330                                    + item.pid + " uid=" + item.uid + ": "
3331                                    + item.foregroundActivities);
3332                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3333                                    item.foregroundActivities);
3334                        }
3335                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3336                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3337                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3338                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3339                        }
3340                    }
3341                } catch (RemoteException e) {
3342                }
3343            }
3344        }
3345        mProcessObservers.finishBroadcast();
3346    }
3347
3348    private void dispatchProcessDied(int pid, int uid) {
3349        int i = mProcessObservers.beginBroadcast();
3350        while (i > 0) {
3351            i--;
3352            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3353            if (observer != null) {
3354                try {
3355                    observer.onProcessDied(pid, uid);
3356                } catch (RemoteException e) {
3357                }
3358            }
3359        }
3360        mProcessObservers.finishBroadcast();
3361    }
3362
3363    @Override
3364    public final int startActivity(IApplicationThread caller, String callingPackage,
3365            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3366            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3367        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3368            resultWho, requestCode, startFlags, profilerInfo, options,
3369            UserHandle.getCallingUserId());
3370    }
3371
3372    @Override
3373    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3374            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3375            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3376        enforceNotIsolatedCaller("startActivity");
3377        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3378                false, ALLOW_FULL_ONLY, "startActivity", null);
3379        // TODO: Switch to user app stacks here.
3380        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3381                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3382                profilerInfo, null, null, options, userId, null, null);
3383    }
3384
3385    @Override
3386    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3387            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3388            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3389
3390        // This is very dangerous -- it allows you to perform a start activity (including
3391        // permission grants) as any app that may launch one of your own activities.  So
3392        // we will only allow this to be done from activities that are part of the core framework,
3393        // and then only when they are running as the system.
3394        final ActivityRecord sourceRecord;
3395        final int targetUid;
3396        final String targetPackage;
3397        synchronized (this) {
3398            if (resultTo == null) {
3399                throw new SecurityException("Must be called from an activity");
3400            }
3401            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3402            if (sourceRecord == null) {
3403                throw new SecurityException("Called with bad activity token: " + resultTo);
3404            }
3405            if (!sourceRecord.info.packageName.equals("android")) {
3406                throw new SecurityException(
3407                        "Must be called from an activity that is declared in the android package");
3408            }
3409            if (sourceRecord.app == null) {
3410                throw new SecurityException("Called without a process attached to activity");
3411            }
3412            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3413                // This is still okay, as long as this activity is running under the
3414                // uid of the original calling activity.
3415                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3416                    throw new SecurityException(
3417                            "Calling activity in uid " + sourceRecord.app.uid
3418                                    + " must be system uid or original calling uid "
3419                                    + sourceRecord.launchedFromUid);
3420                }
3421            }
3422            targetUid = sourceRecord.launchedFromUid;
3423            targetPackage = sourceRecord.launchedFromPackage;
3424        }
3425
3426        if (userId == UserHandle.USER_NULL) {
3427            userId = UserHandle.getUserId(sourceRecord.app.uid);
3428        }
3429
3430        // TODO: Switch to user app stacks here.
3431        try {
3432            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3433                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3434                    null, null, options, userId, null, null);
3435            return ret;
3436        } catch (SecurityException e) {
3437            // XXX need to figure out how to propagate to original app.
3438            // A SecurityException here is generally actually a fault of the original
3439            // calling activity (such as a fairly granting permissions), so propagate it
3440            // back to them.
3441            /*
3442            StringBuilder msg = new StringBuilder();
3443            msg.append("While launching");
3444            msg.append(intent.toString());
3445            msg.append(": ");
3446            msg.append(e.getMessage());
3447            */
3448            throw e;
3449        }
3450    }
3451
3452    @Override
3453    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3454            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3455            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3456        enforceNotIsolatedCaller("startActivityAndWait");
3457        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3458                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3459        WaitResult res = new WaitResult();
3460        // TODO: Switch to user app stacks here.
3461        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3462                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3463                options, userId, null, null);
3464        return res;
3465    }
3466
3467    @Override
3468    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3469            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3470            int startFlags, Configuration config, Bundle options, int userId) {
3471        enforceNotIsolatedCaller("startActivityWithConfig");
3472        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3473                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3474        // TODO: Switch to user app stacks here.
3475        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3476                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3477                null, null, config, options, userId, null, null);
3478        return ret;
3479    }
3480
3481    @Override
3482    public int startActivityIntentSender(IApplicationThread caller,
3483            IntentSender intent, Intent fillInIntent, String resolvedType,
3484            IBinder resultTo, String resultWho, int requestCode,
3485            int flagsMask, int flagsValues, Bundle options) {
3486        enforceNotIsolatedCaller("startActivityIntentSender");
3487        // Refuse possible leaked file descriptors
3488        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3489            throw new IllegalArgumentException("File descriptors passed in Intent");
3490        }
3491
3492        IIntentSender sender = intent.getTarget();
3493        if (!(sender instanceof PendingIntentRecord)) {
3494            throw new IllegalArgumentException("Bad PendingIntent object");
3495        }
3496
3497        PendingIntentRecord pir = (PendingIntentRecord)sender;
3498
3499        synchronized (this) {
3500            // If this is coming from the currently resumed activity, it is
3501            // effectively saying that app switches are allowed at this point.
3502            final ActivityStack stack = getFocusedStack();
3503            if (stack.mResumedActivity != null &&
3504                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3505                mAppSwitchesAllowedTime = 0;
3506            }
3507        }
3508        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3509                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3510        return ret;
3511    }
3512
3513    @Override
3514    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3515            Intent intent, String resolvedType, IVoiceInteractionSession session,
3516            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3517            Bundle options, int userId) {
3518        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3519                != PackageManager.PERMISSION_GRANTED) {
3520            String msg = "Permission Denial: startVoiceActivity() from pid="
3521                    + Binder.getCallingPid()
3522                    + ", uid=" + Binder.getCallingUid()
3523                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3524            Slog.w(TAG, msg);
3525            throw new SecurityException(msg);
3526        }
3527        if (session == null || interactor == null) {
3528            throw new NullPointerException("null session or interactor");
3529        }
3530        userId = handleIncomingUser(callingPid, callingUid, userId,
3531                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3532        // TODO: Switch to user app stacks here.
3533        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3534                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3535                null, options, userId, null, null);
3536    }
3537
3538    @Override
3539    public boolean startNextMatchingActivity(IBinder callingActivity,
3540            Intent intent, Bundle options) {
3541        // Refuse possible leaked file descriptors
3542        if (intent != null && intent.hasFileDescriptors() == true) {
3543            throw new IllegalArgumentException("File descriptors passed in Intent");
3544        }
3545
3546        synchronized (this) {
3547            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3548            if (r == null) {
3549                ActivityOptions.abort(options);
3550                return false;
3551            }
3552            if (r.app == null || r.app.thread == null) {
3553                // The caller is not running...  d'oh!
3554                ActivityOptions.abort(options);
3555                return false;
3556            }
3557            intent = new Intent(intent);
3558            // The caller is not allowed to change the data.
3559            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3560            // And we are resetting to find the next component...
3561            intent.setComponent(null);
3562
3563            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3564
3565            ActivityInfo aInfo = null;
3566            try {
3567                List<ResolveInfo> resolves =
3568                    AppGlobals.getPackageManager().queryIntentActivities(
3569                            intent, r.resolvedType,
3570                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3571                            UserHandle.getCallingUserId());
3572
3573                // Look for the original activity in the list...
3574                final int N = resolves != null ? resolves.size() : 0;
3575                for (int i=0; i<N; i++) {
3576                    ResolveInfo rInfo = resolves.get(i);
3577                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3578                            && rInfo.activityInfo.name.equals(r.info.name)) {
3579                        // We found the current one...  the next matching is
3580                        // after it.
3581                        i++;
3582                        if (i<N) {
3583                            aInfo = resolves.get(i).activityInfo;
3584                        }
3585                        if (debug) {
3586                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3587                                    + "/" + r.info.name);
3588                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3589                                    + "/" + aInfo.name);
3590                        }
3591                        break;
3592                    }
3593                }
3594            } catch (RemoteException e) {
3595            }
3596
3597            if (aInfo == null) {
3598                // Nobody who is next!
3599                ActivityOptions.abort(options);
3600                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3601                return false;
3602            }
3603
3604            intent.setComponent(new ComponentName(
3605                    aInfo.applicationInfo.packageName, aInfo.name));
3606            intent.setFlags(intent.getFlags()&~(
3607                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3608                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3609                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3610                    Intent.FLAG_ACTIVITY_NEW_TASK));
3611
3612            // Okay now we need to start the new activity, replacing the
3613            // currently running activity.  This is a little tricky because
3614            // we want to start the new one as if the current one is finished,
3615            // but not finish the current one first so that there is no flicker.
3616            // And thus...
3617            final boolean wasFinishing = r.finishing;
3618            r.finishing = true;
3619
3620            // Propagate reply information over to the new activity.
3621            final ActivityRecord resultTo = r.resultTo;
3622            final String resultWho = r.resultWho;
3623            final int requestCode = r.requestCode;
3624            r.resultTo = null;
3625            if (resultTo != null) {
3626                resultTo.removeResultsLocked(r, resultWho, requestCode);
3627            }
3628
3629            final long origId = Binder.clearCallingIdentity();
3630            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3631                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3632                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3633                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3634            Binder.restoreCallingIdentity(origId);
3635
3636            r.finishing = wasFinishing;
3637            if (res != ActivityManager.START_SUCCESS) {
3638                return false;
3639            }
3640            return true;
3641        }
3642    }
3643
3644    @Override
3645    public final int startActivityFromRecents(int taskId, Bundle options) {
3646        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3647            String msg = "Permission Denial: startActivityFromRecents called without " +
3648                    START_TASKS_FROM_RECENTS;
3649            Slog.w(TAG, msg);
3650            throw new SecurityException(msg);
3651        }
3652        return startActivityFromRecentsInner(taskId, options);
3653    }
3654
3655    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3656        final TaskRecord task;
3657        final int callingUid;
3658        final String callingPackage;
3659        final Intent intent;
3660        final int userId;
3661        synchronized (this) {
3662            task = recentTaskForIdLocked(taskId);
3663            if (task == null) {
3664                throw new IllegalArgumentException("Task " + taskId + " not found.");
3665            }
3666            callingUid = task.mCallingUid;
3667            callingPackage = task.mCallingPackage;
3668            intent = task.intent;
3669            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3670            userId = task.userId;
3671        }
3672        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3673                options, userId, null, task);
3674    }
3675
3676    final int startActivityInPackage(int uid, String callingPackage,
3677            Intent intent, String resolvedType, IBinder resultTo,
3678            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3679            IActivityContainer container, TaskRecord inTask) {
3680
3681        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3682                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3683
3684        // TODO: Switch to user app stacks here.
3685        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3686                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3687                null, null, null, options, userId, container, inTask);
3688        return ret;
3689    }
3690
3691    @Override
3692    public final int startActivities(IApplicationThread caller, String callingPackage,
3693            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3694            int userId) {
3695        enforceNotIsolatedCaller("startActivities");
3696        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3697                false, ALLOW_FULL_ONLY, "startActivity", null);
3698        // TODO: Switch to user app stacks here.
3699        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3700                resolvedTypes, resultTo, options, userId);
3701        return ret;
3702    }
3703
3704    final int startActivitiesInPackage(int uid, String callingPackage,
3705            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3706            Bundle options, int userId) {
3707
3708        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3709                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3710        // TODO: Switch to user app stacks here.
3711        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3712                resultTo, options, userId);
3713        return ret;
3714    }
3715
3716    //explicitly remove thd old information in mRecentTasks when removing existing user.
3717    private void removeRecentTasksForUserLocked(int userId) {
3718        if(userId <= 0) {
3719            Slog.i(TAG, "Can't remove recent task on user " + userId);
3720            return;
3721        }
3722
3723        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3724            TaskRecord tr = mRecentTasks.get(i);
3725            if (tr.userId == userId) {
3726                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3727                        + " when finishing user" + userId);
3728                mRecentTasks.remove(i);
3729                tr.removedFromRecents(mTaskPersister);
3730            }
3731        }
3732
3733        // Remove tasks from persistent storage.
3734        mTaskPersister.wakeup(null, true);
3735    }
3736
3737    // Sort by taskId
3738    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3739        @Override
3740        public int compare(TaskRecord lhs, TaskRecord rhs) {
3741            return rhs.taskId - lhs.taskId;
3742        }
3743    };
3744
3745    // Extract the affiliates of the chain containing mRecentTasks[start].
3746    private int processNextAffiliateChain(int start) {
3747        final TaskRecord startTask = mRecentTasks.get(start);
3748        final int affiliateId = startTask.mAffiliatedTaskId;
3749
3750        // Quick identification of isolated tasks. I.e. those not launched behind.
3751        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3752                startTask.mNextAffiliate == null) {
3753            // There is still a slim chance that there are other tasks that point to this task
3754            // and that the chain is so messed up that this task no longer points to them but
3755            // the gain of this optimization outweighs the risk.
3756            startTask.inRecents = true;
3757            return start + 1;
3758        }
3759
3760        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3761        mTmpRecents.clear();
3762        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3763            final TaskRecord task = mRecentTasks.get(i);
3764            if (task.mAffiliatedTaskId == affiliateId) {
3765                mRecentTasks.remove(i);
3766                mTmpRecents.add(task);
3767            }
3768        }
3769
3770        // Sort them all by taskId. That is the order they were create in and that order will
3771        // always be correct.
3772        Collections.sort(mTmpRecents, mTaskRecordComparator);
3773
3774        // Go through and fix up the linked list.
3775        // The first one is the end of the chain and has no next.
3776        final TaskRecord first = mTmpRecents.get(0);
3777        first.inRecents = true;
3778        if (first.mNextAffiliate != null) {
3779            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3780            first.setNextAffiliate(null);
3781            mTaskPersister.wakeup(first, false);
3782        }
3783        // Everything in the middle is doubly linked from next to prev.
3784        final int tmpSize = mTmpRecents.size();
3785        for (int i = 0; i < tmpSize - 1; ++i) {
3786            final TaskRecord next = mTmpRecents.get(i);
3787            final TaskRecord prev = mTmpRecents.get(i + 1);
3788            if (next.mPrevAffiliate != prev) {
3789                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3790                        " setting prev=" + prev);
3791                next.setPrevAffiliate(prev);
3792                mTaskPersister.wakeup(next, false);
3793            }
3794            if (prev.mNextAffiliate != next) {
3795                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3796                        " setting next=" + next);
3797                prev.setNextAffiliate(next);
3798                mTaskPersister.wakeup(prev, false);
3799            }
3800            prev.inRecents = true;
3801        }
3802        // The last one is the beginning of the list and has no prev.
3803        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3804        if (last.mPrevAffiliate != null) {
3805            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3806            last.setPrevAffiliate(null);
3807            mTaskPersister.wakeup(last, false);
3808        }
3809
3810        // Insert the group back into mRecentTasks at start.
3811        mRecentTasks.addAll(start, mTmpRecents);
3812
3813        // Let the caller know where we left off.
3814        return start + tmpSize;
3815    }
3816
3817    /**
3818     * Update the recent tasks lists: make sure tasks should still be here (their
3819     * applications / activities still exist), update their availability, fixup ordering
3820     * of affiliations.
3821     */
3822    void cleanupRecentTasksLocked(int userId) {
3823        if (mRecentTasks == null) {
3824            // Happens when called from the packagemanager broadcast before boot.
3825            return;
3826        }
3827
3828        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3829        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3830        final IPackageManager pm = AppGlobals.getPackageManager();
3831        final ActivityInfo dummyAct = new ActivityInfo();
3832        final ApplicationInfo dummyApp = new ApplicationInfo();
3833
3834        int N = mRecentTasks.size();
3835
3836        int[] users = userId == UserHandle.USER_ALL
3837                ? getUsersLocked() : new int[] { userId };
3838        for (int user : users) {
3839            for (int i = 0; i < N; i++) {
3840                TaskRecord task = mRecentTasks.get(i);
3841                if (task.userId != user) {
3842                    // Only look at tasks for the user ID of interest.
3843                    continue;
3844                }
3845                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3846                    // This situation is broken, and we should just get rid of it now.
3847                    mRecentTasks.remove(i);
3848                    task.removedFromRecents(mTaskPersister);
3849                    i--;
3850                    N--;
3851                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3852                    continue;
3853                }
3854                // Check whether this activity is currently available.
3855                if (task.realActivity != null) {
3856                    ActivityInfo ai = availActCache.get(task.realActivity);
3857                    if (ai == null) {
3858                        try {
3859                            ai = pm.getActivityInfo(task.realActivity,
3860                                    PackageManager.GET_UNINSTALLED_PACKAGES
3861                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3862                        } catch (RemoteException e) {
3863                            // Will never happen.
3864                            continue;
3865                        }
3866                        if (ai == null) {
3867                            ai = dummyAct;
3868                        }
3869                        availActCache.put(task.realActivity, ai);
3870                    }
3871                    if (ai == dummyAct) {
3872                        // This could be either because the activity no longer exists, or the
3873                        // app is temporarily gone.  For the former we want to remove the recents
3874                        // entry; for the latter we want to mark it as unavailable.
3875                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3876                        if (app == null) {
3877                            try {
3878                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3879                                        PackageManager.GET_UNINSTALLED_PACKAGES
3880                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3881                            } catch (RemoteException e) {
3882                                // Will never happen.
3883                                continue;
3884                            }
3885                            if (app == null) {
3886                                app = dummyApp;
3887                            }
3888                            availAppCache.put(task.realActivity.getPackageName(), app);
3889                        }
3890                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3891                            // Doesn't exist any more!  Good-bye.
3892                            mRecentTasks.remove(i);
3893                            task.removedFromRecents(mTaskPersister);
3894                            i--;
3895                            N--;
3896                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3897                            continue;
3898                        } else {
3899                            // Otherwise just not available for now.
3900                            if (task.isAvailable) {
3901                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3902                                        + task);
3903                            }
3904                            task.isAvailable = false;
3905                        }
3906                    } else {
3907                        if (!ai.enabled || !ai.applicationInfo.enabled
3908                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3909                            if (task.isAvailable) {
3910                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3911                                        + task + " (enabled=" + ai.enabled + "/"
3912                                        + ai.applicationInfo.enabled +  " flags="
3913                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3914                            }
3915                            task.isAvailable = false;
3916                        } else {
3917                            if (!task.isAvailable) {
3918                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3919                                        + task);
3920                            }
3921                            task.isAvailable = true;
3922                        }
3923                    }
3924                }
3925            }
3926        }
3927
3928        // Verify the affiliate chain for each task.
3929        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3930        }
3931
3932        mTmpRecents.clear();
3933        // mRecentTasks is now in sorted, affiliated order.
3934    }
3935
3936    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3937        int N = mRecentTasks.size();
3938        TaskRecord top = task;
3939        int topIndex = taskIndex;
3940        while (top.mNextAffiliate != null && topIndex > 0) {
3941            top = top.mNextAffiliate;
3942            topIndex--;
3943        }
3944        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3945                + topIndex + " from intial " + taskIndex);
3946        // Find the end of the chain, doing a sanity check along the way.
3947        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3948        int endIndex = topIndex;
3949        TaskRecord prev = top;
3950        while (endIndex < N) {
3951            TaskRecord cur = mRecentTasks.get(endIndex);
3952            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3953                    + endIndex + " " + cur);
3954            if (cur == top) {
3955                // Verify start of the chain.
3956                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3957                    Slog.wtf(TAG, "Bad chain @" + endIndex
3958                            + ": first task has next affiliate: " + prev);
3959                    sane = false;
3960                    break;
3961                }
3962            } else {
3963                // Verify middle of the chain's next points back to the one before.
3964                if (cur.mNextAffiliate != prev
3965                        || cur.mNextAffiliateTaskId != prev.taskId) {
3966                    Slog.wtf(TAG, "Bad chain @" + endIndex
3967                            + ": middle task " + cur + " @" + endIndex
3968                            + " has bad next affiliate "
3969                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3970                            + ", expected " + prev);
3971                    sane = false;
3972                    break;
3973                }
3974            }
3975            if (cur.mPrevAffiliateTaskId == -1) {
3976                // Chain ends here.
3977                if (cur.mPrevAffiliate != null) {
3978                    Slog.wtf(TAG, "Bad chain @" + endIndex
3979                            + ": last task " + cur + " has previous affiliate "
3980                            + cur.mPrevAffiliate);
3981                    sane = false;
3982                }
3983                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3984                break;
3985            } else {
3986                // Verify middle of the chain's prev points to a valid item.
3987                if (cur.mPrevAffiliate == null) {
3988                    Slog.wtf(TAG, "Bad chain @" + endIndex
3989                            + ": task " + cur + " has previous affiliate "
3990                            + cur.mPrevAffiliate + " but should be id "
3991                            + cur.mPrevAffiliate);
3992                    sane = false;
3993                    break;
3994                }
3995            }
3996            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3997                Slog.wtf(TAG, "Bad chain @" + endIndex
3998                        + ": task " + cur + " has affiliated id "
3999                        + cur.mAffiliatedTaskId + " but should be "
4000                        + task.mAffiliatedTaskId);
4001                sane = false;
4002                break;
4003            }
4004            prev = cur;
4005            endIndex++;
4006            if (endIndex >= N) {
4007                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4008                        + ": last task " + prev);
4009                sane = false;
4010                break;
4011            }
4012        }
4013        if (sane) {
4014            if (endIndex < taskIndex) {
4015                Slog.wtf(TAG, "Bad chain @" + endIndex
4016                        + ": did not extend to task " + task + " @" + taskIndex);
4017                sane = false;
4018            }
4019        }
4020        if (sane) {
4021            // All looks good, we can just move all of the affiliated tasks
4022            // to the top.
4023            for (int i=topIndex; i<=endIndex; i++) {
4024                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4025                        + " from " + i + " to " + (i-topIndex));
4026                TaskRecord cur = mRecentTasks.remove(i);
4027                mRecentTasks.add(i-topIndex, cur);
4028            }
4029            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4030                    + " to " + endIndex);
4031            return true;
4032        }
4033
4034        // Whoops, couldn't do it.
4035        return false;
4036    }
4037
4038    final void addRecentTaskLocked(TaskRecord task) {
4039        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4040                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4041
4042        int N = mRecentTasks.size();
4043        // Quick case: check if the top-most recent task is the same.
4044        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4045            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4046            return;
4047        }
4048        // Another quick case: check if this is part of a set of affiliated
4049        // tasks that are at the top.
4050        if (isAffiliated && N > 0 && task.inRecents
4051                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4052            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4053                    + " at top when adding " + task);
4054            return;
4055        }
4056        // Another quick case: never add voice sessions.
4057        if (task.voiceSession != null) {
4058            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4059            return;
4060        }
4061
4062        boolean needAffiliationFix = false;
4063
4064        // Slightly less quick case: the task is already in recents, so all we need
4065        // to do is move it.
4066        if (task.inRecents) {
4067            int taskIndex = mRecentTasks.indexOf(task);
4068            if (taskIndex >= 0) {
4069                if (!isAffiliated) {
4070                    // Simple case: this is not an affiliated task, so we just move it to the front.
4071                    mRecentTasks.remove(taskIndex);
4072                    mRecentTasks.add(0, task);
4073                    notifyTaskPersisterLocked(task, false);
4074                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4075                            + " from " + taskIndex);
4076                    return;
4077                } else {
4078                    // More complicated: need to keep all affiliated tasks together.
4079                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4080                        // All went well.
4081                        return;
4082                    }
4083
4084                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4085                    // everything and then go through our general path of adding a new task.
4086                    needAffiliationFix = true;
4087                }
4088            } else {
4089                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4090                needAffiliationFix = true;
4091            }
4092        }
4093
4094        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4095        trimRecentsForTask(task, true);
4096
4097        N = mRecentTasks.size();
4098        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4099            final TaskRecord tr = mRecentTasks.remove(N - 1);
4100            tr.removedFromRecents(mTaskPersister);
4101            N--;
4102        }
4103        task.inRecents = true;
4104        if (!isAffiliated || needAffiliationFix) {
4105            // If this is a simple non-affiliated task, or we had some failure trying to
4106            // handle it as part of an affilated task, then just place it at the top.
4107            mRecentTasks.add(0, task);
4108        } else if (isAffiliated) {
4109            // If this is a new affiliated task, then move all of the affiliated tasks
4110            // to the front and insert this new one.
4111            TaskRecord other = task.mNextAffiliate;
4112            if (other == null) {
4113                other = task.mPrevAffiliate;
4114            }
4115            if (other != null) {
4116                int otherIndex = mRecentTasks.indexOf(other);
4117                if (otherIndex >= 0) {
4118                    // Insert new task at appropriate location.
4119                    int taskIndex;
4120                    if (other == task.mNextAffiliate) {
4121                        // We found the index of our next affiliation, which is who is
4122                        // before us in the list, so add after that point.
4123                        taskIndex = otherIndex+1;
4124                    } else {
4125                        // We found the index of our previous affiliation, which is who is
4126                        // after us in the list, so add at their position.
4127                        taskIndex = otherIndex;
4128                    }
4129                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4130                            + taskIndex + ": " + task);
4131                    mRecentTasks.add(taskIndex, task);
4132
4133                    // Now move everything to the front.
4134                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4135                        // All went well.
4136                        return;
4137                    }
4138
4139                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4140                    // everything and then go through our general path of adding a new task.
4141                    needAffiliationFix = true;
4142                } else {
4143                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4144                            + other);
4145                    needAffiliationFix = true;
4146                }
4147            } else {
4148                if (DEBUG_RECENTS) Slog.d(TAG,
4149                        "addRecent: adding affiliated task without next/prev:" + task);
4150                needAffiliationFix = true;
4151            }
4152        }
4153        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4154
4155        if (needAffiliationFix) {
4156            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4157            cleanupRecentTasksLocked(task.userId);
4158        }
4159    }
4160
4161    /**
4162     * If needed, remove oldest existing entries in recents that are for the same kind
4163     * of task as the given one.
4164     */
4165    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4166        int N = mRecentTasks.size();
4167        final Intent intent = task.intent;
4168        final boolean document = intent != null && intent.isDocument();
4169
4170        int maxRecents = task.maxRecents - 1;
4171        for (int i=0; i<N; i++) {
4172            final TaskRecord tr = mRecentTasks.get(i);
4173            if (task != tr) {
4174                if (task.userId != tr.userId) {
4175                    continue;
4176                }
4177                if (i > MAX_RECENT_BITMAPS) {
4178                    tr.freeLastThumbnail();
4179                }
4180                final Intent trIntent = tr.intent;
4181                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4182                    (intent == null || !intent.filterEquals(trIntent))) {
4183                    continue;
4184                }
4185                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4186                if (document && trIsDocument) {
4187                    // These are the same document activity (not necessarily the same doc).
4188                    if (maxRecents > 0) {
4189                        --maxRecents;
4190                        continue;
4191                    }
4192                    // Hit the maximum number of documents for this task. Fall through
4193                    // and remove this document from recents.
4194                } else if (document || trIsDocument) {
4195                    // Only one of these is a document. Not the droid we're looking for.
4196                    continue;
4197                }
4198            }
4199
4200            if (!doTrim) {
4201                // If the caller is not actually asking for a trim, just tell them we reached
4202                // a point where the trim would happen.
4203                return i;
4204            }
4205
4206            // Either task and tr are the same or, their affinities match or their intents match
4207            // and neither of them is a document, or they are documents using the same activity
4208            // and their maxRecents has been reached.
4209            tr.disposeThumbnail();
4210            mRecentTasks.remove(i);
4211            if (task != tr) {
4212                tr.removedFromRecents(mTaskPersister);
4213            }
4214            i--;
4215            N--;
4216            if (task.intent == null) {
4217                // If the new recent task we are adding is not fully
4218                // specified, then replace it with the existing recent task.
4219                task = tr;
4220            }
4221            notifyTaskPersisterLocked(tr, false);
4222        }
4223
4224        return -1;
4225    }
4226
4227    @Override
4228    public void reportActivityFullyDrawn(IBinder token) {
4229        synchronized (this) {
4230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4231            if (r == null) {
4232                return;
4233            }
4234            r.reportFullyDrawnLocked();
4235        }
4236    }
4237
4238    @Override
4239    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4240        synchronized (this) {
4241            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4242            if (r == null) {
4243                return;
4244            }
4245            final long origId = Binder.clearCallingIdentity();
4246            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4247            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4248                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4249            if (config != null) {
4250                r.frozenBeforeDestroy = true;
4251                if (!updateConfigurationLocked(config, r, false, false)) {
4252                    mStackSupervisor.resumeTopActivitiesLocked();
4253                }
4254            }
4255            Binder.restoreCallingIdentity(origId);
4256        }
4257    }
4258
4259    @Override
4260    public int getRequestedOrientation(IBinder token) {
4261        synchronized (this) {
4262            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4263            if (r == null) {
4264                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4265            }
4266            return mWindowManager.getAppOrientation(r.appToken);
4267        }
4268    }
4269
4270    /**
4271     * This is the internal entry point for handling Activity.finish().
4272     *
4273     * @param token The Binder token referencing the Activity we want to finish.
4274     * @param resultCode Result code, if any, from this Activity.
4275     * @param resultData Result data (Intent), if any, from this Activity.
4276     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4277     *            the root Activity in the task.
4278     *
4279     * @return Returns true if the activity successfully finished, or false if it is still running.
4280     */
4281    @Override
4282    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4283            boolean finishTask) {
4284        // Refuse possible leaked file descriptors
4285        if (resultData != null && resultData.hasFileDescriptors() == true) {
4286            throw new IllegalArgumentException("File descriptors passed in Intent");
4287        }
4288
4289        synchronized(this) {
4290            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4291            if (r == null) {
4292                return true;
4293            }
4294            // Keep track of the root activity of the task before we finish it
4295            TaskRecord tr = r.task;
4296            ActivityRecord rootR = tr.getRootActivity();
4297            if (rootR == null) {
4298                Slog.w(TAG, "Finishing task with all activities already finished");
4299            }
4300            // Do not allow task to finish in Lock Task mode.
4301            if (tr == mStackSupervisor.mLockTaskModeTask) {
4302                if (rootR == r) {
4303                    Slog.i(TAG, "Not finishing task in lock task mode");
4304                    mStackSupervisor.showLockTaskToast();
4305                    return false;
4306                }
4307            }
4308            if (mController != null) {
4309                // Find the first activity that is not finishing.
4310                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4311                if (next != null) {
4312                    // ask watcher if this is allowed
4313                    boolean resumeOK = true;
4314                    try {
4315                        resumeOK = mController.activityResuming(next.packageName);
4316                    } catch (RemoteException e) {
4317                        mController = null;
4318                        Watchdog.getInstance().setActivityController(null);
4319                    }
4320
4321                    if (!resumeOK) {
4322                        Slog.i(TAG, "Not finishing activity because controller resumed");
4323                        return false;
4324                    }
4325                }
4326            }
4327            final long origId = Binder.clearCallingIdentity();
4328            try {
4329                boolean res;
4330                if (finishTask && r == rootR) {
4331                    // If requested, remove the task that is associated to this activity only if it
4332                    // was the root activity in the task. The result code and data is ignored
4333                    // because we don't support returning them across task boundaries.
4334                    res = removeTaskByIdLocked(tr.taskId, false);
4335                    if (!res) {
4336                        Slog.i(TAG, "Removing task failed to finish activity");
4337                    }
4338                } else {
4339                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4340                            resultData, "app-request", true);
4341                    if (!res) {
4342                        Slog.i(TAG, "Failed to finish by app-request");
4343                    }
4344                }
4345                return res;
4346            } finally {
4347                Binder.restoreCallingIdentity(origId);
4348            }
4349        }
4350    }
4351
4352    @Override
4353    public final void finishHeavyWeightApp() {
4354        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4355                != PackageManager.PERMISSION_GRANTED) {
4356            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4357                    + Binder.getCallingPid()
4358                    + ", uid=" + Binder.getCallingUid()
4359                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4360            Slog.w(TAG, msg);
4361            throw new SecurityException(msg);
4362        }
4363
4364        synchronized(this) {
4365            if (mHeavyWeightProcess == null) {
4366                return;
4367            }
4368
4369            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4370                    mHeavyWeightProcess.activities);
4371            for (int i=0; i<activities.size(); i++) {
4372                ActivityRecord r = activities.get(i);
4373                if (!r.finishing) {
4374                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4375                            null, "finish-heavy", true);
4376                }
4377            }
4378
4379            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4380                    mHeavyWeightProcess.userId, 0));
4381            mHeavyWeightProcess = null;
4382        }
4383    }
4384
4385    @Override
4386    public void crashApplication(int uid, int initialPid, String packageName,
4387            String message) {
4388        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4389                != PackageManager.PERMISSION_GRANTED) {
4390            String msg = "Permission Denial: crashApplication() from pid="
4391                    + Binder.getCallingPid()
4392                    + ", uid=" + Binder.getCallingUid()
4393                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4394            Slog.w(TAG, msg);
4395            throw new SecurityException(msg);
4396        }
4397
4398        synchronized(this) {
4399            ProcessRecord proc = null;
4400
4401            // Figure out which process to kill.  We don't trust that initialPid
4402            // still has any relation to current pids, so must scan through the
4403            // list.
4404            synchronized (mPidsSelfLocked) {
4405                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4406                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4407                    if (p.uid != uid) {
4408                        continue;
4409                    }
4410                    if (p.pid == initialPid) {
4411                        proc = p;
4412                        break;
4413                    }
4414                    if (p.pkgList.containsKey(packageName)) {
4415                        proc = p;
4416                    }
4417                }
4418            }
4419
4420            if (proc == null) {
4421                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4422                        + " initialPid=" + initialPid
4423                        + " packageName=" + packageName);
4424                return;
4425            }
4426
4427            if (proc.thread != null) {
4428                if (proc.pid == Process.myPid()) {
4429                    Log.w(TAG, "crashApplication: trying to crash self!");
4430                    return;
4431                }
4432                long ident = Binder.clearCallingIdentity();
4433                try {
4434                    proc.thread.scheduleCrash(message);
4435                } catch (RemoteException e) {
4436                }
4437                Binder.restoreCallingIdentity(ident);
4438            }
4439        }
4440    }
4441
4442    @Override
4443    public final void finishSubActivity(IBinder token, String resultWho,
4444            int requestCode) {
4445        synchronized(this) {
4446            final long origId = Binder.clearCallingIdentity();
4447            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4448            if (r != null) {
4449                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4450            }
4451            Binder.restoreCallingIdentity(origId);
4452        }
4453    }
4454
4455    @Override
4456    public boolean finishActivityAffinity(IBinder token) {
4457        synchronized(this) {
4458            final long origId = Binder.clearCallingIdentity();
4459            try {
4460                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4461
4462                ActivityRecord rootR = r.task.getRootActivity();
4463                // Do not allow task to finish in Lock Task mode.
4464                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4465                    if (rootR == r) {
4466                        mStackSupervisor.showLockTaskToast();
4467                        return false;
4468                    }
4469                }
4470                boolean res = false;
4471                if (r != null) {
4472                    res = r.task.stack.finishActivityAffinityLocked(r);
4473                }
4474                return res;
4475            } finally {
4476                Binder.restoreCallingIdentity(origId);
4477            }
4478        }
4479    }
4480
4481    @Override
4482    public void finishVoiceTask(IVoiceInteractionSession session) {
4483        synchronized(this) {
4484            final long origId = Binder.clearCallingIdentity();
4485            try {
4486                mStackSupervisor.finishVoiceTask(session);
4487            } finally {
4488                Binder.restoreCallingIdentity(origId);
4489            }
4490        }
4491
4492    }
4493
4494    @Override
4495    public boolean releaseActivityInstance(IBinder token) {
4496        synchronized(this) {
4497            final long origId = Binder.clearCallingIdentity();
4498            try {
4499                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4500                if (r.task == null || r.task.stack == null) {
4501                    return false;
4502                }
4503                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4504            } finally {
4505                Binder.restoreCallingIdentity(origId);
4506            }
4507        }
4508    }
4509
4510    @Override
4511    public void releaseSomeActivities(IApplicationThread appInt) {
4512        synchronized(this) {
4513            final long origId = Binder.clearCallingIdentity();
4514            try {
4515                ProcessRecord app = getRecordForAppLocked(appInt);
4516                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4517            } finally {
4518                Binder.restoreCallingIdentity(origId);
4519            }
4520        }
4521    }
4522
4523    @Override
4524    public boolean willActivityBeVisible(IBinder token) {
4525        synchronized(this) {
4526            ActivityStack stack = ActivityRecord.getStackLocked(token);
4527            if (stack != null) {
4528                return stack.willActivityBeVisibleLocked(token);
4529            }
4530            return false;
4531        }
4532    }
4533
4534    @Override
4535    public void overridePendingTransition(IBinder token, String packageName,
4536            int enterAnim, int exitAnim) {
4537        synchronized(this) {
4538            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4539            if (self == null) {
4540                return;
4541            }
4542
4543            final long origId = Binder.clearCallingIdentity();
4544
4545            if (self.state == ActivityState.RESUMED
4546                    || self.state == ActivityState.PAUSING) {
4547                mWindowManager.overridePendingAppTransition(packageName,
4548                        enterAnim, exitAnim, null);
4549            }
4550
4551            Binder.restoreCallingIdentity(origId);
4552        }
4553    }
4554
4555    /**
4556     * Main function for removing an existing process from the activity manager
4557     * as a result of that process going away.  Clears out all connections
4558     * to the process.
4559     */
4560    private final void handleAppDiedLocked(ProcessRecord app,
4561            boolean restarting, boolean allowRestart) {
4562        int pid = app.pid;
4563        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4564        if (!kept && !restarting) {
4565            removeLruProcessLocked(app);
4566            if (pid > 0) {
4567                ProcessList.remove(pid);
4568            }
4569        }
4570
4571        if (mProfileProc == app) {
4572            clearProfilerLocked();
4573        }
4574
4575        // Remove this application's activities from active lists.
4576        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4577
4578        app.activities.clear();
4579
4580        if (app.instrumentationClass != null) {
4581            Slog.w(TAG, "Crash of app " + app.processName
4582                  + " running instrumentation " + app.instrumentationClass);
4583            Bundle info = new Bundle();
4584            info.putString("shortMsg", "Process crashed.");
4585            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4586        }
4587
4588        if (!restarting) {
4589            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4590                // If there was nothing to resume, and we are not already
4591                // restarting this process, but there is a visible activity that
4592                // is hosted by the process...  then make sure all visible
4593                // activities are running, taking care of restarting this
4594                // process.
4595                if (hasVisibleActivities) {
4596                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4597                }
4598            }
4599        }
4600    }
4601
4602    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4603        IBinder threadBinder = thread.asBinder();
4604        // Find the application record.
4605        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4606            ProcessRecord rec = mLruProcesses.get(i);
4607            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4608                return i;
4609            }
4610        }
4611        return -1;
4612    }
4613
4614    final ProcessRecord getRecordForAppLocked(
4615            IApplicationThread thread) {
4616        if (thread == null) {
4617            return null;
4618        }
4619
4620        int appIndex = getLRURecordIndexForAppLocked(thread);
4621        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4622    }
4623
4624    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4625        // If there are no longer any background processes running,
4626        // and the app that died was not running instrumentation,
4627        // then tell everyone we are now low on memory.
4628        boolean haveBg = false;
4629        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4630            ProcessRecord rec = mLruProcesses.get(i);
4631            if (rec.thread != null
4632                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4633                haveBg = true;
4634                break;
4635            }
4636        }
4637
4638        if (!haveBg) {
4639            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4640            if (doReport) {
4641                long now = SystemClock.uptimeMillis();
4642                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4643                    doReport = false;
4644                } else {
4645                    mLastMemUsageReportTime = now;
4646                }
4647            }
4648            final ArrayList<ProcessMemInfo> memInfos
4649                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4650            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4651            long now = SystemClock.uptimeMillis();
4652            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4653                ProcessRecord rec = mLruProcesses.get(i);
4654                if (rec == dyingProc || rec.thread == null) {
4655                    continue;
4656                }
4657                if (doReport) {
4658                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4659                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4660                }
4661                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4662                    // The low memory report is overriding any current
4663                    // state for a GC request.  Make sure to do
4664                    // heavy/important/visible/foreground processes first.
4665                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4666                        rec.lastRequestedGc = 0;
4667                    } else {
4668                        rec.lastRequestedGc = rec.lastLowMemory;
4669                    }
4670                    rec.reportLowMemory = true;
4671                    rec.lastLowMemory = now;
4672                    mProcessesToGc.remove(rec);
4673                    addProcessToGcListLocked(rec);
4674                }
4675            }
4676            if (doReport) {
4677                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4678                mHandler.sendMessage(msg);
4679            }
4680            scheduleAppGcsLocked();
4681        }
4682    }
4683
4684    final void appDiedLocked(ProcessRecord app) {
4685       appDiedLocked(app, app.pid, app.thread);
4686    }
4687
4688    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4689        // First check if this ProcessRecord is actually active for the pid.
4690        synchronized (mPidsSelfLocked) {
4691            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4692            if (curProc != app) {
4693                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4694                return;
4695            }
4696        }
4697
4698        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4699        synchronized (stats) {
4700            stats.noteProcessDiedLocked(app.info.uid, pid);
4701        }
4702
4703        Process.killProcessQuiet(pid);
4704        Process.killProcessGroup(app.info.uid, pid);
4705        app.killed = true;
4706
4707        // Clean up already done if the process has been re-started.
4708        if (app.pid == pid && app.thread != null &&
4709                app.thread.asBinder() == thread.asBinder()) {
4710            boolean doLowMem = app.instrumentationClass == null;
4711            boolean doOomAdj = doLowMem;
4712            if (!app.killedByAm) {
4713                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4714                        + ") has died");
4715                mAllowLowerMemLevel = true;
4716            } else {
4717                // Note that we always want to do oom adj to update our state with the
4718                // new number of procs.
4719                mAllowLowerMemLevel = false;
4720                doLowMem = false;
4721            }
4722            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4723            if (DEBUG_CLEANUP) Slog.v(
4724                TAG, "Dying app: " + app + ", pid: " + pid
4725                + ", thread: " + thread.asBinder());
4726            handleAppDiedLocked(app, false, true);
4727
4728            if (doOomAdj) {
4729                updateOomAdjLocked();
4730            }
4731            if (doLowMem) {
4732                doLowMemReportIfNeededLocked(app);
4733            }
4734        } else if (app.pid != pid) {
4735            // A new process has already been started.
4736            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4737                    + ") has died and restarted (pid " + app.pid + ").");
4738            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4739        } else if (DEBUG_PROCESSES) {
4740            Slog.d(TAG, "Received spurious death notification for thread "
4741                    + thread.asBinder());
4742        }
4743    }
4744
4745    /**
4746     * If a stack trace dump file is configured, dump process stack traces.
4747     * @param clearTraces causes the dump file to be erased prior to the new
4748     *    traces being written, if true; when false, the new traces will be
4749     *    appended to any existing file content.
4750     * @param firstPids of dalvik VM processes to dump stack traces for first
4751     * @param lastPids of dalvik VM processes to dump stack traces for last
4752     * @param nativeProcs optional list of native process names to dump stack crawls
4753     * @return file containing stack traces, or null if no dump file is configured
4754     */
4755    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4756            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4757        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4758        if (tracesPath == null || tracesPath.length() == 0) {
4759            return null;
4760        }
4761
4762        File tracesFile = new File(tracesPath);
4763        try {
4764            File tracesDir = tracesFile.getParentFile();
4765            if (!tracesDir.exists()) {
4766                tracesDir.mkdirs();
4767                if (!SELinux.restorecon(tracesDir)) {
4768                    return null;
4769                }
4770            }
4771            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4772
4773            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4774            tracesFile.createNewFile();
4775            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4776        } catch (IOException e) {
4777            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4778            return null;
4779        }
4780
4781        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4782        return tracesFile;
4783    }
4784
4785    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4786            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4787        // Use a FileObserver to detect when traces finish writing.
4788        // The order of traces is considered important to maintain for legibility.
4789        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4790            @Override
4791            public synchronized void onEvent(int event, String path) { notify(); }
4792        };
4793
4794        try {
4795            observer.startWatching();
4796
4797            // First collect all of the stacks of the most important pids.
4798            if (firstPids != null) {
4799                try {
4800                    int num = firstPids.size();
4801                    for (int i = 0; i < num; i++) {
4802                        synchronized (observer) {
4803                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4804                            observer.wait(200);  // Wait for write-close, give up after 200msec
4805                        }
4806                    }
4807                } catch (InterruptedException e) {
4808                    Slog.wtf(TAG, e);
4809                }
4810            }
4811
4812            // Next collect the stacks of the native pids
4813            if (nativeProcs != null) {
4814                int[] pids = Process.getPidsForCommands(nativeProcs);
4815                if (pids != null) {
4816                    for (int pid : pids) {
4817                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4818                    }
4819                }
4820            }
4821
4822            // Lastly, measure CPU usage.
4823            if (processCpuTracker != null) {
4824                processCpuTracker.init();
4825                System.gc();
4826                processCpuTracker.update();
4827                try {
4828                    synchronized (processCpuTracker) {
4829                        processCpuTracker.wait(500); // measure over 1/2 second.
4830                    }
4831                } catch (InterruptedException e) {
4832                }
4833                processCpuTracker.update();
4834
4835                // We'll take the stack crawls of just the top apps using CPU.
4836                final int N = processCpuTracker.countWorkingStats();
4837                int numProcs = 0;
4838                for (int i=0; i<N && numProcs<5; i++) {
4839                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4840                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4841                        numProcs++;
4842                        try {
4843                            synchronized (observer) {
4844                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4845                                observer.wait(200);  // Wait for write-close, give up after 200msec
4846                            }
4847                        } catch (InterruptedException e) {
4848                            Slog.wtf(TAG, e);
4849                        }
4850
4851                    }
4852                }
4853            }
4854        } finally {
4855            observer.stopWatching();
4856        }
4857    }
4858
4859    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4860        if (true || IS_USER_BUILD) {
4861            return;
4862        }
4863        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4864        if (tracesPath == null || tracesPath.length() == 0) {
4865            return;
4866        }
4867
4868        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4869        StrictMode.allowThreadDiskWrites();
4870        try {
4871            final File tracesFile = new File(tracesPath);
4872            final File tracesDir = tracesFile.getParentFile();
4873            final File tracesTmp = new File(tracesDir, "__tmp__");
4874            try {
4875                if (!tracesDir.exists()) {
4876                    tracesDir.mkdirs();
4877                    if (!SELinux.restorecon(tracesDir.getPath())) {
4878                        return;
4879                    }
4880                }
4881                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4882
4883                if (tracesFile.exists()) {
4884                    tracesTmp.delete();
4885                    tracesFile.renameTo(tracesTmp);
4886                }
4887                StringBuilder sb = new StringBuilder();
4888                Time tobj = new Time();
4889                tobj.set(System.currentTimeMillis());
4890                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4891                sb.append(": ");
4892                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4893                sb.append(" since ");
4894                sb.append(msg);
4895                FileOutputStream fos = new FileOutputStream(tracesFile);
4896                fos.write(sb.toString().getBytes());
4897                if (app == null) {
4898                    fos.write("\n*** No application process!".getBytes());
4899                }
4900                fos.close();
4901                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4902            } catch (IOException e) {
4903                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4904                return;
4905            }
4906
4907            if (app != null) {
4908                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4909                firstPids.add(app.pid);
4910                dumpStackTraces(tracesPath, firstPids, null, null, null);
4911            }
4912
4913            File lastTracesFile = null;
4914            File curTracesFile = null;
4915            for (int i=9; i>=0; i--) {
4916                String name = String.format(Locale.US, "slow%02d.txt", i);
4917                curTracesFile = new File(tracesDir, name);
4918                if (curTracesFile.exists()) {
4919                    if (lastTracesFile != null) {
4920                        curTracesFile.renameTo(lastTracesFile);
4921                    } else {
4922                        curTracesFile.delete();
4923                    }
4924                }
4925                lastTracesFile = curTracesFile;
4926            }
4927            tracesFile.renameTo(curTracesFile);
4928            if (tracesTmp.exists()) {
4929                tracesTmp.renameTo(tracesFile);
4930            }
4931        } finally {
4932            StrictMode.setThreadPolicy(oldPolicy);
4933        }
4934    }
4935
4936    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4937            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4938        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4939        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4940
4941        if (mController != null) {
4942            try {
4943                // 0 == continue, -1 = kill process immediately
4944                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4945                if (res < 0 && app.pid != MY_PID) {
4946                    app.kill("anr", true);
4947                }
4948            } catch (RemoteException e) {
4949                mController = null;
4950                Watchdog.getInstance().setActivityController(null);
4951            }
4952        }
4953
4954        long anrTime = SystemClock.uptimeMillis();
4955        if (MONITOR_CPU_USAGE) {
4956            updateCpuStatsNow();
4957        }
4958
4959        synchronized (this) {
4960            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4961            if (mShuttingDown) {
4962                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4963                return;
4964            } else if (app.notResponding) {
4965                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4966                return;
4967            } else if (app.crashing) {
4968                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4969                return;
4970            }
4971
4972            // In case we come through here for the same app before completing
4973            // this one, mark as anring now so we will bail out.
4974            app.notResponding = true;
4975
4976            // Log the ANR to the event log.
4977            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4978                    app.processName, app.info.flags, annotation);
4979
4980            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4981            firstPids.add(app.pid);
4982
4983            int parentPid = app.pid;
4984            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4985            if (parentPid != app.pid) firstPids.add(parentPid);
4986
4987            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4988
4989            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4990                ProcessRecord r = mLruProcesses.get(i);
4991                if (r != null && r.thread != null) {
4992                    int pid = r.pid;
4993                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4994                        if (r.persistent) {
4995                            firstPids.add(pid);
4996                        } else {
4997                            lastPids.put(pid, Boolean.TRUE);
4998                        }
4999                    }
5000                }
5001            }
5002        }
5003
5004        // Log the ANR to the main log.
5005        StringBuilder info = new StringBuilder();
5006        info.setLength(0);
5007        info.append("ANR in ").append(app.processName);
5008        if (activity != null && activity.shortComponentName != null) {
5009            info.append(" (").append(activity.shortComponentName).append(")");
5010        }
5011        info.append("\n");
5012        info.append("PID: ").append(app.pid).append("\n");
5013        if (annotation != null) {
5014            info.append("Reason: ").append(annotation).append("\n");
5015        }
5016        if (parent != null && parent != activity) {
5017            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5018        }
5019
5020        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5021
5022        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5023                NATIVE_STACKS_OF_INTEREST);
5024
5025        String cpuInfo = null;
5026        if (MONITOR_CPU_USAGE) {
5027            updateCpuStatsNow();
5028            synchronized (mProcessCpuTracker) {
5029                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5030            }
5031            info.append(processCpuTracker.printCurrentLoad());
5032            info.append(cpuInfo);
5033        }
5034
5035        info.append(processCpuTracker.printCurrentState(anrTime));
5036
5037        Slog.e(TAG, info.toString());
5038        if (tracesFile == null) {
5039            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5040            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5041        }
5042
5043        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5044                cpuInfo, tracesFile, null);
5045
5046        if (mController != null) {
5047            try {
5048                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5049                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5050                if (res != 0) {
5051                    if (res < 0 && app.pid != MY_PID) {
5052                        app.kill("anr", true);
5053                    } else {
5054                        synchronized (this) {
5055                            mServices.scheduleServiceTimeoutLocked(app);
5056                        }
5057                    }
5058                    return;
5059                }
5060            } catch (RemoteException e) {
5061                mController = null;
5062                Watchdog.getInstance().setActivityController(null);
5063            }
5064        }
5065
5066        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5067        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5068                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5069
5070        synchronized (this) {
5071            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5072                app.kill("bg anr", true);
5073                return;
5074            }
5075
5076            // Set the app's notResponding state, and look up the errorReportReceiver
5077            makeAppNotRespondingLocked(app,
5078                    activity != null ? activity.shortComponentName : null,
5079                    annotation != null ? "ANR " + annotation : "ANR",
5080                    info.toString());
5081
5082            // Bring up the infamous App Not Responding dialog
5083            Message msg = Message.obtain();
5084            HashMap<String, Object> map = new HashMap<String, Object>();
5085            msg.what = SHOW_NOT_RESPONDING_MSG;
5086            msg.obj = map;
5087            msg.arg1 = aboveSystem ? 1 : 0;
5088            map.put("app", app);
5089            if (activity != null) {
5090                map.put("activity", activity);
5091            }
5092
5093            mHandler.sendMessage(msg);
5094        }
5095    }
5096
5097    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5098        if (!mLaunchWarningShown) {
5099            mLaunchWarningShown = true;
5100            mHandler.post(new Runnable() {
5101                @Override
5102                public void run() {
5103                    synchronized (ActivityManagerService.this) {
5104                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5105                        d.show();
5106                        mHandler.postDelayed(new Runnable() {
5107                            @Override
5108                            public void run() {
5109                                synchronized (ActivityManagerService.this) {
5110                                    d.dismiss();
5111                                    mLaunchWarningShown = false;
5112                                }
5113                            }
5114                        }, 4000);
5115                    }
5116                }
5117            });
5118        }
5119    }
5120
5121    @Override
5122    public boolean clearApplicationUserData(final String packageName,
5123            final IPackageDataObserver observer, int userId) {
5124        enforceNotIsolatedCaller("clearApplicationUserData");
5125        int uid = Binder.getCallingUid();
5126        int pid = Binder.getCallingPid();
5127        userId = handleIncomingUser(pid, uid,
5128                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5129        long callingId = Binder.clearCallingIdentity();
5130        try {
5131            IPackageManager pm = AppGlobals.getPackageManager();
5132            int pkgUid = -1;
5133            synchronized(this) {
5134                try {
5135                    pkgUid = pm.getPackageUid(packageName, userId);
5136                } catch (RemoteException e) {
5137                }
5138                if (pkgUid == -1) {
5139                    Slog.w(TAG, "Invalid packageName: " + packageName);
5140                    if (observer != null) {
5141                        try {
5142                            observer.onRemoveCompleted(packageName, false);
5143                        } catch (RemoteException e) {
5144                            Slog.i(TAG, "Observer no longer exists.");
5145                        }
5146                    }
5147                    return false;
5148                }
5149                if (uid == pkgUid || checkComponentPermission(
5150                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5151                        pid, uid, -1, true)
5152                        == PackageManager.PERMISSION_GRANTED) {
5153                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5154                } else {
5155                    throw new SecurityException("PID " + pid + " does not have permission "
5156                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5157                                    + " of package " + packageName);
5158                }
5159
5160                // Remove all tasks match the cleared application package and user
5161                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5162                    final TaskRecord tr = mRecentTasks.get(i);
5163                    final String taskPackageName =
5164                            tr.getBaseIntent().getComponent().getPackageName();
5165                    if (tr.userId != userId) continue;
5166                    if (!taskPackageName.equals(packageName)) continue;
5167                    removeTaskByIdLocked(tr.taskId, false);
5168                }
5169            }
5170
5171            try {
5172                // Clear application user data
5173                pm.clearApplicationUserData(packageName, observer, userId);
5174
5175                synchronized(this) {
5176                    // Remove all permissions granted from/to this package
5177                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5178                }
5179
5180                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5181                        Uri.fromParts("package", packageName, null));
5182                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5183                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5184                        null, null, 0, null, null, null, false, false, userId);
5185            } catch (RemoteException e) {
5186            }
5187        } finally {
5188            Binder.restoreCallingIdentity(callingId);
5189        }
5190        return true;
5191    }
5192
5193    @Override
5194    public void killBackgroundProcesses(final String packageName, int userId) {
5195        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5196                != PackageManager.PERMISSION_GRANTED &&
5197                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5198                        != PackageManager.PERMISSION_GRANTED) {
5199            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5200                    + Binder.getCallingPid()
5201                    + ", uid=" + Binder.getCallingUid()
5202                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5203            Slog.w(TAG, msg);
5204            throw new SecurityException(msg);
5205        }
5206
5207        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5208                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5209        long callingId = Binder.clearCallingIdentity();
5210        try {
5211            IPackageManager pm = AppGlobals.getPackageManager();
5212            synchronized(this) {
5213                int appId = -1;
5214                try {
5215                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5216                } catch (RemoteException e) {
5217                }
5218                if (appId == -1) {
5219                    Slog.w(TAG, "Invalid packageName: " + packageName);
5220                    return;
5221                }
5222                killPackageProcessesLocked(packageName, appId, userId,
5223                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5224            }
5225        } finally {
5226            Binder.restoreCallingIdentity(callingId);
5227        }
5228    }
5229
5230    @Override
5231    public void killAllBackgroundProcesses() {
5232        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5233                != PackageManager.PERMISSION_GRANTED) {
5234            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5235                    + Binder.getCallingPid()
5236                    + ", uid=" + Binder.getCallingUid()
5237                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5238            Slog.w(TAG, msg);
5239            throw new SecurityException(msg);
5240        }
5241
5242        long callingId = Binder.clearCallingIdentity();
5243        try {
5244            synchronized(this) {
5245                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5246                final int NP = mProcessNames.getMap().size();
5247                for (int ip=0; ip<NP; ip++) {
5248                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5249                    final int NA = apps.size();
5250                    for (int ia=0; ia<NA; ia++) {
5251                        ProcessRecord app = apps.valueAt(ia);
5252                        if (app.persistent) {
5253                            // we don't kill persistent processes
5254                            continue;
5255                        }
5256                        if (app.removed) {
5257                            procs.add(app);
5258                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5259                            app.removed = true;
5260                            procs.add(app);
5261                        }
5262                    }
5263                }
5264
5265                int N = procs.size();
5266                for (int i=0; i<N; i++) {
5267                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5268                }
5269                mAllowLowerMemLevel = true;
5270                updateOomAdjLocked();
5271                doLowMemReportIfNeededLocked(null);
5272            }
5273        } finally {
5274            Binder.restoreCallingIdentity(callingId);
5275        }
5276    }
5277
5278    @Override
5279    public void forceStopPackage(final String packageName, int userId) {
5280        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5281                != PackageManager.PERMISSION_GRANTED) {
5282            String msg = "Permission Denial: forceStopPackage() from pid="
5283                    + Binder.getCallingPid()
5284                    + ", uid=" + Binder.getCallingUid()
5285                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5286            Slog.w(TAG, msg);
5287            throw new SecurityException(msg);
5288        }
5289        final int callingPid = Binder.getCallingPid();
5290        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5291                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5292        long callingId = Binder.clearCallingIdentity();
5293        try {
5294            IPackageManager pm = AppGlobals.getPackageManager();
5295            synchronized(this) {
5296                int[] users = userId == UserHandle.USER_ALL
5297                        ? getUsersLocked() : new int[] { userId };
5298                for (int user : users) {
5299                    int pkgUid = -1;
5300                    try {
5301                        pkgUid = pm.getPackageUid(packageName, user);
5302                    } catch (RemoteException e) {
5303                    }
5304                    if (pkgUid == -1) {
5305                        Slog.w(TAG, "Invalid packageName: " + packageName);
5306                        continue;
5307                    }
5308                    try {
5309                        pm.setPackageStoppedState(packageName, true, user);
5310                    } catch (RemoteException e) {
5311                    } catch (IllegalArgumentException e) {
5312                        Slog.w(TAG, "Failed trying to unstop package "
5313                                + packageName + ": " + e);
5314                    }
5315                    if (isUserRunningLocked(user, false)) {
5316                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5317                    }
5318                }
5319            }
5320        } finally {
5321            Binder.restoreCallingIdentity(callingId);
5322        }
5323    }
5324
5325    @Override
5326    public void addPackageDependency(String packageName) {
5327        synchronized (this) {
5328            int callingPid = Binder.getCallingPid();
5329            if (callingPid == Process.myPid()) {
5330                //  Yeah, um, no.
5331                Slog.w(TAG, "Can't addPackageDependency on system process");
5332                return;
5333            }
5334            ProcessRecord proc;
5335            synchronized (mPidsSelfLocked) {
5336                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5337            }
5338            if (proc != null) {
5339                if (proc.pkgDeps == null) {
5340                    proc.pkgDeps = new ArraySet<String>(1);
5341                }
5342                proc.pkgDeps.add(packageName);
5343            }
5344        }
5345    }
5346
5347    /*
5348     * The pkg name and app id have to be specified.
5349     */
5350    @Override
5351    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5352        if (pkg == null) {
5353            return;
5354        }
5355        // Make sure the uid is valid.
5356        if (appid < 0) {
5357            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5358            return;
5359        }
5360        int callerUid = Binder.getCallingUid();
5361        // Only the system server can kill an application
5362        if (callerUid == Process.SYSTEM_UID) {
5363            // Post an aysnc message to kill the application
5364            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5365            msg.arg1 = appid;
5366            msg.arg2 = 0;
5367            Bundle bundle = new Bundle();
5368            bundle.putString("pkg", pkg);
5369            bundle.putString("reason", reason);
5370            msg.obj = bundle;
5371            mHandler.sendMessage(msg);
5372        } else {
5373            throw new SecurityException(callerUid + " cannot kill pkg: " +
5374                    pkg);
5375        }
5376    }
5377
5378    @Override
5379    public void closeSystemDialogs(String reason) {
5380        enforceNotIsolatedCaller("closeSystemDialogs");
5381
5382        final int pid = Binder.getCallingPid();
5383        final int uid = Binder.getCallingUid();
5384        final long origId = Binder.clearCallingIdentity();
5385        try {
5386            synchronized (this) {
5387                // Only allow this from foreground processes, so that background
5388                // applications can't abuse it to prevent system UI from being shown.
5389                if (uid >= Process.FIRST_APPLICATION_UID) {
5390                    ProcessRecord proc;
5391                    synchronized (mPidsSelfLocked) {
5392                        proc = mPidsSelfLocked.get(pid);
5393                    }
5394                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5395                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5396                                + " from background process " + proc);
5397                        return;
5398                    }
5399                }
5400                closeSystemDialogsLocked(reason);
5401            }
5402        } finally {
5403            Binder.restoreCallingIdentity(origId);
5404        }
5405    }
5406
5407    void closeSystemDialogsLocked(String reason) {
5408        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5409        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5410                | Intent.FLAG_RECEIVER_FOREGROUND);
5411        if (reason != null) {
5412            intent.putExtra("reason", reason);
5413        }
5414        mWindowManager.closeSystemDialogs(reason);
5415
5416        mStackSupervisor.closeSystemDialogsLocked();
5417
5418        broadcastIntentLocked(null, null, intent, null,
5419                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5420                Process.SYSTEM_UID, UserHandle.USER_ALL);
5421    }
5422
5423    @Override
5424    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5425        enforceNotIsolatedCaller("getProcessMemoryInfo");
5426        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5427        for (int i=pids.length-1; i>=0; i--) {
5428            ProcessRecord proc;
5429            int oomAdj;
5430            synchronized (this) {
5431                synchronized (mPidsSelfLocked) {
5432                    proc = mPidsSelfLocked.get(pids[i]);
5433                    oomAdj = proc != null ? proc.setAdj : 0;
5434                }
5435            }
5436            infos[i] = new Debug.MemoryInfo();
5437            Debug.getMemoryInfo(pids[i], infos[i]);
5438            if (proc != null) {
5439                synchronized (this) {
5440                    if (proc.thread != null && proc.setAdj == oomAdj) {
5441                        // Record this for posterity if the process has been stable.
5442                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5443                                infos[i].getTotalUss(), false, proc.pkgList);
5444                    }
5445                }
5446            }
5447        }
5448        return infos;
5449    }
5450
5451    @Override
5452    public long[] getProcessPss(int[] pids) {
5453        enforceNotIsolatedCaller("getProcessPss");
5454        long[] pss = new long[pids.length];
5455        for (int i=pids.length-1; i>=0; i--) {
5456            ProcessRecord proc;
5457            int oomAdj;
5458            synchronized (this) {
5459                synchronized (mPidsSelfLocked) {
5460                    proc = mPidsSelfLocked.get(pids[i]);
5461                    oomAdj = proc != null ? proc.setAdj : 0;
5462                }
5463            }
5464            long[] tmpUss = new long[1];
5465            pss[i] = Debug.getPss(pids[i], tmpUss);
5466            if (proc != null) {
5467                synchronized (this) {
5468                    if (proc.thread != null && proc.setAdj == oomAdj) {
5469                        // Record this for posterity if the process has been stable.
5470                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5471                    }
5472                }
5473            }
5474        }
5475        return pss;
5476    }
5477
5478    @Override
5479    public void killApplicationProcess(String processName, int uid) {
5480        if (processName == null) {
5481            return;
5482        }
5483
5484        int callerUid = Binder.getCallingUid();
5485        // Only the system server can kill an application
5486        if (callerUid == Process.SYSTEM_UID) {
5487            synchronized (this) {
5488                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5489                if (app != null && app.thread != null) {
5490                    try {
5491                        app.thread.scheduleSuicide();
5492                    } catch (RemoteException e) {
5493                        // If the other end already died, then our work here is done.
5494                    }
5495                } else {
5496                    Slog.w(TAG, "Process/uid not found attempting kill of "
5497                            + processName + " / " + uid);
5498                }
5499            }
5500        } else {
5501            throw new SecurityException(callerUid + " cannot kill app process: " +
5502                    processName);
5503        }
5504    }
5505
5506    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5507        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5508                false, true, false, false, UserHandle.getUserId(uid), reason);
5509        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5510                Uri.fromParts("package", packageName, null));
5511        if (!mProcessesReady) {
5512            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5513                    | Intent.FLAG_RECEIVER_FOREGROUND);
5514        }
5515        intent.putExtra(Intent.EXTRA_UID, uid);
5516        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5517        broadcastIntentLocked(null, null, intent,
5518                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5519                false, false,
5520                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5521    }
5522
5523    private void forceStopUserLocked(int userId, String reason) {
5524        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5525        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5526        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5527                | Intent.FLAG_RECEIVER_FOREGROUND);
5528        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5529        broadcastIntentLocked(null, null, intent,
5530                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5531                false, false,
5532                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5533    }
5534
5535    private final boolean killPackageProcessesLocked(String packageName, int appId,
5536            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5537            boolean doit, boolean evenPersistent, String reason) {
5538        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5539
5540        // Remove all processes this package may have touched: all with the
5541        // same UID (except for the system or root user), and all whose name
5542        // matches the package name.
5543        final int NP = mProcessNames.getMap().size();
5544        for (int ip=0; ip<NP; ip++) {
5545            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5546            final int NA = apps.size();
5547            for (int ia=0; ia<NA; ia++) {
5548                ProcessRecord app = apps.valueAt(ia);
5549                if (app.persistent && !evenPersistent) {
5550                    // we don't kill persistent processes
5551                    continue;
5552                }
5553                if (app.removed) {
5554                    if (doit) {
5555                        procs.add(app);
5556                    }
5557                    continue;
5558                }
5559
5560                // Skip process if it doesn't meet our oom adj requirement.
5561                if (app.setAdj < minOomAdj) {
5562                    continue;
5563                }
5564
5565                // If no package is specified, we call all processes under the
5566                // give user id.
5567                if (packageName == null) {
5568                    if (app.userId != userId) {
5569                        continue;
5570                    }
5571                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5572                        continue;
5573                    }
5574                // Package has been specified, we want to hit all processes
5575                // that match it.  We need to qualify this by the processes
5576                // that are running under the specified app and user ID.
5577                } else {
5578                    final boolean isDep = app.pkgDeps != null
5579                            && app.pkgDeps.contains(packageName);
5580                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5581                        continue;
5582                    }
5583                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5584                        continue;
5585                    }
5586                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5587                        continue;
5588                    }
5589                }
5590
5591                // Process has passed all conditions, kill it!
5592                if (!doit) {
5593                    return true;
5594                }
5595                app.removed = true;
5596                procs.add(app);
5597            }
5598        }
5599
5600        int N = procs.size();
5601        for (int i=0; i<N; i++) {
5602            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5603        }
5604        updateOomAdjLocked();
5605        return N > 0;
5606    }
5607
5608    private final boolean forceStopPackageLocked(String name, int appId,
5609            boolean callerWillRestart, boolean purgeCache, boolean doit,
5610            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5611        int i;
5612        int N;
5613
5614        if (userId == UserHandle.USER_ALL && name == null) {
5615            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5616        }
5617
5618        if (appId < 0 && name != null) {
5619            try {
5620                appId = UserHandle.getAppId(
5621                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5622            } catch (RemoteException e) {
5623            }
5624        }
5625
5626        if (doit) {
5627            if (name != null) {
5628                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5629                        + " user=" + userId + ": " + reason);
5630            } else {
5631                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5632            }
5633
5634            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5635            for (int ip=pmap.size()-1; ip>=0; ip--) {
5636                SparseArray<Long> ba = pmap.valueAt(ip);
5637                for (i=ba.size()-1; i>=0; i--) {
5638                    boolean remove = false;
5639                    final int entUid = ba.keyAt(i);
5640                    if (name != null) {
5641                        if (userId == UserHandle.USER_ALL) {
5642                            if (UserHandle.getAppId(entUid) == appId) {
5643                                remove = true;
5644                            }
5645                        } else {
5646                            if (entUid == UserHandle.getUid(userId, appId)) {
5647                                remove = true;
5648                            }
5649                        }
5650                    } else if (UserHandle.getUserId(entUid) == userId) {
5651                        remove = true;
5652                    }
5653                    if (remove) {
5654                        ba.removeAt(i);
5655                    }
5656                }
5657                if (ba.size() == 0) {
5658                    pmap.removeAt(ip);
5659                }
5660            }
5661        }
5662
5663        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5664                -100, callerWillRestart, true, doit, evenPersistent,
5665                name == null ? ("stop user " + userId) : ("stop " + name));
5666
5667        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5668            if (!doit) {
5669                return true;
5670            }
5671            didSomething = true;
5672        }
5673
5674        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5675            if (!doit) {
5676                return true;
5677            }
5678            didSomething = true;
5679        }
5680
5681        if (name == null) {
5682            // Remove all sticky broadcasts from this user.
5683            mStickyBroadcasts.remove(userId);
5684        }
5685
5686        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5687        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5688                userId, providers)) {
5689            if (!doit) {
5690                return true;
5691            }
5692            didSomething = true;
5693        }
5694        N = providers.size();
5695        for (i=0; i<N; i++) {
5696            removeDyingProviderLocked(null, providers.get(i), true);
5697        }
5698
5699        // Remove transient permissions granted from/to this package/user
5700        removeUriPermissionsForPackageLocked(name, userId, false);
5701
5702        if (name == null || uninstalling) {
5703            // Remove pending intents.  For now we only do this when force
5704            // stopping users, because we have some problems when doing this
5705            // for packages -- app widgets are not currently cleaned up for
5706            // such packages, so they can be left with bad pending intents.
5707            if (mIntentSenderRecords.size() > 0) {
5708                Iterator<WeakReference<PendingIntentRecord>> it
5709                        = mIntentSenderRecords.values().iterator();
5710                while (it.hasNext()) {
5711                    WeakReference<PendingIntentRecord> wpir = it.next();
5712                    if (wpir == null) {
5713                        it.remove();
5714                        continue;
5715                    }
5716                    PendingIntentRecord pir = wpir.get();
5717                    if (pir == null) {
5718                        it.remove();
5719                        continue;
5720                    }
5721                    if (name == null) {
5722                        // Stopping user, remove all objects for the user.
5723                        if (pir.key.userId != userId) {
5724                            // Not the same user, skip it.
5725                            continue;
5726                        }
5727                    } else {
5728                        if (UserHandle.getAppId(pir.uid) != appId) {
5729                            // Different app id, skip it.
5730                            continue;
5731                        }
5732                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5733                            // Different user, skip it.
5734                            continue;
5735                        }
5736                        if (!pir.key.packageName.equals(name)) {
5737                            // Different package, skip it.
5738                            continue;
5739                        }
5740                    }
5741                    if (!doit) {
5742                        return true;
5743                    }
5744                    didSomething = true;
5745                    it.remove();
5746                    pir.canceled = true;
5747                    if (pir.key.activity != null) {
5748                        pir.key.activity.pendingResults.remove(pir.ref);
5749                    }
5750                }
5751            }
5752        }
5753
5754        if (doit) {
5755            if (purgeCache && name != null) {
5756                AttributeCache ac = AttributeCache.instance();
5757                if (ac != null) {
5758                    ac.removePackage(name);
5759                }
5760            }
5761            if (mBooted) {
5762                mStackSupervisor.resumeTopActivitiesLocked();
5763                mStackSupervisor.scheduleIdleLocked();
5764            }
5765        }
5766
5767        return didSomething;
5768    }
5769
5770    private final boolean removeProcessLocked(ProcessRecord app,
5771            boolean callerWillRestart, boolean allowRestart, String reason) {
5772        final String name = app.processName;
5773        final int uid = app.uid;
5774        if (DEBUG_PROCESSES) Slog.d(
5775            TAG, "Force removing proc " + app.toShortString() + " (" + name
5776            + "/" + uid + ")");
5777
5778        mProcessNames.remove(name, uid);
5779        mIsolatedProcesses.remove(app.uid);
5780        if (mHeavyWeightProcess == app) {
5781            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5782                    mHeavyWeightProcess.userId, 0));
5783            mHeavyWeightProcess = null;
5784        }
5785        boolean needRestart = false;
5786        if (app.pid > 0 && app.pid != MY_PID) {
5787            int pid = app.pid;
5788            synchronized (mPidsSelfLocked) {
5789                mPidsSelfLocked.remove(pid);
5790                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5791            }
5792            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5793            if (app.isolated) {
5794                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5795            }
5796            app.kill(reason, true);
5797            handleAppDiedLocked(app, true, allowRestart);
5798            removeLruProcessLocked(app);
5799
5800            if (app.persistent && !app.isolated) {
5801                if (!callerWillRestart) {
5802                    addAppLocked(app.info, false, null /* ABI override */);
5803                } else {
5804                    needRestart = true;
5805                }
5806            }
5807        } else {
5808            mRemovedProcesses.add(app);
5809        }
5810
5811        return needRestart;
5812    }
5813
5814    private final void processStartTimedOutLocked(ProcessRecord app) {
5815        final int pid = app.pid;
5816        boolean gone = false;
5817        synchronized (mPidsSelfLocked) {
5818            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5819            if (knownApp != null && knownApp.thread == null) {
5820                mPidsSelfLocked.remove(pid);
5821                gone = true;
5822            }
5823        }
5824
5825        if (gone) {
5826            Slog.w(TAG, "Process " + app + " failed to attach");
5827            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5828                    pid, app.uid, app.processName);
5829            mProcessNames.remove(app.processName, app.uid);
5830            mIsolatedProcesses.remove(app.uid);
5831            if (mHeavyWeightProcess == app) {
5832                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5833                        mHeavyWeightProcess.userId, 0));
5834                mHeavyWeightProcess = null;
5835            }
5836            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5837            if (app.isolated) {
5838                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5839            }
5840            // Take care of any launching providers waiting for this process.
5841            checkAppInLaunchingProvidersLocked(app, true);
5842            // Take care of any services that are waiting for the process.
5843            mServices.processStartTimedOutLocked(app);
5844            app.kill("start timeout", true);
5845            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5846                Slog.w(TAG, "Unattached app died before backup, skipping");
5847                try {
5848                    IBackupManager bm = IBackupManager.Stub.asInterface(
5849                            ServiceManager.getService(Context.BACKUP_SERVICE));
5850                    bm.agentDisconnected(app.info.packageName);
5851                } catch (RemoteException e) {
5852                    // Can't happen; the backup manager is local
5853                }
5854            }
5855            if (isPendingBroadcastProcessLocked(pid)) {
5856                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5857                skipPendingBroadcastLocked(pid);
5858            }
5859        } else {
5860            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5861        }
5862    }
5863
5864    private final boolean attachApplicationLocked(IApplicationThread thread,
5865            int pid) {
5866
5867        // Find the application record that is being attached...  either via
5868        // the pid if we are running in multiple processes, or just pull the
5869        // next app record if we are emulating process with anonymous threads.
5870        ProcessRecord app;
5871        if (pid != MY_PID && pid >= 0) {
5872            synchronized (mPidsSelfLocked) {
5873                app = mPidsSelfLocked.get(pid);
5874            }
5875        } else {
5876            app = null;
5877        }
5878
5879        if (app == null) {
5880            Slog.w(TAG, "No pending application record for pid " + pid
5881                    + " (IApplicationThread " + thread + "); dropping process");
5882            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5883            if (pid > 0 && pid != MY_PID) {
5884                Process.killProcessQuiet(pid);
5885                //TODO: Process.killProcessGroup(app.info.uid, pid);
5886            } else {
5887                try {
5888                    thread.scheduleExit();
5889                } catch (Exception e) {
5890                    // Ignore exceptions.
5891                }
5892            }
5893            return false;
5894        }
5895
5896        // If this application record is still attached to a previous
5897        // process, clean it up now.
5898        if (app.thread != null) {
5899            handleAppDiedLocked(app, true, true);
5900        }
5901
5902        // Tell the process all about itself.
5903
5904        if (localLOGV) Slog.v(
5905                TAG, "Binding process pid " + pid + " to record " + app);
5906
5907        final String processName = app.processName;
5908        try {
5909            AppDeathRecipient adr = new AppDeathRecipient(
5910                    app, pid, thread);
5911            thread.asBinder().linkToDeath(adr, 0);
5912            app.deathRecipient = adr;
5913        } catch (RemoteException e) {
5914            app.resetPackageList(mProcessStats);
5915            startProcessLocked(app, "link fail", processName);
5916            return false;
5917        }
5918
5919        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5920
5921        app.makeActive(thread, mProcessStats);
5922        app.curAdj = app.setAdj = -100;
5923        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5924        app.forcingToForeground = null;
5925        updateProcessForegroundLocked(app, false, false);
5926        app.hasShownUi = false;
5927        app.debugging = false;
5928        app.cached = false;
5929
5930        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5931
5932        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5933        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5934
5935        if (!normalMode) {
5936            Slog.i(TAG, "Launching preboot mode app: " + app);
5937        }
5938
5939        if (localLOGV) Slog.v(
5940            TAG, "New app record " + app
5941            + " thread=" + thread.asBinder() + " pid=" + pid);
5942        try {
5943            int testMode = IApplicationThread.DEBUG_OFF;
5944            if (mDebugApp != null && mDebugApp.equals(processName)) {
5945                testMode = mWaitForDebugger
5946                    ? IApplicationThread.DEBUG_WAIT
5947                    : IApplicationThread.DEBUG_ON;
5948                app.debugging = true;
5949                if (mDebugTransient) {
5950                    mDebugApp = mOrigDebugApp;
5951                    mWaitForDebugger = mOrigWaitForDebugger;
5952                }
5953            }
5954            String profileFile = app.instrumentationProfileFile;
5955            ParcelFileDescriptor profileFd = null;
5956            int samplingInterval = 0;
5957            boolean profileAutoStop = false;
5958            if (mProfileApp != null && mProfileApp.equals(processName)) {
5959                mProfileProc = app;
5960                profileFile = mProfileFile;
5961                profileFd = mProfileFd;
5962                samplingInterval = mSamplingInterval;
5963                profileAutoStop = mAutoStopProfiler;
5964            }
5965            boolean enableOpenGlTrace = false;
5966            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5967                enableOpenGlTrace = true;
5968                mOpenGlTraceApp = null;
5969            }
5970
5971            // If the app is being launched for restore or full backup, set it up specially
5972            boolean isRestrictedBackupMode = false;
5973            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5974                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5975                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5976                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5977            }
5978
5979            ensurePackageDexOpt(app.instrumentationInfo != null
5980                    ? app.instrumentationInfo.packageName
5981                    : app.info.packageName);
5982            if (app.instrumentationClass != null) {
5983                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5984            }
5985            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5986                    + processName + " with config " + mConfiguration);
5987            ApplicationInfo appInfo = app.instrumentationInfo != null
5988                    ? app.instrumentationInfo : app.info;
5989            app.compat = compatibilityInfoForPackageLocked(appInfo);
5990            if (profileFd != null) {
5991                profileFd = profileFd.dup();
5992            }
5993            ProfilerInfo profilerInfo = profileFile == null ? null
5994                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5995            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5996                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5997                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5998                    isRestrictedBackupMode || !normalMode, app.persistent,
5999                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6000                    mCoreSettingsObserver.getCoreSettingsLocked());
6001            updateLruProcessLocked(app, false, null);
6002            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6003        } catch (Exception e) {
6004            // todo: Yikes!  What should we do?  For now we will try to
6005            // start another process, but that could easily get us in
6006            // an infinite loop of restarting processes...
6007            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6008
6009            app.resetPackageList(mProcessStats);
6010            app.unlinkDeathRecipient();
6011            startProcessLocked(app, "bind fail", processName);
6012            return false;
6013        }
6014
6015        // Remove this record from the list of starting applications.
6016        mPersistentStartingProcesses.remove(app);
6017        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6018                "Attach application locked removing on hold: " + app);
6019        mProcessesOnHold.remove(app);
6020
6021        boolean badApp = false;
6022        boolean didSomething = false;
6023
6024        // See if the top visible activity is waiting to run in this process...
6025        if (normalMode) {
6026            try {
6027                if (mStackSupervisor.attachApplicationLocked(app)) {
6028                    didSomething = true;
6029                }
6030            } catch (Exception e) {
6031                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6032                badApp = true;
6033            }
6034        }
6035
6036        // Find any services that should be running in this process...
6037        if (!badApp) {
6038            try {
6039                didSomething |= mServices.attachApplicationLocked(app, processName);
6040            } catch (Exception e) {
6041                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6042                badApp = true;
6043            }
6044        }
6045
6046        // Check if a next-broadcast receiver is in this process...
6047        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6048            try {
6049                didSomething |= sendPendingBroadcastsLocked(app);
6050            } catch (Exception e) {
6051                // If the app died trying to launch the receiver we declare it 'bad'
6052                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6053                badApp = true;
6054            }
6055        }
6056
6057        // Check whether the next backup agent is in this process...
6058        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6059            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6060            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6061            try {
6062                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6063                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6064                        mBackupTarget.backupMode);
6065            } catch (Exception e) {
6066                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6067                badApp = true;
6068            }
6069        }
6070
6071        if (badApp) {
6072            app.kill("error during init", true);
6073            handleAppDiedLocked(app, false, true);
6074            return false;
6075        }
6076
6077        if (!didSomething) {
6078            updateOomAdjLocked();
6079        }
6080
6081        return true;
6082    }
6083
6084    @Override
6085    public final void attachApplication(IApplicationThread thread) {
6086        synchronized (this) {
6087            int callingPid = Binder.getCallingPid();
6088            final long origId = Binder.clearCallingIdentity();
6089            attachApplicationLocked(thread, callingPid);
6090            Binder.restoreCallingIdentity(origId);
6091        }
6092    }
6093
6094    @Override
6095    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6096        final long origId = Binder.clearCallingIdentity();
6097        synchronized (this) {
6098            ActivityStack stack = ActivityRecord.getStackLocked(token);
6099            if (stack != null) {
6100                ActivityRecord r =
6101                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6102                if (stopProfiling) {
6103                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6104                        try {
6105                            mProfileFd.close();
6106                        } catch (IOException e) {
6107                        }
6108                        clearProfilerLocked();
6109                    }
6110                }
6111            }
6112        }
6113        Binder.restoreCallingIdentity(origId);
6114    }
6115
6116    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6117        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6118                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6119    }
6120
6121    void enableScreenAfterBoot() {
6122        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6123                SystemClock.uptimeMillis());
6124        mWindowManager.enableScreenAfterBoot();
6125
6126        synchronized (this) {
6127            updateEventDispatchingLocked();
6128        }
6129    }
6130
6131    @Override
6132    public void showBootMessage(final CharSequence msg, final boolean always) {
6133        enforceNotIsolatedCaller("showBootMessage");
6134        mWindowManager.showBootMessage(msg, always);
6135    }
6136
6137    @Override
6138    public void keyguardWaitingForActivityDrawn() {
6139        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6140        final long token = Binder.clearCallingIdentity();
6141        try {
6142            synchronized (this) {
6143                if (DEBUG_LOCKSCREEN) logLockScreen("");
6144                mWindowManager.keyguardWaitingForActivityDrawn();
6145                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6146                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6147                }
6148            }
6149        } finally {
6150            Binder.restoreCallingIdentity(token);
6151        }
6152    }
6153
6154    final void finishBooting() {
6155        synchronized (this) {
6156            if (!mBootAnimationComplete) {
6157                mCallFinishBooting = true;
6158                return;
6159            }
6160            mCallFinishBooting = false;
6161        }
6162
6163        ArraySet<String> completedIsas = new ArraySet<String>();
6164        for (String abi : Build.SUPPORTED_ABIS) {
6165            Process.establishZygoteConnectionForAbi(abi);
6166            final String instructionSet = VMRuntime.getInstructionSet(abi);
6167            if (!completedIsas.contains(instructionSet)) {
6168                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6169                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6170                }
6171                completedIsas.add(instructionSet);
6172            }
6173        }
6174
6175        // Register receivers to handle package update events
6176        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6177
6178        // Let system services know.
6179        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6180
6181        synchronized (this) {
6182            // Ensure that any processes we had put on hold are now started
6183            // up.
6184            final int NP = mProcessesOnHold.size();
6185            if (NP > 0) {
6186                ArrayList<ProcessRecord> procs =
6187                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6188                for (int ip=0; ip<NP; ip++) {
6189                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6190                            + procs.get(ip));
6191                    startProcessLocked(procs.get(ip), "on-hold", null);
6192                }
6193            }
6194
6195            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6196                // Start looking for apps that are abusing wake locks.
6197                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6198                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6199                // Tell anyone interested that we are done booting!
6200                SystemProperties.set("sys.boot_completed", "1");
6201
6202                // And trigger dev.bootcomplete if we are not showing encryption progress
6203                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6204                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6205                    SystemProperties.set("dev.bootcomplete", "1");
6206                }
6207                for (int i=0; i<mStartedUsers.size(); i++) {
6208                    UserStartedState uss = mStartedUsers.valueAt(i);
6209                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6210                        uss.mState = UserStartedState.STATE_RUNNING;
6211                        final int userId = mStartedUsers.keyAt(i);
6212                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6213                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6214                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6215                        broadcastIntentLocked(null, null, intent, null,
6216                                new IIntentReceiver.Stub() {
6217                                    @Override
6218                                    public void performReceive(Intent intent, int resultCode,
6219                                            String data, Bundle extras, boolean ordered,
6220                                            boolean sticky, int sendingUser) {
6221                                        synchronized (ActivityManagerService.this) {
6222                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6223                                                    true, false);
6224                                        }
6225                                    }
6226                                },
6227                                0, null, null,
6228                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6229                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6230                                userId);
6231                    }
6232                }
6233                scheduleStartProfilesLocked();
6234            }
6235        }
6236    }
6237
6238    @Override
6239    public void bootAnimationComplete() {
6240        final boolean callFinishBooting;
6241        synchronized (this) {
6242            callFinishBooting = mCallFinishBooting;
6243            mBootAnimationComplete = true;
6244        }
6245        if (callFinishBooting) {
6246            finishBooting();
6247        }
6248    }
6249
6250    final void ensureBootCompleted() {
6251        boolean booting;
6252        boolean enableScreen;
6253        synchronized (this) {
6254            booting = mBooting;
6255            mBooting = false;
6256            enableScreen = !mBooted;
6257            mBooted = true;
6258        }
6259
6260        if (booting) {
6261            finishBooting();
6262        }
6263
6264        if (enableScreen) {
6265            enableScreenAfterBoot();
6266        }
6267    }
6268
6269    @Override
6270    public final void activityResumed(IBinder token) {
6271        final long origId = Binder.clearCallingIdentity();
6272        synchronized(this) {
6273            ActivityStack stack = ActivityRecord.getStackLocked(token);
6274            if (stack != null) {
6275                ActivityRecord.activityResumedLocked(token);
6276            }
6277        }
6278        Binder.restoreCallingIdentity(origId);
6279    }
6280
6281    @Override
6282    public final void activityPaused(IBinder token) {
6283        final long origId = Binder.clearCallingIdentity();
6284        synchronized(this) {
6285            ActivityStack stack = ActivityRecord.getStackLocked(token);
6286            if (stack != null) {
6287                stack.activityPausedLocked(token, false);
6288            }
6289        }
6290        Binder.restoreCallingIdentity(origId);
6291    }
6292
6293    @Override
6294    public final void activityStopped(IBinder token, Bundle icicle,
6295            PersistableBundle persistentState, CharSequence description) {
6296        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6297
6298        // Refuse possible leaked file descriptors
6299        if (icicle != null && icicle.hasFileDescriptors()) {
6300            throw new IllegalArgumentException("File descriptors passed in Bundle");
6301        }
6302
6303        final long origId = Binder.clearCallingIdentity();
6304
6305        synchronized (this) {
6306            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6307            if (r != null) {
6308                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6309            }
6310        }
6311
6312        trimApplications();
6313
6314        Binder.restoreCallingIdentity(origId);
6315    }
6316
6317    @Override
6318    public final void activityDestroyed(IBinder token) {
6319        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6320        synchronized (this) {
6321            ActivityStack stack = ActivityRecord.getStackLocked(token);
6322            if (stack != null) {
6323                stack.activityDestroyedLocked(token);
6324            }
6325        }
6326    }
6327
6328    @Override
6329    public final void backgroundResourcesReleased(IBinder token) {
6330        final long origId = Binder.clearCallingIdentity();
6331        try {
6332            synchronized (this) {
6333                ActivityStack stack = ActivityRecord.getStackLocked(token);
6334                if (stack != null) {
6335                    stack.backgroundResourcesReleased(token);
6336                }
6337            }
6338        } finally {
6339            Binder.restoreCallingIdentity(origId);
6340        }
6341    }
6342
6343    @Override
6344    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6345        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6346    }
6347
6348    @Override
6349    public final void notifyEnterAnimationComplete(IBinder token) {
6350        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6351    }
6352
6353    @Override
6354    public String getCallingPackage(IBinder token) {
6355        synchronized (this) {
6356            ActivityRecord r = getCallingRecordLocked(token);
6357            return r != null ? r.info.packageName : null;
6358        }
6359    }
6360
6361    @Override
6362    public ComponentName getCallingActivity(IBinder token) {
6363        synchronized (this) {
6364            ActivityRecord r = getCallingRecordLocked(token);
6365            return r != null ? r.intent.getComponent() : null;
6366        }
6367    }
6368
6369    private ActivityRecord getCallingRecordLocked(IBinder token) {
6370        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6371        if (r == null) {
6372            return null;
6373        }
6374        return r.resultTo;
6375    }
6376
6377    @Override
6378    public ComponentName getActivityClassForToken(IBinder token) {
6379        synchronized(this) {
6380            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6381            if (r == null) {
6382                return null;
6383            }
6384            return r.intent.getComponent();
6385        }
6386    }
6387
6388    @Override
6389    public String getPackageForToken(IBinder token) {
6390        synchronized(this) {
6391            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6392            if (r == null) {
6393                return null;
6394            }
6395            return r.packageName;
6396        }
6397    }
6398
6399    @Override
6400    public IIntentSender getIntentSender(int type,
6401            String packageName, IBinder token, String resultWho,
6402            int requestCode, Intent[] intents, String[] resolvedTypes,
6403            int flags, Bundle options, int userId) {
6404        enforceNotIsolatedCaller("getIntentSender");
6405        // Refuse possible leaked file descriptors
6406        if (intents != null) {
6407            if (intents.length < 1) {
6408                throw new IllegalArgumentException("Intents array length must be >= 1");
6409            }
6410            for (int i=0; i<intents.length; i++) {
6411                Intent intent = intents[i];
6412                if (intent != null) {
6413                    if (intent.hasFileDescriptors()) {
6414                        throw new IllegalArgumentException("File descriptors passed in Intent");
6415                    }
6416                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6417                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6418                        throw new IllegalArgumentException(
6419                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6420                    }
6421                    intents[i] = new Intent(intent);
6422                }
6423            }
6424            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6425                throw new IllegalArgumentException(
6426                        "Intent array length does not match resolvedTypes length");
6427            }
6428        }
6429        if (options != null) {
6430            if (options.hasFileDescriptors()) {
6431                throw new IllegalArgumentException("File descriptors passed in options");
6432            }
6433        }
6434
6435        synchronized(this) {
6436            int callingUid = Binder.getCallingUid();
6437            int origUserId = userId;
6438            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6439                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6440                    ALLOW_NON_FULL, "getIntentSender", null);
6441            if (origUserId == UserHandle.USER_CURRENT) {
6442                // We don't want to evaluate this until the pending intent is
6443                // actually executed.  However, we do want to always do the
6444                // security checking for it above.
6445                userId = UserHandle.USER_CURRENT;
6446            }
6447            try {
6448                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6449                    int uid = AppGlobals.getPackageManager()
6450                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6451                    if (!UserHandle.isSameApp(callingUid, uid)) {
6452                        String msg = "Permission Denial: getIntentSender() from pid="
6453                            + Binder.getCallingPid()
6454                            + ", uid=" + Binder.getCallingUid()
6455                            + ", (need uid=" + uid + ")"
6456                            + " is not allowed to send as package " + packageName;
6457                        Slog.w(TAG, msg);
6458                        throw new SecurityException(msg);
6459                    }
6460                }
6461
6462                return getIntentSenderLocked(type, packageName, callingUid, userId,
6463                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6464
6465            } catch (RemoteException e) {
6466                throw new SecurityException(e);
6467            }
6468        }
6469    }
6470
6471    IIntentSender getIntentSenderLocked(int type, String packageName,
6472            int callingUid, int userId, IBinder token, String resultWho,
6473            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6474            Bundle options) {
6475        if (DEBUG_MU)
6476            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6477        ActivityRecord activity = null;
6478        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6479            activity = ActivityRecord.isInStackLocked(token);
6480            if (activity == null) {
6481                return null;
6482            }
6483            if (activity.finishing) {
6484                return null;
6485            }
6486        }
6487
6488        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6489        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6490        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6491        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6492                |PendingIntent.FLAG_UPDATE_CURRENT);
6493
6494        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6495                type, packageName, activity, resultWho,
6496                requestCode, intents, resolvedTypes, flags, options, userId);
6497        WeakReference<PendingIntentRecord> ref;
6498        ref = mIntentSenderRecords.get(key);
6499        PendingIntentRecord rec = ref != null ? ref.get() : null;
6500        if (rec != null) {
6501            if (!cancelCurrent) {
6502                if (updateCurrent) {
6503                    if (rec.key.requestIntent != null) {
6504                        rec.key.requestIntent.replaceExtras(intents != null ?
6505                                intents[intents.length - 1] : null);
6506                    }
6507                    if (intents != null) {
6508                        intents[intents.length-1] = rec.key.requestIntent;
6509                        rec.key.allIntents = intents;
6510                        rec.key.allResolvedTypes = resolvedTypes;
6511                    } else {
6512                        rec.key.allIntents = null;
6513                        rec.key.allResolvedTypes = null;
6514                    }
6515                }
6516                return rec;
6517            }
6518            rec.canceled = true;
6519            mIntentSenderRecords.remove(key);
6520        }
6521        if (noCreate) {
6522            return rec;
6523        }
6524        rec = new PendingIntentRecord(this, key, callingUid);
6525        mIntentSenderRecords.put(key, rec.ref);
6526        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6527            if (activity.pendingResults == null) {
6528                activity.pendingResults
6529                        = new HashSet<WeakReference<PendingIntentRecord>>();
6530            }
6531            activity.pendingResults.add(rec.ref);
6532        }
6533        return rec;
6534    }
6535
6536    @Override
6537    public void cancelIntentSender(IIntentSender sender) {
6538        if (!(sender instanceof PendingIntentRecord)) {
6539            return;
6540        }
6541        synchronized(this) {
6542            PendingIntentRecord rec = (PendingIntentRecord)sender;
6543            try {
6544                int uid = AppGlobals.getPackageManager()
6545                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6546                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6547                    String msg = "Permission Denial: cancelIntentSender() from pid="
6548                        + Binder.getCallingPid()
6549                        + ", uid=" + Binder.getCallingUid()
6550                        + " is not allowed to cancel packges "
6551                        + rec.key.packageName;
6552                    Slog.w(TAG, msg);
6553                    throw new SecurityException(msg);
6554                }
6555            } catch (RemoteException e) {
6556                throw new SecurityException(e);
6557            }
6558            cancelIntentSenderLocked(rec, true);
6559        }
6560    }
6561
6562    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6563        rec.canceled = true;
6564        mIntentSenderRecords.remove(rec.key);
6565        if (cleanActivity && rec.key.activity != null) {
6566            rec.key.activity.pendingResults.remove(rec.ref);
6567        }
6568    }
6569
6570    @Override
6571    public String getPackageForIntentSender(IIntentSender pendingResult) {
6572        if (!(pendingResult instanceof PendingIntentRecord)) {
6573            return null;
6574        }
6575        try {
6576            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6577            return res.key.packageName;
6578        } catch (ClassCastException e) {
6579        }
6580        return null;
6581    }
6582
6583    @Override
6584    public int getUidForIntentSender(IIntentSender sender) {
6585        if (sender instanceof PendingIntentRecord) {
6586            try {
6587                PendingIntentRecord res = (PendingIntentRecord)sender;
6588                return res.uid;
6589            } catch (ClassCastException e) {
6590            }
6591        }
6592        return -1;
6593    }
6594
6595    @Override
6596    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6597        if (!(pendingResult instanceof PendingIntentRecord)) {
6598            return false;
6599        }
6600        try {
6601            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6602            if (res.key.allIntents == null) {
6603                return false;
6604            }
6605            for (int i=0; i<res.key.allIntents.length; i++) {
6606                Intent intent = res.key.allIntents[i];
6607                if (intent.getPackage() != null && intent.getComponent() != null) {
6608                    return false;
6609                }
6610            }
6611            return true;
6612        } catch (ClassCastException e) {
6613        }
6614        return false;
6615    }
6616
6617    @Override
6618    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6619        if (!(pendingResult instanceof PendingIntentRecord)) {
6620            return false;
6621        }
6622        try {
6623            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6624            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6625                return true;
6626            }
6627            return false;
6628        } catch (ClassCastException e) {
6629        }
6630        return false;
6631    }
6632
6633    @Override
6634    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6635        if (!(pendingResult instanceof PendingIntentRecord)) {
6636            return null;
6637        }
6638        try {
6639            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6640            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6641        } catch (ClassCastException e) {
6642        }
6643        return null;
6644    }
6645
6646    @Override
6647    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6648        if (!(pendingResult instanceof PendingIntentRecord)) {
6649            return null;
6650        }
6651        try {
6652            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6653            Intent intent = res.key.requestIntent;
6654            if (intent != null) {
6655                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6656                        || res.lastTagPrefix.equals(prefix))) {
6657                    return res.lastTag;
6658                }
6659                res.lastTagPrefix = prefix;
6660                StringBuilder sb = new StringBuilder(128);
6661                if (prefix != null) {
6662                    sb.append(prefix);
6663                }
6664                if (intent.getAction() != null) {
6665                    sb.append(intent.getAction());
6666                } else if (intent.getComponent() != null) {
6667                    intent.getComponent().appendShortString(sb);
6668                } else {
6669                    sb.append("?");
6670                }
6671                return res.lastTag = sb.toString();
6672            }
6673        } catch (ClassCastException e) {
6674        }
6675        return null;
6676    }
6677
6678    @Override
6679    public void setProcessLimit(int max) {
6680        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6681                "setProcessLimit()");
6682        synchronized (this) {
6683            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6684            mProcessLimitOverride = max;
6685        }
6686        trimApplications();
6687    }
6688
6689    @Override
6690    public int getProcessLimit() {
6691        synchronized (this) {
6692            return mProcessLimitOverride;
6693        }
6694    }
6695
6696    void foregroundTokenDied(ForegroundToken token) {
6697        synchronized (ActivityManagerService.this) {
6698            synchronized (mPidsSelfLocked) {
6699                ForegroundToken cur
6700                    = mForegroundProcesses.get(token.pid);
6701                if (cur != token) {
6702                    return;
6703                }
6704                mForegroundProcesses.remove(token.pid);
6705                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6706                if (pr == null) {
6707                    return;
6708                }
6709                pr.forcingToForeground = null;
6710                updateProcessForegroundLocked(pr, false, false);
6711            }
6712            updateOomAdjLocked();
6713        }
6714    }
6715
6716    @Override
6717    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6718        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6719                "setProcessForeground()");
6720        synchronized(this) {
6721            boolean changed = false;
6722
6723            synchronized (mPidsSelfLocked) {
6724                ProcessRecord pr = mPidsSelfLocked.get(pid);
6725                if (pr == null && isForeground) {
6726                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6727                    return;
6728                }
6729                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6730                if (oldToken != null) {
6731                    oldToken.token.unlinkToDeath(oldToken, 0);
6732                    mForegroundProcesses.remove(pid);
6733                    if (pr != null) {
6734                        pr.forcingToForeground = null;
6735                    }
6736                    changed = true;
6737                }
6738                if (isForeground && token != null) {
6739                    ForegroundToken newToken = new ForegroundToken() {
6740                        @Override
6741                        public void binderDied() {
6742                            foregroundTokenDied(this);
6743                        }
6744                    };
6745                    newToken.pid = pid;
6746                    newToken.token = token;
6747                    try {
6748                        token.linkToDeath(newToken, 0);
6749                        mForegroundProcesses.put(pid, newToken);
6750                        pr.forcingToForeground = token;
6751                        changed = true;
6752                    } catch (RemoteException e) {
6753                        // If the process died while doing this, we will later
6754                        // do the cleanup with the process death link.
6755                    }
6756                }
6757            }
6758
6759            if (changed) {
6760                updateOomAdjLocked();
6761            }
6762        }
6763    }
6764
6765    // =========================================================
6766    // PERMISSIONS
6767    // =========================================================
6768
6769    static class PermissionController extends IPermissionController.Stub {
6770        ActivityManagerService mActivityManagerService;
6771        PermissionController(ActivityManagerService activityManagerService) {
6772            mActivityManagerService = activityManagerService;
6773        }
6774
6775        @Override
6776        public boolean checkPermission(String permission, int pid, int uid) {
6777            return mActivityManagerService.checkPermission(permission, pid,
6778                    uid) == PackageManager.PERMISSION_GRANTED;
6779        }
6780    }
6781
6782    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6783        @Override
6784        public int checkComponentPermission(String permission, int pid, int uid,
6785                int owningUid, boolean exported) {
6786            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6787                    owningUid, exported);
6788        }
6789
6790        @Override
6791        public Object getAMSLock() {
6792            return ActivityManagerService.this;
6793        }
6794    }
6795
6796    /**
6797     * This can be called with or without the global lock held.
6798     */
6799    int checkComponentPermission(String permission, int pid, int uid,
6800            int owningUid, boolean exported) {
6801        // We might be performing an operation on behalf of an indirect binder
6802        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6803        // client identity accordingly before proceeding.
6804        Identity tlsIdentity = sCallerIdentity.get();
6805        if (tlsIdentity != null) {
6806            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6807                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6808            uid = tlsIdentity.uid;
6809            pid = tlsIdentity.pid;
6810        }
6811
6812        if (pid == MY_PID) {
6813            return PackageManager.PERMISSION_GRANTED;
6814        }
6815
6816        return ActivityManager.checkComponentPermission(permission, uid,
6817                owningUid, exported);
6818    }
6819
6820    /**
6821     * As the only public entry point for permissions checking, this method
6822     * can enforce the semantic that requesting a check on a null global
6823     * permission is automatically denied.  (Internally a null permission
6824     * string is used when calling {@link #checkComponentPermission} in cases
6825     * when only uid-based security is needed.)
6826     *
6827     * This can be called with or without the global lock held.
6828     */
6829    @Override
6830    public int checkPermission(String permission, int pid, int uid) {
6831        if (permission == null) {
6832            return PackageManager.PERMISSION_DENIED;
6833        }
6834        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6835    }
6836
6837    /**
6838     * Binder IPC calls go through the public entry point.
6839     * This can be called with or without the global lock held.
6840     */
6841    int checkCallingPermission(String permission) {
6842        return checkPermission(permission,
6843                Binder.getCallingPid(),
6844                UserHandle.getAppId(Binder.getCallingUid()));
6845    }
6846
6847    /**
6848     * This can be called with or without the global lock held.
6849     */
6850    void enforceCallingPermission(String permission, String func) {
6851        if (checkCallingPermission(permission)
6852                == PackageManager.PERMISSION_GRANTED) {
6853            return;
6854        }
6855
6856        String msg = "Permission Denial: " + func + " from pid="
6857                + Binder.getCallingPid()
6858                + ", uid=" + Binder.getCallingUid()
6859                + " requires " + permission;
6860        Slog.w(TAG, msg);
6861        throw new SecurityException(msg);
6862    }
6863
6864    /**
6865     * Determine if UID is holding permissions required to access {@link Uri} in
6866     * the given {@link ProviderInfo}. Final permission checking is always done
6867     * in {@link ContentProvider}.
6868     */
6869    private final boolean checkHoldingPermissionsLocked(
6870            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6871        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6872                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6873        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6874            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6875                    != PERMISSION_GRANTED) {
6876                return false;
6877            }
6878        }
6879        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6880    }
6881
6882    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6883            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6884        if (pi.applicationInfo.uid == uid) {
6885            return true;
6886        } else if (!pi.exported) {
6887            return false;
6888        }
6889
6890        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6891        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6892        try {
6893            // check if target holds top-level <provider> permissions
6894            if (!readMet && pi.readPermission != null && considerUidPermissions
6895                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6896                readMet = true;
6897            }
6898            if (!writeMet && pi.writePermission != null && considerUidPermissions
6899                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6900                writeMet = true;
6901            }
6902
6903            // track if unprotected read/write is allowed; any denied
6904            // <path-permission> below removes this ability
6905            boolean allowDefaultRead = pi.readPermission == null;
6906            boolean allowDefaultWrite = pi.writePermission == null;
6907
6908            // check if target holds any <path-permission> that match uri
6909            final PathPermission[] pps = pi.pathPermissions;
6910            if (pps != null) {
6911                final String path = grantUri.uri.getPath();
6912                int i = pps.length;
6913                while (i > 0 && (!readMet || !writeMet)) {
6914                    i--;
6915                    PathPermission pp = pps[i];
6916                    if (pp.match(path)) {
6917                        if (!readMet) {
6918                            final String pprperm = pp.getReadPermission();
6919                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6920                                    + pprperm + " for " + pp.getPath()
6921                                    + ": match=" + pp.match(path)
6922                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6923                            if (pprperm != null) {
6924                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6925                                        == PERMISSION_GRANTED) {
6926                                    readMet = true;
6927                                } else {
6928                                    allowDefaultRead = false;
6929                                }
6930                            }
6931                        }
6932                        if (!writeMet) {
6933                            final String ppwperm = pp.getWritePermission();
6934                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6935                                    + ppwperm + " for " + pp.getPath()
6936                                    + ": match=" + pp.match(path)
6937                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6938                            if (ppwperm != null) {
6939                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6940                                        == PERMISSION_GRANTED) {
6941                                    writeMet = true;
6942                                } else {
6943                                    allowDefaultWrite = false;
6944                                }
6945                            }
6946                        }
6947                    }
6948                }
6949            }
6950
6951            // grant unprotected <provider> read/write, if not blocked by
6952            // <path-permission> above
6953            if (allowDefaultRead) readMet = true;
6954            if (allowDefaultWrite) writeMet = true;
6955
6956        } catch (RemoteException e) {
6957            return false;
6958        }
6959
6960        return readMet && writeMet;
6961    }
6962
6963    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6964        ProviderInfo pi = null;
6965        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6966        if (cpr != null) {
6967            pi = cpr.info;
6968        } else {
6969            try {
6970                pi = AppGlobals.getPackageManager().resolveContentProvider(
6971                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6972            } catch (RemoteException ex) {
6973            }
6974        }
6975        return pi;
6976    }
6977
6978    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6979        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6980        if (targetUris != null) {
6981            return targetUris.get(grantUri);
6982        }
6983        return null;
6984    }
6985
6986    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6987            String targetPkg, int targetUid, GrantUri grantUri) {
6988        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6989        if (targetUris == null) {
6990            targetUris = Maps.newArrayMap();
6991            mGrantedUriPermissions.put(targetUid, targetUris);
6992        }
6993
6994        UriPermission perm = targetUris.get(grantUri);
6995        if (perm == null) {
6996            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6997            targetUris.put(grantUri, perm);
6998        }
6999
7000        return perm;
7001    }
7002
7003    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7004            final int modeFlags) {
7005        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7006        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7007                : UriPermission.STRENGTH_OWNED;
7008
7009        // Root gets to do everything.
7010        if (uid == 0) {
7011            return true;
7012        }
7013
7014        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7015        if (perms == null) return false;
7016
7017        // First look for exact match
7018        final UriPermission exactPerm = perms.get(grantUri);
7019        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7020            return true;
7021        }
7022
7023        // No exact match, look for prefixes
7024        final int N = perms.size();
7025        for (int i = 0; i < N; i++) {
7026            final UriPermission perm = perms.valueAt(i);
7027            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7028                    && perm.getStrength(modeFlags) >= minStrength) {
7029                return true;
7030            }
7031        }
7032
7033        return false;
7034    }
7035
7036    /**
7037     * @param uri This uri must NOT contain an embedded userId.
7038     * @param userId The userId in which the uri is to be resolved.
7039     */
7040    @Override
7041    public int checkUriPermission(Uri uri, int pid, int uid,
7042            final int modeFlags, int userId) {
7043        enforceNotIsolatedCaller("checkUriPermission");
7044
7045        // Another redirected-binder-call permissions check as in
7046        // {@link checkComponentPermission}.
7047        Identity tlsIdentity = sCallerIdentity.get();
7048        if (tlsIdentity != null) {
7049            uid = tlsIdentity.uid;
7050            pid = tlsIdentity.pid;
7051        }
7052
7053        // Our own process gets to do everything.
7054        if (pid == MY_PID) {
7055            return PackageManager.PERMISSION_GRANTED;
7056        }
7057        synchronized (this) {
7058            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7059                    ? PackageManager.PERMISSION_GRANTED
7060                    : PackageManager.PERMISSION_DENIED;
7061        }
7062    }
7063
7064    /**
7065     * Check if the targetPkg can be granted permission to access uri by
7066     * the callingUid using the given modeFlags.  Throws a security exception
7067     * if callingUid is not allowed to do this.  Returns the uid of the target
7068     * if the URI permission grant should be performed; returns -1 if it is not
7069     * needed (for example targetPkg already has permission to access the URI).
7070     * If you already know the uid of the target, you can supply it in
7071     * lastTargetUid else set that to -1.
7072     */
7073    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7074            final int modeFlags, int lastTargetUid) {
7075        if (!Intent.isAccessUriMode(modeFlags)) {
7076            return -1;
7077        }
7078
7079        if (targetPkg != null) {
7080            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7081                    "Checking grant " + targetPkg + " permission to " + grantUri);
7082        }
7083
7084        final IPackageManager pm = AppGlobals.getPackageManager();
7085
7086        // If this is not a content: uri, we can't do anything with it.
7087        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7088            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7089                    "Can't grant URI permission for non-content URI: " + grantUri);
7090            return -1;
7091        }
7092
7093        final String authority = grantUri.uri.getAuthority();
7094        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7095        if (pi == null) {
7096            Slog.w(TAG, "No content provider found for permission check: " +
7097                    grantUri.uri.toSafeString());
7098            return -1;
7099        }
7100
7101        int targetUid = lastTargetUid;
7102        if (targetUid < 0 && targetPkg != null) {
7103            try {
7104                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7105                if (targetUid < 0) {
7106                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7107                            "Can't grant URI permission no uid for: " + targetPkg);
7108                    return -1;
7109                }
7110            } catch (RemoteException ex) {
7111                return -1;
7112            }
7113        }
7114
7115        if (targetUid >= 0) {
7116            // First...  does the target actually need this permission?
7117            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7118                // No need to grant the target this permission.
7119                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7120                        "Target " + targetPkg + " already has full permission to " + grantUri);
7121                return -1;
7122            }
7123        } else {
7124            // First...  there is no target package, so can anyone access it?
7125            boolean allowed = pi.exported;
7126            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7127                if (pi.readPermission != null) {
7128                    allowed = false;
7129                }
7130            }
7131            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7132                if (pi.writePermission != null) {
7133                    allowed = false;
7134                }
7135            }
7136            if (allowed) {
7137                return -1;
7138            }
7139        }
7140
7141        /* There is a special cross user grant if:
7142         * - The target is on another user.
7143         * - Apps on the current user can access the uri without any uid permissions.
7144         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7145         * grant uri permissions.
7146         */
7147        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7148                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7149                modeFlags, false /*without considering the uid permissions*/);
7150
7151        // Second...  is the provider allowing granting of URI permissions?
7152        if (!specialCrossUserGrant) {
7153            if (!pi.grantUriPermissions) {
7154                throw new SecurityException("Provider " + pi.packageName
7155                        + "/" + pi.name
7156                        + " does not allow granting of Uri permissions (uri "
7157                        + grantUri + ")");
7158            }
7159            if (pi.uriPermissionPatterns != null) {
7160                final int N = pi.uriPermissionPatterns.length;
7161                boolean allowed = false;
7162                for (int i=0; i<N; i++) {
7163                    if (pi.uriPermissionPatterns[i] != null
7164                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7165                        allowed = true;
7166                        break;
7167                    }
7168                }
7169                if (!allowed) {
7170                    throw new SecurityException("Provider " + pi.packageName
7171                            + "/" + pi.name
7172                            + " does not allow granting of permission to path of Uri "
7173                            + grantUri);
7174                }
7175            }
7176        }
7177
7178        // Third...  does the caller itself have permission to access
7179        // this uri?
7180        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7181            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7182                // Require they hold a strong enough Uri permission
7183                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7184                    throw new SecurityException("Uid " + callingUid
7185                            + " does not have permission to uri " + grantUri);
7186                }
7187            }
7188        }
7189        return targetUid;
7190    }
7191
7192    /**
7193     * @param uri This uri must NOT contain an embedded userId.
7194     * @param userId The userId in which the uri is to be resolved.
7195     */
7196    @Override
7197    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7198            final int modeFlags, int userId) {
7199        enforceNotIsolatedCaller("checkGrantUriPermission");
7200        synchronized(this) {
7201            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7202                    new GrantUri(userId, uri, false), modeFlags, -1);
7203        }
7204    }
7205
7206    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7207            final int modeFlags, UriPermissionOwner owner) {
7208        if (!Intent.isAccessUriMode(modeFlags)) {
7209            return;
7210        }
7211
7212        // So here we are: the caller has the assumed permission
7213        // to the uri, and the target doesn't.  Let's now give this to
7214        // the target.
7215
7216        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7217                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7218
7219        final String authority = grantUri.uri.getAuthority();
7220        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7221        if (pi == null) {
7222            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7223            return;
7224        }
7225
7226        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7227            grantUri.prefix = true;
7228        }
7229        final UriPermission perm = findOrCreateUriPermissionLocked(
7230                pi.packageName, targetPkg, targetUid, grantUri);
7231        perm.grantModes(modeFlags, owner);
7232    }
7233
7234    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7235            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7236        if (targetPkg == null) {
7237            throw new NullPointerException("targetPkg");
7238        }
7239        int targetUid;
7240        final IPackageManager pm = AppGlobals.getPackageManager();
7241        try {
7242            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7243        } catch (RemoteException ex) {
7244            return;
7245        }
7246
7247        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7248                targetUid);
7249        if (targetUid < 0) {
7250            return;
7251        }
7252
7253        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7254                owner);
7255    }
7256
7257    static class NeededUriGrants extends ArrayList<GrantUri> {
7258        final String targetPkg;
7259        final int targetUid;
7260        final int flags;
7261
7262        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7263            this.targetPkg = targetPkg;
7264            this.targetUid = targetUid;
7265            this.flags = flags;
7266        }
7267    }
7268
7269    /**
7270     * Like checkGrantUriPermissionLocked, but takes an Intent.
7271     */
7272    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7273            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7274        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7275                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7276                + " clip=" + (intent != null ? intent.getClipData() : null)
7277                + " from " + intent + "; flags=0x"
7278                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7279
7280        if (targetPkg == null) {
7281            throw new NullPointerException("targetPkg");
7282        }
7283
7284        if (intent == null) {
7285            return null;
7286        }
7287        Uri data = intent.getData();
7288        ClipData clip = intent.getClipData();
7289        if (data == null && clip == null) {
7290            return null;
7291        }
7292        // Default userId for uris in the intent (if they don't specify it themselves)
7293        int contentUserHint = intent.getContentUserHint();
7294        if (contentUserHint == UserHandle.USER_CURRENT) {
7295            contentUserHint = UserHandle.getUserId(callingUid);
7296        }
7297        final IPackageManager pm = AppGlobals.getPackageManager();
7298        int targetUid;
7299        if (needed != null) {
7300            targetUid = needed.targetUid;
7301        } else {
7302            try {
7303                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7304            } catch (RemoteException ex) {
7305                return null;
7306            }
7307            if (targetUid < 0) {
7308                if (DEBUG_URI_PERMISSION) {
7309                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7310                            + " on user " + targetUserId);
7311                }
7312                return null;
7313            }
7314        }
7315        if (data != null) {
7316            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7317            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7318                    targetUid);
7319            if (targetUid > 0) {
7320                if (needed == null) {
7321                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7322                }
7323                needed.add(grantUri);
7324            }
7325        }
7326        if (clip != null) {
7327            for (int i=0; i<clip.getItemCount(); i++) {
7328                Uri uri = clip.getItemAt(i).getUri();
7329                if (uri != null) {
7330                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7331                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7332                            targetUid);
7333                    if (targetUid > 0) {
7334                        if (needed == null) {
7335                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7336                        }
7337                        needed.add(grantUri);
7338                    }
7339                } else {
7340                    Intent clipIntent = clip.getItemAt(i).getIntent();
7341                    if (clipIntent != null) {
7342                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7343                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7344                        if (newNeeded != null) {
7345                            needed = newNeeded;
7346                        }
7347                    }
7348                }
7349            }
7350        }
7351
7352        return needed;
7353    }
7354
7355    /**
7356     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7357     */
7358    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7359            UriPermissionOwner owner) {
7360        if (needed != null) {
7361            for (int i=0; i<needed.size(); i++) {
7362                GrantUri grantUri = needed.get(i);
7363                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7364                        grantUri, needed.flags, owner);
7365            }
7366        }
7367    }
7368
7369    void grantUriPermissionFromIntentLocked(int callingUid,
7370            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7371        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7372                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7373        if (needed == null) {
7374            return;
7375        }
7376
7377        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7378    }
7379
7380    /**
7381     * @param uri This uri must NOT contain an embedded userId.
7382     * @param userId The userId in which the uri is to be resolved.
7383     */
7384    @Override
7385    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7386            final int modeFlags, int userId) {
7387        enforceNotIsolatedCaller("grantUriPermission");
7388        GrantUri grantUri = new GrantUri(userId, uri, false);
7389        synchronized(this) {
7390            final ProcessRecord r = getRecordForAppLocked(caller);
7391            if (r == null) {
7392                throw new SecurityException("Unable to find app for caller "
7393                        + caller
7394                        + " when granting permission to uri " + grantUri);
7395            }
7396            if (targetPkg == null) {
7397                throw new IllegalArgumentException("null target");
7398            }
7399            if (grantUri == null) {
7400                throw new IllegalArgumentException("null uri");
7401            }
7402
7403            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7404                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7405                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7406                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7407
7408            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7409                    UserHandle.getUserId(r.uid));
7410        }
7411    }
7412
7413    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7414        if (perm.modeFlags == 0) {
7415            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7416                    perm.targetUid);
7417            if (perms != null) {
7418                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7419                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7420
7421                perms.remove(perm.uri);
7422                if (perms.isEmpty()) {
7423                    mGrantedUriPermissions.remove(perm.targetUid);
7424                }
7425            }
7426        }
7427    }
7428
7429    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7430        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7431
7432        final IPackageManager pm = AppGlobals.getPackageManager();
7433        final String authority = grantUri.uri.getAuthority();
7434        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7435        if (pi == null) {
7436            Slog.w(TAG, "No content provider found for permission revoke: "
7437                    + grantUri.toSafeString());
7438            return;
7439        }
7440
7441        // Does the caller have this permission on the URI?
7442        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7443            // If they don't have direct access to the URI, then revoke any
7444            // ownerless URI permissions that have been granted to them.
7445            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7446            if (perms != null) {
7447                boolean persistChanged = false;
7448                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7449                    final UriPermission perm = it.next();
7450                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7451                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7452                        if (DEBUG_URI_PERMISSION)
7453                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7454                                    " permission to " + perm.uri);
7455                        persistChanged |= perm.revokeModes(
7456                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7457                        if (perm.modeFlags == 0) {
7458                            it.remove();
7459                        }
7460                    }
7461                }
7462                if (perms.isEmpty()) {
7463                    mGrantedUriPermissions.remove(callingUid);
7464                }
7465                if (persistChanged) {
7466                    schedulePersistUriGrants();
7467                }
7468            }
7469            return;
7470        }
7471
7472        boolean persistChanged = false;
7473
7474        // Go through all of the permissions and remove any that match.
7475        int N = mGrantedUriPermissions.size();
7476        for (int i = 0; i < N; i++) {
7477            final int targetUid = mGrantedUriPermissions.keyAt(i);
7478            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7479
7480            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7481                final UriPermission perm = it.next();
7482                if (perm.uri.sourceUserId == grantUri.sourceUserId
7483                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7484                    if (DEBUG_URI_PERMISSION)
7485                        Slog.v(TAG,
7486                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7487                    persistChanged |= perm.revokeModes(
7488                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7489                    if (perm.modeFlags == 0) {
7490                        it.remove();
7491                    }
7492                }
7493            }
7494
7495            if (perms.isEmpty()) {
7496                mGrantedUriPermissions.remove(targetUid);
7497                N--;
7498                i--;
7499            }
7500        }
7501
7502        if (persistChanged) {
7503            schedulePersistUriGrants();
7504        }
7505    }
7506
7507    /**
7508     * @param uri This uri must NOT contain an embedded userId.
7509     * @param userId The userId in which the uri is to be resolved.
7510     */
7511    @Override
7512    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7513            int userId) {
7514        enforceNotIsolatedCaller("revokeUriPermission");
7515        synchronized(this) {
7516            final ProcessRecord r = getRecordForAppLocked(caller);
7517            if (r == null) {
7518                throw new SecurityException("Unable to find app for caller "
7519                        + caller
7520                        + " when revoking permission to uri " + uri);
7521            }
7522            if (uri == null) {
7523                Slog.w(TAG, "revokeUriPermission: null uri");
7524                return;
7525            }
7526
7527            if (!Intent.isAccessUriMode(modeFlags)) {
7528                return;
7529            }
7530
7531            final IPackageManager pm = AppGlobals.getPackageManager();
7532            final String authority = uri.getAuthority();
7533            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7534            if (pi == null) {
7535                Slog.w(TAG, "No content provider found for permission revoke: "
7536                        + uri.toSafeString());
7537                return;
7538            }
7539
7540            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7541        }
7542    }
7543
7544    /**
7545     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7546     * given package.
7547     *
7548     * @param packageName Package name to match, or {@code null} to apply to all
7549     *            packages.
7550     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7551     *            to all users.
7552     * @param persistable If persistable grants should be removed.
7553     */
7554    private void removeUriPermissionsForPackageLocked(
7555            String packageName, int userHandle, boolean persistable) {
7556        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7557            throw new IllegalArgumentException("Must narrow by either package or user");
7558        }
7559
7560        boolean persistChanged = false;
7561
7562        int N = mGrantedUriPermissions.size();
7563        for (int i = 0; i < N; i++) {
7564            final int targetUid = mGrantedUriPermissions.keyAt(i);
7565            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7566
7567            // Only inspect grants matching user
7568            if (userHandle == UserHandle.USER_ALL
7569                    || userHandle == UserHandle.getUserId(targetUid)) {
7570                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7571                    final UriPermission perm = it.next();
7572
7573                    // Only inspect grants matching package
7574                    if (packageName == null || perm.sourcePkg.equals(packageName)
7575                            || perm.targetPkg.equals(packageName)) {
7576                        persistChanged |= perm.revokeModes(persistable
7577                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7578
7579                        // Only remove when no modes remain; any persisted grants
7580                        // will keep this alive.
7581                        if (perm.modeFlags == 0) {
7582                            it.remove();
7583                        }
7584                    }
7585                }
7586
7587                if (perms.isEmpty()) {
7588                    mGrantedUriPermissions.remove(targetUid);
7589                    N--;
7590                    i--;
7591                }
7592            }
7593        }
7594
7595        if (persistChanged) {
7596            schedulePersistUriGrants();
7597        }
7598    }
7599
7600    @Override
7601    public IBinder newUriPermissionOwner(String name) {
7602        enforceNotIsolatedCaller("newUriPermissionOwner");
7603        synchronized(this) {
7604            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7605            return owner.getExternalTokenLocked();
7606        }
7607    }
7608
7609    /**
7610     * @param uri This uri must NOT contain an embedded userId.
7611     * @param sourceUserId The userId in which the uri is to be resolved.
7612     * @param targetUserId The userId of the app that receives the grant.
7613     */
7614    @Override
7615    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7616            final int modeFlags, int sourceUserId, int targetUserId) {
7617        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7618                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7619        synchronized(this) {
7620            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7621            if (owner == null) {
7622                throw new IllegalArgumentException("Unknown owner: " + token);
7623            }
7624            if (fromUid != Binder.getCallingUid()) {
7625                if (Binder.getCallingUid() != Process.myUid()) {
7626                    // Only system code can grant URI permissions on behalf
7627                    // of other users.
7628                    throw new SecurityException("nice try");
7629                }
7630            }
7631            if (targetPkg == null) {
7632                throw new IllegalArgumentException("null target");
7633            }
7634            if (uri == null) {
7635                throw new IllegalArgumentException("null uri");
7636            }
7637
7638            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7639                    modeFlags, owner, targetUserId);
7640        }
7641    }
7642
7643    /**
7644     * @param uri This uri must NOT contain an embedded userId.
7645     * @param userId The userId in which the uri is to be resolved.
7646     */
7647    @Override
7648    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7649        synchronized(this) {
7650            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7651            if (owner == null) {
7652                throw new IllegalArgumentException("Unknown owner: " + token);
7653            }
7654
7655            if (uri == null) {
7656                owner.removeUriPermissionsLocked(mode);
7657            } else {
7658                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7659            }
7660        }
7661    }
7662
7663    private void schedulePersistUriGrants() {
7664        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7665            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7666                    10 * DateUtils.SECOND_IN_MILLIS);
7667        }
7668    }
7669
7670    private void writeGrantedUriPermissions() {
7671        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7672
7673        // Snapshot permissions so we can persist without lock
7674        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7675        synchronized (this) {
7676            final int size = mGrantedUriPermissions.size();
7677            for (int i = 0; i < size; i++) {
7678                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7679                for (UriPermission perm : perms.values()) {
7680                    if (perm.persistedModeFlags != 0) {
7681                        persist.add(perm.snapshot());
7682                    }
7683                }
7684            }
7685        }
7686
7687        FileOutputStream fos = null;
7688        try {
7689            fos = mGrantFile.startWrite();
7690
7691            XmlSerializer out = new FastXmlSerializer();
7692            out.setOutput(fos, "utf-8");
7693            out.startDocument(null, true);
7694            out.startTag(null, TAG_URI_GRANTS);
7695            for (UriPermission.Snapshot perm : persist) {
7696                out.startTag(null, TAG_URI_GRANT);
7697                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7698                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7699                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7700                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7701                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7702                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7703                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7704                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7705                out.endTag(null, TAG_URI_GRANT);
7706            }
7707            out.endTag(null, TAG_URI_GRANTS);
7708            out.endDocument();
7709
7710            mGrantFile.finishWrite(fos);
7711        } catch (IOException e) {
7712            if (fos != null) {
7713                mGrantFile.failWrite(fos);
7714            }
7715        }
7716    }
7717
7718    private void readGrantedUriPermissionsLocked() {
7719        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7720
7721        final long now = System.currentTimeMillis();
7722
7723        FileInputStream fis = null;
7724        try {
7725            fis = mGrantFile.openRead();
7726            final XmlPullParser in = Xml.newPullParser();
7727            in.setInput(fis, null);
7728
7729            int type;
7730            while ((type = in.next()) != END_DOCUMENT) {
7731                final String tag = in.getName();
7732                if (type == START_TAG) {
7733                    if (TAG_URI_GRANT.equals(tag)) {
7734                        final int sourceUserId;
7735                        final int targetUserId;
7736                        final int userHandle = readIntAttribute(in,
7737                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7738                        if (userHandle != UserHandle.USER_NULL) {
7739                            // For backwards compatibility.
7740                            sourceUserId = userHandle;
7741                            targetUserId = userHandle;
7742                        } else {
7743                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7744                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7745                        }
7746                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7747                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7748                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7749                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7750                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7751                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7752
7753                        // Sanity check that provider still belongs to source package
7754                        final ProviderInfo pi = getProviderInfoLocked(
7755                                uri.getAuthority(), sourceUserId);
7756                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7757                            int targetUid = -1;
7758                            try {
7759                                targetUid = AppGlobals.getPackageManager()
7760                                        .getPackageUid(targetPkg, targetUserId);
7761                            } catch (RemoteException e) {
7762                            }
7763                            if (targetUid != -1) {
7764                                final UriPermission perm = findOrCreateUriPermissionLocked(
7765                                        sourcePkg, targetPkg, targetUid,
7766                                        new GrantUri(sourceUserId, uri, prefix));
7767                                perm.initPersistedModes(modeFlags, createdTime);
7768                            }
7769                        } else {
7770                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7771                                    + " but instead found " + pi);
7772                        }
7773                    }
7774                }
7775            }
7776        } catch (FileNotFoundException e) {
7777            // Missing grants is okay
7778        } catch (IOException e) {
7779            Slog.wtf(TAG, "Failed reading Uri grants", e);
7780        } catch (XmlPullParserException e) {
7781            Slog.wtf(TAG, "Failed reading Uri grants", e);
7782        } finally {
7783            IoUtils.closeQuietly(fis);
7784        }
7785    }
7786
7787    /**
7788     * @param uri This uri must NOT contain an embedded userId.
7789     * @param userId The userId in which the uri is to be resolved.
7790     */
7791    @Override
7792    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7793        enforceNotIsolatedCaller("takePersistableUriPermission");
7794
7795        Preconditions.checkFlagsArgument(modeFlags,
7796                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7797
7798        synchronized (this) {
7799            final int callingUid = Binder.getCallingUid();
7800            boolean persistChanged = false;
7801            GrantUri grantUri = new GrantUri(userId, uri, false);
7802
7803            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7804                    new GrantUri(userId, uri, false));
7805            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7806                    new GrantUri(userId, uri, true));
7807
7808            final boolean exactValid = (exactPerm != null)
7809                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7810            final boolean prefixValid = (prefixPerm != null)
7811                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7812
7813            if (!(exactValid || prefixValid)) {
7814                throw new SecurityException("No persistable permission grants found for UID "
7815                        + callingUid + " and Uri " + grantUri.toSafeString());
7816            }
7817
7818            if (exactValid) {
7819                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7820            }
7821            if (prefixValid) {
7822                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7823            }
7824
7825            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7826
7827            if (persistChanged) {
7828                schedulePersistUriGrants();
7829            }
7830        }
7831    }
7832
7833    /**
7834     * @param uri This uri must NOT contain an embedded userId.
7835     * @param userId The userId in which the uri is to be resolved.
7836     */
7837    @Override
7838    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7839        enforceNotIsolatedCaller("releasePersistableUriPermission");
7840
7841        Preconditions.checkFlagsArgument(modeFlags,
7842                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7843
7844        synchronized (this) {
7845            final int callingUid = Binder.getCallingUid();
7846            boolean persistChanged = false;
7847
7848            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7849                    new GrantUri(userId, uri, false));
7850            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7851                    new GrantUri(userId, uri, true));
7852            if (exactPerm == null && prefixPerm == null) {
7853                throw new SecurityException("No permission grants found for UID " + callingUid
7854                        + " and Uri " + uri.toSafeString());
7855            }
7856
7857            if (exactPerm != null) {
7858                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7859                removeUriPermissionIfNeededLocked(exactPerm);
7860            }
7861            if (prefixPerm != null) {
7862                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7863                removeUriPermissionIfNeededLocked(prefixPerm);
7864            }
7865
7866            if (persistChanged) {
7867                schedulePersistUriGrants();
7868            }
7869        }
7870    }
7871
7872    /**
7873     * Prune any older {@link UriPermission} for the given UID until outstanding
7874     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7875     *
7876     * @return if any mutations occured that require persisting.
7877     */
7878    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7879        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7880        if (perms == null) return false;
7881        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7882
7883        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7884        for (UriPermission perm : perms.values()) {
7885            if (perm.persistedModeFlags != 0) {
7886                persisted.add(perm);
7887            }
7888        }
7889
7890        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7891        if (trimCount <= 0) return false;
7892
7893        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7894        for (int i = 0; i < trimCount; i++) {
7895            final UriPermission perm = persisted.get(i);
7896
7897            if (DEBUG_URI_PERMISSION) {
7898                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7899            }
7900
7901            perm.releasePersistableModes(~0);
7902            removeUriPermissionIfNeededLocked(perm);
7903        }
7904
7905        return true;
7906    }
7907
7908    @Override
7909    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7910            String packageName, boolean incoming) {
7911        enforceNotIsolatedCaller("getPersistedUriPermissions");
7912        Preconditions.checkNotNull(packageName, "packageName");
7913
7914        final int callingUid = Binder.getCallingUid();
7915        final IPackageManager pm = AppGlobals.getPackageManager();
7916        try {
7917            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7918            if (packageUid != callingUid) {
7919                throw new SecurityException(
7920                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7921            }
7922        } catch (RemoteException e) {
7923            throw new SecurityException("Failed to verify package name ownership");
7924        }
7925
7926        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7927        synchronized (this) {
7928            if (incoming) {
7929                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7930                        callingUid);
7931                if (perms == null) {
7932                    Slog.w(TAG, "No permission grants found for " + packageName);
7933                } else {
7934                    for (UriPermission perm : perms.values()) {
7935                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7936                            result.add(perm.buildPersistedPublicApiObject());
7937                        }
7938                    }
7939                }
7940            } else {
7941                final int size = mGrantedUriPermissions.size();
7942                for (int i = 0; i < size; i++) {
7943                    final ArrayMap<GrantUri, UriPermission> perms =
7944                            mGrantedUriPermissions.valueAt(i);
7945                    for (UriPermission perm : perms.values()) {
7946                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7947                            result.add(perm.buildPersistedPublicApiObject());
7948                        }
7949                    }
7950                }
7951            }
7952        }
7953        return new ParceledListSlice<android.content.UriPermission>(result);
7954    }
7955
7956    @Override
7957    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7958        synchronized (this) {
7959            ProcessRecord app =
7960                who != null ? getRecordForAppLocked(who) : null;
7961            if (app == null) return;
7962
7963            Message msg = Message.obtain();
7964            msg.what = WAIT_FOR_DEBUGGER_MSG;
7965            msg.obj = app;
7966            msg.arg1 = waiting ? 1 : 0;
7967            mHandler.sendMessage(msg);
7968        }
7969    }
7970
7971    @Override
7972    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7973        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7974        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7975        outInfo.availMem = Process.getFreeMemory();
7976        outInfo.totalMem = Process.getTotalMemory();
7977        outInfo.threshold = homeAppMem;
7978        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7979        outInfo.hiddenAppThreshold = cachedAppMem;
7980        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7981                ProcessList.SERVICE_ADJ);
7982        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7983                ProcessList.VISIBLE_APP_ADJ);
7984        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7985                ProcessList.FOREGROUND_APP_ADJ);
7986    }
7987
7988    // =========================================================
7989    // TASK MANAGEMENT
7990    // =========================================================
7991
7992    @Override
7993    public List<IAppTask> getAppTasks(String callingPackage) {
7994        int callingUid = Binder.getCallingUid();
7995        long ident = Binder.clearCallingIdentity();
7996
7997        synchronized(this) {
7998            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7999            try {
8000                if (localLOGV) Slog.v(TAG, "getAppTasks");
8001
8002                final int N = mRecentTasks.size();
8003                for (int i = 0; i < N; i++) {
8004                    TaskRecord tr = mRecentTasks.get(i);
8005                    // Skip tasks that do not match the caller.  We don't need to verify
8006                    // callingPackage, because we are also limiting to callingUid and know
8007                    // that will limit to the correct security sandbox.
8008                    if (tr.effectiveUid != callingUid) {
8009                        continue;
8010                    }
8011                    Intent intent = tr.getBaseIntent();
8012                    if (intent == null ||
8013                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8014                        continue;
8015                    }
8016                    ActivityManager.RecentTaskInfo taskInfo =
8017                            createRecentTaskInfoFromTaskRecord(tr);
8018                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8019                    list.add(taskImpl);
8020                }
8021            } finally {
8022                Binder.restoreCallingIdentity(ident);
8023            }
8024            return list;
8025        }
8026    }
8027
8028    @Override
8029    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8030        final int callingUid = Binder.getCallingUid();
8031        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8032
8033        synchronized(this) {
8034            if (localLOGV) Slog.v(
8035                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8036
8037            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8038                    callingUid);
8039
8040            // TODO: Improve with MRU list from all ActivityStacks.
8041            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8042        }
8043
8044        return list;
8045    }
8046
8047    TaskRecord getMostRecentTask() {
8048        return mRecentTasks.get(0);
8049    }
8050
8051    /**
8052     * Creates a new RecentTaskInfo from a TaskRecord.
8053     */
8054    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8055        // Update the task description to reflect any changes in the task stack
8056        tr.updateTaskDescription();
8057
8058        // Compose the recent task info
8059        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8060        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8061        rti.persistentId = tr.taskId;
8062        rti.baseIntent = new Intent(tr.getBaseIntent());
8063        rti.origActivity = tr.origActivity;
8064        rti.description = tr.lastDescription;
8065        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8066        rti.userId = tr.userId;
8067        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8068        rti.firstActiveTime = tr.firstActiveTime;
8069        rti.lastActiveTime = tr.lastActiveTime;
8070        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8071        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8072        return rti;
8073    }
8074
8075    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8076        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8077                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8078        if (!allowed) {
8079            if (checkPermission(android.Manifest.permission.GET_TASKS,
8080                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8081                // Temporary compatibility: some existing apps on the system image may
8082                // still be requesting the old permission and not switched to the new
8083                // one; if so, we'll still allow them full access.  This means we need
8084                // to see if they are holding the old permission and are a system app.
8085                try {
8086                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8087                        allowed = true;
8088                        Slog.w(TAG, caller + ": caller " + callingUid
8089                                + " is using old GET_TASKS but privileged; allowing");
8090                    }
8091                } catch (RemoteException e) {
8092                }
8093            }
8094        }
8095        if (!allowed) {
8096            Slog.w(TAG, caller + ": caller " + callingUid
8097                    + " does not hold GET_TASKS; limiting output");
8098        }
8099        return allowed;
8100    }
8101
8102    @Override
8103    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8104        final int callingUid = Binder.getCallingUid();
8105        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8106                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8107
8108        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8109        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8110        synchronized (this) {
8111            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8112                    callingUid);
8113            final boolean detailed = checkCallingPermission(
8114                    android.Manifest.permission.GET_DETAILED_TASKS)
8115                    == PackageManager.PERMISSION_GRANTED;
8116
8117            final int N = mRecentTasks.size();
8118            ArrayList<ActivityManager.RecentTaskInfo> res
8119                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8120                            maxNum < N ? maxNum : N);
8121
8122            final Set<Integer> includedUsers;
8123            if (includeProfiles) {
8124                includedUsers = getProfileIdsLocked(userId);
8125            } else {
8126                includedUsers = new HashSet<Integer>();
8127            }
8128            includedUsers.add(Integer.valueOf(userId));
8129
8130            for (int i=0; i<N && maxNum > 0; i++) {
8131                TaskRecord tr = mRecentTasks.get(i);
8132                // Only add calling user or related users recent tasks
8133                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8134                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8135                    continue;
8136                }
8137
8138                // Return the entry if desired by the caller.  We always return
8139                // the first entry, because callers always expect this to be the
8140                // foreground app.  We may filter others if the caller has
8141                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8142                // we should exclude the entry.
8143
8144                if (i == 0
8145                        || withExcluded
8146                        || (tr.intent == null)
8147                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8148                                == 0)) {
8149                    if (!allowed) {
8150                        // If the caller doesn't have the GET_TASKS permission, then only
8151                        // allow them to see a small subset of tasks -- their own and home.
8152                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8153                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8154                            continue;
8155                        }
8156                    }
8157                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8158                        if (tr.stack != null && tr.stack.isHomeStack()) {
8159                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8160                            continue;
8161                        }
8162                    }
8163                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8164                        // Don't include auto remove tasks that are finished or finishing.
8165                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8166                                + tr);
8167                        continue;
8168                    }
8169                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8170                            && !tr.isAvailable) {
8171                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8172                        continue;
8173                    }
8174
8175                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8176                    if (!detailed) {
8177                        rti.baseIntent.replaceExtras((Bundle)null);
8178                    }
8179
8180                    res.add(rti);
8181                    maxNum--;
8182                }
8183            }
8184            return res;
8185        }
8186    }
8187
8188    private TaskRecord taskForIdLocked(int id) {
8189        final TaskRecord task = recentTaskForIdLocked(id);
8190        if (task != null) {
8191            return task;
8192        }
8193
8194        // Don't give up. Sometimes it just hasn't made it to recents yet.
8195        return mStackSupervisor.anyTaskForIdLocked(id);
8196    }
8197
8198    private TaskRecord recentTaskForIdLocked(int id) {
8199        final int N = mRecentTasks.size();
8200            for (int i=0; i<N; i++) {
8201                TaskRecord tr = mRecentTasks.get(i);
8202                if (tr.taskId == id) {
8203                    return tr;
8204                }
8205            }
8206            return null;
8207    }
8208
8209    @Override
8210    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8211        synchronized (this) {
8212            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8213                    "getTaskThumbnail()");
8214            TaskRecord tr = recentTaskForIdLocked(id);
8215            if (tr != null) {
8216                return tr.getTaskThumbnailLocked();
8217            }
8218        }
8219        return null;
8220    }
8221
8222    @Override
8223    public int addAppTask(IBinder activityToken, Intent intent,
8224            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8225        final int callingUid = Binder.getCallingUid();
8226        final long callingIdent = Binder.clearCallingIdentity();
8227
8228        try {
8229            synchronized (this) {
8230                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8231                if (r == null) {
8232                    throw new IllegalArgumentException("Activity does not exist; token="
8233                            + activityToken);
8234                }
8235                ComponentName comp = intent.getComponent();
8236                if (comp == null) {
8237                    throw new IllegalArgumentException("Intent " + intent
8238                            + " must specify explicit component");
8239                }
8240                if (thumbnail.getWidth() != mThumbnailWidth
8241                        || thumbnail.getHeight() != mThumbnailHeight) {
8242                    throw new IllegalArgumentException("Bad thumbnail size: got "
8243                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8244                            + mThumbnailWidth + "x" + mThumbnailHeight);
8245                }
8246                if (intent.getSelector() != null) {
8247                    intent.setSelector(null);
8248                }
8249                if (intent.getSourceBounds() != null) {
8250                    intent.setSourceBounds(null);
8251                }
8252                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8253                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8254                        // The caller has added this as an auto-remove task...  that makes no
8255                        // sense, so turn off auto-remove.
8256                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8257                    }
8258                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8259                    // Must be a new task.
8260                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8261                }
8262                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8263                    mLastAddedTaskActivity = null;
8264                }
8265                ActivityInfo ainfo = mLastAddedTaskActivity;
8266                if (ainfo == null) {
8267                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8268                            comp, 0, UserHandle.getUserId(callingUid));
8269                    if (ainfo.applicationInfo.uid != callingUid) {
8270                        throw new SecurityException(
8271                                "Can't add task for another application: target uid="
8272                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8273                    }
8274                }
8275
8276                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8277                        intent, description);
8278
8279                int trimIdx = trimRecentsForTask(task, false);
8280                if (trimIdx >= 0) {
8281                    // If this would have caused a trim, then we'll abort because that
8282                    // means it would be added at the end of the list but then just removed.
8283                    return -1;
8284                }
8285
8286                final int N = mRecentTasks.size();
8287                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8288                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8289                    tr.removedFromRecents(mTaskPersister);
8290                }
8291
8292                task.inRecents = true;
8293                mRecentTasks.add(task);
8294                r.task.stack.addTask(task, false, false);
8295
8296                task.setLastThumbnail(thumbnail);
8297                task.freeLastThumbnail();
8298
8299                return task.taskId;
8300            }
8301        } finally {
8302            Binder.restoreCallingIdentity(callingIdent);
8303        }
8304    }
8305
8306    @Override
8307    public Point getAppTaskThumbnailSize() {
8308        synchronized (this) {
8309            return new Point(mThumbnailWidth,  mThumbnailHeight);
8310        }
8311    }
8312
8313    @Override
8314    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8315        synchronized (this) {
8316            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8317            if (r != null) {
8318                r.setTaskDescription(td);
8319                r.task.updateTaskDescription();
8320            }
8321        }
8322    }
8323
8324    @Override
8325    public Bitmap getTaskDescriptionIcon(String filename) {
8326        if (!FileUtils.isValidExtFilename(filename)
8327                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8328            throw new IllegalArgumentException("Bad filename: " + filename);
8329        }
8330        return mTaskPersister.getTaskDescriptionIcon(filename);
8331    }
8332
8333    @Override
8334    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8335            throws RemoteException {
8336        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8337                opts.getCustomInPlaceResId() == 0) {
8338            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8339                    "with valid animation");
8340        }
8341        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8342        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8343                opts.getCustomInPlaceResId());
8344        mWindowManager.executeAppTransition();
8345    }
8346
8347    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8348        mRecentTasks.remove(tr);
8349        tr.removedFromRecents(mTaskPersister);
8350        ComponentName component = tr.getBaseIntent().getComponent();
8351        if (component == null) {
8352            Slog.w(TAG, "No component for base intent of task: " + tr);
8353            return;
8354        }
8355
8356        if (!killProcess) {
8357            return;
8358        }
8359
8360        // Determine if the process(es) for this task should be killed.
8361        final String pkg = component.getPackageName();
8362        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8363        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8364        for (int i = 0; i < pmap.size(); i++) {
8365
8366            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8367            for (int j = 0; j < uids.size(); j++) {
8368                ProcessRecord proc = uids.valueAt(j);
8369                if (proc.userId != tr.userId) {
8370                    // Don't kill process for a different user.
8371                    continue;
8372                }
8373                if (proc == mHomeProcess) {
8374                    // Don't kill the home process along with tasks from the same package.
8375                    continue;
8376                }
8377                if (!proc.pkgList.containsKey(pkg)) {
8378                    // Don't kill process that is not associated with this task.
8379                    continue;
8380                }
8381
8382                for (int k = 0; k < proc.activities.size(); k++) {
8383                    TaskRecord otherTask = proc.activities.get(k).task;
8384                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8385                        // Don't kill process(es) that has an activity in a different task that is
8386                        // also in recents.
8387                        return;
8388                    }
8389                }
8390
8391                // Add process to kill list.
8392                procsToKill.add(proc);
8393            }
8394        }
8395
8396        // Find any running services associated with this app and stop if needed.
8397        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8398
8399        // Kill the running processes.
8400        for (int i = 0; i < procsToKill.size(); i++) {
8401            ProcessRecord pr = procsToKill.get(i);
8402            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8403                pr.kill("remove task", true);
8404            } else {
8405                pr.waitingToKill = "remove task";
8406            }
8407        }
8408    }
8409
8410    /**
8411     * Removes the task with the specified task id.
8412     *
8413     * @param taskId Identifier of the task to be removed.
8414     * @param killProcess Kill any process associated with the task if possible.
8415     * @return Returns true if the given task was found and removed.
8416     */
8417    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8418        TaskRecord tr = taskForIdLocked(taskId);
8419        if (tr != null) {
8420            tr.removeTaskActivitiesLocked();
8421            cleanUpRemovedTaskLocked(tr, killProcess);
8422            if (tr.isPersistable) {
8423                notifyTaskPersisterLocked(null, true);
8424            }
8425            return true;
8426        }
8427        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8428        return false;
8429    }
8430
8431    @Override
8432    public boolean removeTask(int taskId) {
8433        synchronized (this) {
8434            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8435                    "removeTask()");
8436            long ident = Binder.clearCallingIdentity();
8437            try {
8438                return removeTaskByIdLocked(taskId, true);
8439            } finally {
8440                Binder.restoreCallingIdentity(ident);
8441            }
8442        }
8443    }
8444
8445    /**
8446     * TODO: Add mController hook
8447     */
8448    @Override
8449    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8450        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8451                "moveTaskToFront()");
8452
8453        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8454        synchronized(this) {
8455            moveTaskToFrontLocked(taskId, flags, options);
8456        }
8457    }
8458
8459    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8460        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8461                Binder.getCallingUid(), -1, -1, "Task to front")) {
8462            ActivityOptions.abort(options);
8463            return;
8464        }
8465        final long origId = Binder.clearCallingIdentity();
8466        try {
8467            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8468            if (task == null) {
8469                Slog.d(TAG, "Could not find task for id: "+ taskId);
8470                return;
8471            }
8472            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8473                mStackSupervisor.showLockTaskToast();
8474                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8475                return;
8476            }
8477            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8478            if (prev != null && prev.isRecentsActivity()) {
8479                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8480            }
8481            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8482        } finally {
8483            Binder.restoreCallingIdentity(origId);
8484        }
8485        ActivityOptions.abort(options);
8486    }
8487
8488    @Override
8489    public void moveTaskToBack(int taskId) {
8490        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8491                "moveTaskToBack()");
8492
8493        synchronized(this) {
8494            TaskRecord tr = taskForIdLocked(taskId);
8495            if (tr != null) {
8496                if (tr == mStackSupervisor.mLockTaskModeTask) {
8497                    mStackSupervisor.showLockTaskToast();
8498                    return;
8499                }
8500                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8501                ActivityStack stack = tr.stack;
8502                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8503                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8504                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8505                        return;
8506                    }
8507                }
8508                final long origId = Binder.clearCallingIdentity();
8509                try {
8510                    stack.moveTaskToBackLocked(taskId, null);
8511                } finally {
8512                    Binder.restoreCallingIdentity(origId);
8513                }
8514            }
8515        }
8516    }
8517
8518    /**
8519     * Moves an activity, and all of the other activities within the same task, to the bottom
8520     * of the history stack.  The activity's order within the task is unchanged.
8521     *
8522     * @param token A reference to the activity we wish to move
8523     * @param nonRoot If false then this only works if the activity is the root
8524     *                of a task; if true it will work for any activity in a task.
8525     * @return Returns true if the move completed, false if not.
8526     */
8527    @Override
8528    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8529        enforceNotIsolatedCaller("moveActivityTaskToBack");
8530        synchronized(this) {
8531            final long origId = Binder.clearCallingIdentity();
8532            try {
8533                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8534                if (taskId >= 0) {
8535                    if ((mStackSupervisor.mLockTaskModeTask != null)
8536                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8537                        mStackSupervisor.showLockTaskToast();
8538                        return false;
8539                    }
8540                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8541                }
8542            } finally {
8543                Binder.restoreCallingIdentity(origId);
8544            }
8545        }
8546        return false;
8547    }
8548
8549    @Override
8550    public void moveTaskBackwards(int task) {
8551        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8552                "moveTaskBackwards()");
8553
8554        synchronized(this) {
8555            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8556                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8557                return;
8558            }
8559            final long origId = Binder.clearCallingIdentity();
8560            moveTaskBackwardsLocked(task);
8561            Binder.restoreCallingIdentity(origId);
8562        }
8563    }
8564
8565    private final void moveTaskBackwardsLocked(int task) {
8566        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8567    }
8568
8569    @Override
8570    public IBinder getHomeActivityToken() throws RemoteException {
8571        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8572                "getHomeActivityToken()");
8573        synchronized (this) {
8574            return mStackSupervisor.getHomeActivityToken();
8575        }
8576    }
8577
8578    @Override
8579    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8580            IActivityContainerCallback callback) throws RemoteException {
8581        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8582                "createActivityContainer()");
8583        synchronized (this) {
8584            if (parentActivityToken == null) {
8585                throw new IllegalArgumentException("parent token must not be null");
8586            }
8587            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8588            if (r == null) {
8589                return null;
8590            }
8591            if (callback == null) {
8592                throw new IllegalArgumentException("callback must not be null");
8593            }
8594            return mStackSupervisor.createActivityContainer(r, callback);
8595        }
8596    }
8597
8598    @Override
8599    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8600        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8601                "deleteActivityContainer()");
8602        synchronized (this) {
8603            mStackSupervisor.deleteActivityContainer(container);
8604        }
8605    }
8606
8607    @Override
8608    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8609            throws RemoteException {
8610        synchronized (this) {
8611            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8612            if (stack != null) {
8613                return stack.mActivityContainer;
8614            }
8615            return null;
8616        }
8617    }
8618
8619    @Override
8620    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8621        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8622                "moveTaskToStack()");
8623        if (stackId == HOME_STACK_ID) {
8624            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8625                    new RuntimeException("here").fillInStackTrace());
8626        }
8627        synchronized (this) {
8628            long ident = Binder.clearCallingIdentity();
8629            try {
8630                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8631                        + stackId + " toTop=" + toTop);
8632                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8633            } finally {
8634                Binder.restoreCallingIdentity(ident);
8635            }
8636        }
8637    }
8638
8639    @Override
8640    public void resizeStack(int stackBoxId, Rect bounds) {
8641        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8642                "resizeStackBox()");
8643        long ident = Binder.clearCallingIdentity();
8644        try {
8645            mWindowManager.resizeStack(stackBoxId, bounds);
8646        } finally {
8647            Binder.restoreCallingIdentity(ident);
8648        }
8649    }
8650
8651    @Override
8652    public List<StackInfo> getAllStackInfos() {
8653        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8654                "getAllStackInfos()");
8655        long ident = Binder.clearCallingIdentity();
8656        try {
8657            synchronized (this) {
8658                return mStackSupervisor.getAllStackInfosLocked();
8659            }
8660        } finally {
8661            Binder.restoreCallingIdentity(ident);
8662        }
8663    }
8664
8665    @Override
8666    public StackInfo getStackInfo(int stackId) {
8667        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8668                "getStackInfo()");
8669        long ident = Binder.clearCallingIdentity();
8670        try {
8671            synchronized (this) {
8672                return mStackSupervisor.getStackInfoLocked(stackId);
8673            }
8674        } finally {
8675            Binder.restoreCallingIdentity(ident);
8676        }
8677    }
8678
8679    @Override
8680    public boolean isInHomeStack(int taskId) {
8681        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8682                "getStackInfo()");
8683        long ident = Binder.clearCallingIdentity();
8684        try {
8685            synchronized (this) {
8686                TaskRecord tr = taskForIdLocked(taskId);
8687                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8688            }
8689        } finally {
8690            Binder.restoreCallingIdentity(ident);
8691        }
8692    }
8693
8694    @Override
8695    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8696        synchronized(this) {
8697            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8698        }
8699    }
8700
8701    private boolean isLockTaskAuthorized(String pkg) {
8702        final DevicePolicyManager dpm = (DevicePolicyManager)
8703                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8704        try {
8705            int uid = mContext.getPackageManager().getPackageUid(pkg,
8706                    Binder.getCallingUserHandle().getIdentifier());
8707            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8708        } catch (NameNotFoundException e) {
8709            return false;
8710        }
8711    }
8712
8713    void startLockTaskMode(TaskRecord task) {
8714        final String pkg;
8715        synchronized (this) {
8716            pkg = task.intent.getComponent().getPackageName();
8717        }
8718        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8719        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8720            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8721                    StatusBarManagerInternal.class);
8722            if (statusBarManager != null) {
8723                statusBarManager.showScreenPinningRequest();
8724            }
8725            return;
8726        }
8727        long ident = Binder.clearCallingIdentity();
8728        try {
8729            synchronized (this) {
8730                // Since we lost lock on task, make sure it is still there.
8731                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8732                if (task != null) {
8733                    if (!isSystemInitiated
8734                            && ((mStackSupervisor.getFocusedStack() == null)
8735                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8736                        throw new IllegalArgumentException("Invalid task, not in foreground");
8737                    }
8738                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8739                }
8740            }
8741        } finally {
8742            Binder.restoreCallingIdentity(ident);
8743        }
8744    }
8745
8746    @Override
8747    public void startLockTaskMode(int taskId) {
8748        final TaskRecord task;
8749        long ident = Binder.clearCallingIdentity();
8750        try {
8751            synchronized (this) {
8752                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8753            }
8754        } finally {
8755            Binder.restoreCallingIdentity(ident);
8756        }
8757        if (task != null) {
8758            startLockTaskMode(task);
8759        }
8760    }
8761
8762    @Override
8763    public void startLockTaskMode(IBinder token) {
8764        final TaskRecord task;
8765        long ident = Binder.clearCallingIdentity();
8766        try {
8767            synchronized (this) {
8768                final ActivityRecord r = ActivityRecord.forToken(token);
8769                if (r == null) {
8770                    return;
8771                }
8772                task = r.task;
8773            }
8774        } finally {
8775            Binder.restoreCallingIdentity(ident);
8776        }
8777        if (task != null) {
8778            startLockTaskMode(task);
8779        }
8780    }
8781
8782    @Override
8783    public void startLockTaskModeOnCurrent() throws RemoteException {
8784        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8785                "startLockTaskModeOnCurrent");
8786        long ident = Binder.clearCallingIdentity();
8787        try {
8788            ActivityRecord r = null;
8789            synchronized (this) {
8790                r = mStackSupervisor.topRunningActivityLocked();
8791            }
8792            startLockTaskMode(r.task);
8793        } finally {
8794            Binder.restoreCallingIdentity(ident);
8795        }
8796    }
8797
8798    @Override
8799    public void stopLockTaskMode() {
8800        // Verify that the user matches the package of the intent for the TaskRecord
8801        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8802        // and stopLockTaskMode.
8803        final int callingUid = Binder.getCallingUid();
8804        if (callingUid != Process.SYSTEM_UID) {
8805            try {
8806                String pkg =
8807                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8808                int uid = mContext.getPackageManager().getPackageUid(pkg,
8809                        Binder.getCallingUserHandle().getIdentifier());
8810                if (uid != callingUid) {
8811                    throw new SecurityException("Invalid uid, expected " + uid);
8812                }
8813            } catch (NameNotFoundException e) {
8814                Log.d(TAG, "stopLockTaskMode " + e);
8815                return;
8816            }
8817        }
8818        long ident = Binder.clearCallingIdentity();
8819        try {
8820            Log.d(TAG, "stopLockTaskMode");
8821            // Stop lock task
8822            synchronized (this) {
8823                mStackSupervisor.setLockTaskModeLocked(null, false);
8824            }
8825        } finally {
8826            Binder.restoreCallingIdentity(ident);
8827        }
8828    }
8829
8830    @Override
8831    public void stopLockTaskModeOnCurrent() throws RemoteException {
8832        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8833                "stopLockTaskModeOnCurrent");
8834        long ident = Binder.clearCallingIdentity();
8835        try {
8836            stopLockTaskMode();
8837        } finally {
8838            Binder.restoreCallingIdentity(ident);
8839        }
8840    }
8841
8842    @Override
8843    public boolean isInLockTaskMode() {
8844        synchronized (this) {
8845            return mStackSupervisor.isInLockTaskMode();
8846        }
8847    }
8848
8849    // =========================================================
8850    // CONTENT PROVIDERS
8851    // =========================================================
8852
8853    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8854        List<ProviderInfo> providers = null;
8855        try {
8856            providers = AppGlobals.getPackageManager().
8857                queryContentProviders(app.processName, app.uid,
8858                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8859        } catch (RemoteException ex) {
8860        }
8861        if (DEBUG_MU)
8862            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8863        int userId = app.userId;
8864        if (providers != null) {
8865            int N = providers.size();
8866            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8867            for (int i=0; i<N; i++) {
8868                ProviderInfo cpi =
8869                    (ProviderInfo)providers.get(i);
8870                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8871                        cpi.name, cpi.flags);
8872                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8873                    // This is a singleton provider, but a user besides the
8874                    // default user is asking to initialize a process it runs
8875                    // in...  well, no, it doesn't actually run in this process,
8876                    // it runs in the process of the default user.  Get rid of it.
8877                    providers.remove(i);
8878                    N--;
8879                    i--;
8880                    continue;
8881                }
8882
8883                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8884                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8885                if (cpr == null) {
8886                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8887                    mProviderMap.putProviderByClass(comp, cpr);
8888                }
8889                if (DEBUG_MU)
8890                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8891                app.pubProviders.put(cpi.name, cpr);
8892                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8893                    // Don't add this if it is a platform component that is marked
8894                    // to run in multiple processes, because this is actually
8895                    // part of the framework so doesn't make sense to track as a
8896                    // separate apk in the process.
8897                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8898                            mProcessStats);
8899                }
8900                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8901            }
8902        }
8903        return providers;
8904    }
8905
8906    /**
8907     * Check if {@link ProcessRecord} has a possible chance at accessing the
8908     * given {@link ProviderInfo}. Final permission checking is always done
8909     * in {@link ContentProvider}.
8910     */
8911    private final String checkContentProviderPermissionLocked(
8912            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8913        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8914        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8915        boolean checkedGrants = false;
8916        if (checkUser) {
8917            // Looking for cross-user grants before enforcing the typical cross-users permissions
8918            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8919            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8920                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8921                    return null;
8922                }
8923                checkedGrants = true;
8924            }
8925            userId = handleIncomingUser(callingPid, callingUid, userId,
8926                    false, ALLOW_NON_FULL,
8927                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8928            if (userId != tmpTargetUserId) {
8929                // When we actually went to determine the final targer user ID, this ended
8930                // up different than our initial check for the authority.  This is because
8931                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8932                // SELF.  So we need to re-check the grants again.
8933                checkedGrants = false;
8934            }
8935        }
8936        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8937                cpi.applicationInfo.uid, cpi.exported)
8938                == PackageManager.PERMISSION_GRANTED) {
8939            return null;
8940        }
8941        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8942                cpi.applicationInfo.uid, cpi.exported)
8943                == PackageManager.PERMISSION_GRANTED) {
8944            return null;
8945        }
8946
8947        PathPermission[] pps = cpi.pathPermissions;
8948        if (pps != null) {
8949            int i = pps.length;
8950            while (i > 0) {
8951                i--;
8952                PathPermission pp = pps[i];
8953                String pprperm = pp.getReadPermission();
8954                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8955                        cpi.applicationInfo.uid, cpi.exported)
8956                        == PackageManager.PERMISSION_GRANTED) {
8957                    return null;
8958                }
8959                String ppwperm = pp.getWritePermission();
8960                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8961                        cpi.applicationInfo.uid, cpi.exported)
8962                        == PackageManager.PERMISSION_GRANTED) {
8963                    return null;
8964                }
8965            }
8966        }
8967        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8968            return null;
8969        }
8970
8971        String msg;
8972        if (!cpi.exported) {
8973            msg = "Permission Denial: opening provider " + cpi.name
8974                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8975                    + ", uid=" + callingUid + ") that is not exported from uid "
8976                    + cpi.applicationInfo.uid;
8977        } else {
8978            msg = "Permission Denial: opening provider " + cpi.name
8979                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8980                    + ", uid=" + callingUid + ") requires "
8981                    + cpi.readPermission + " or " + cpi.writePermission;
8982        }
8983        Slog.w(TAG, msg);
8984        return msg;
8985    }
8986
8987    /**
8988     * Returns if the ContentProvider has granted a uri to callingUid
8989     */
8990    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8991        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8992        if (perms != null) {
8993            for (int i=perms.size()-1; i>=0; i--) {
8994                GrantUri grantUri = perms.keyAt(i);
8995                if (grantUri.sourceUserId == userId || !checkUser) {
8996                    if (matchesProvider(grantUri.uri, cpi)) {
8997                        return true;
8998                    }
8999                }
9000            }
9001        }
9002        return false;
9003    }
9004
9005    /**
9006     * Returns true if the uri authority is one of the authorities specified in the provider.
9007     */
9008    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9009        String uriAuth = uri.getAuthority();
9010        String cpiAuth = cpi.authority;
9011        if (cpiAuth.indexOf(';') == -1) {
9012            return cpiAuth.equals(uriAuth);
9013        }
9014        String[] cpiAuths = cpiAuth.split(";");
9015        int length = cpiAuths.length;
9016        for (int i = 0; i < length; i++) {
9017            if (cpiAuths[i].equals(uriAuth)) return true;
9018        }
9019        return false;
9020    }
9021
9022    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9023            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9024        if (r != null) {
9025            for (int i=0; i<r.conProviders.size(); i++) {
9026                ContentProviderConnection conn = r.conProviders.get(i);
9027                if (conn.provider == cpr) {
9028                    if (DEBUG_PROVIDER) Slog.v(TAG,
9029                            "Adding provider requested by "
9030                            + r.processName + " from process "
9031                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9032                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9033                    if (stable) {
9034                        conn.stableCount++;
9035                        conn.numStableIncs++;
9036                    } else {
9037                        conn.unstableCount++;
9038                        conn.numUnstableIncs++;
9039                    }
9040                    return conn;
9041                }
9042            }
9043            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9044            if (stable) {
9045                conn.stableCount = 1;
9046                conn.numStableIncs = 1;
9047            } else {
9048                conn.unstableCount = 1;
9049                conn.numUnstableIncs = 1;
9050            }
9051            cpr.connections.add(conn);
9052            r.conProviders.add(conn);
9053            return conn;
9054        }
9055        cpr.addExternalProcessHandleLocked(externalProcessToken);
9056        return null;
9057    }
9058
9059    boolean decProviderCountLocked(ContentProviderConnection conn,
9060            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9061        if (conn != null) {
9062            cpr = conn.provider;
9063            if (DEBUG_PROVIDER) Slog.v(TAG,
9064                    "Removing provider requested by "
9065                    + conn.client.processName + " from process "
9066                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9067                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9068            if (stable) {
9069                conn.stableCount--;
9070            } else {
9071                conn.unstableCount--;
9072            }
9073            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9074                cpr.connections.remove(conn);
9075                conn.client.conProviders.remove(conn);
9076                return true;
9077            }
9078            return false;
9079        }
9080        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9081        return false;
9082    }
9083
9084    private void checkTime(long startTime, String where) {
9085        long now = SystemClock.elapsedRealtime();
9086        if ((now-startTime) > 1000) {
9087            // If we are taking more than a second, log about it.
9088            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9089        }
9090    }
9091
9092    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9093            String name, IBinder token, boolean stable, int userId) {
9094        ContentProviderRecord cpr;
9095        ContentProviderConnection conn = null;
9096        ProviderInfo cpi = null;
9097
9098        synchronized(this) {
9099            long startTime = SystemClock.elapsedRealtime();
9100
9101            ProcessRecord r = null;
9102            if (caller != null) {
9103                r = getRecordForAppLocked(caller);
9104                if (r == null) {
9105                    throw new SecurityException(
9106                            "Unable to find app for caller " + caller
9107                          + " (pid=" + Binder.getCallingPid()
9108                          + ") when getting content provider " + name);
9109                }
9110            }
9111
9112            boolean checkCrossUser = true;
9113
9114            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9115
9116            // First check if this content provider has been published...
9117            cpr = mProviderMap.getProviderByName(name, userId);
9118            // If that didn't work, check if it exists for user 0 and then
9119            // verify that it's a singleton provider before using it.
9120            if (cpr == null && userId != UserHandle.USER_OWNER) {
9121                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9122                if (cpr != null) {
9123                    cpi = cpr.info;
9124                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9125                            cpi.name, cpi.flags)
9126                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9127                        userId = UserHandle.USER_OWNER;
9128                        checkCrossUser = false;
9129                    } else {
9130                        cpr = null;
9131                        cpi = null;
9132                    }
9133                }
9134            }
9135
9136            boolean providerRunning = cpr != null;
9137            if (providerRunning) {
9138                cpi = cpr.info;
9139                String msg;
9140                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9141                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9142                        != null) {
9143                    throw new SecurityException(msg);
9144                }
9145                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9146
9147                if (r != null && cpr.canRunHere(r)) {
9148                    // This provider has been published or is in the process
9149                    // of being published...  but it is also allowed to run
9150                    // in the caller's process, so don't make a connection
9151                    // and just let the caller instantiate its own instance.
9152                    ContentProviderHolder holder = cpr.newHolder(null);
9153                    // don't give caller the provider object, it needs
9154                    // to make its own.
9155                    holder.provider = null;
9156                    return holder;
9157                }
9158
9159                final long origId = Binder.clearCallingIdentity();
9160
9161                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9162
9163                // In this case the provider instance already exists, so we can
9164                // return it right away.
9165                conn = incProviderCountLocked(r, cpr, token, stable);
9166                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9167                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9168                        // If this is a perceptible app accessing the provider,
9169                        // make sure to count it as being accessed and thus
9170                        // back up on the LRU list.  This is good because
9171                        // content providers are often expensive to start.
9172                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9173                        updateLruProcessLocked(cpr.proc, false, null);
9174                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9175                    }
9176                }
9177
9178                if (cpr.proc != null) {
9179                    if (false) {
9180                        if (cpr.name.flattenToShortString().equals(
9181                                "com.android.providers.calendar/.CalendarProvider2")) {
9182                            Slog.v(TAG, "****************** KILLING "
9183                                + cpr.name.flattenToShortString());
9184                            Process.killProcess(cpr.proc.pid);
9185                        }
9186                    }
9187                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9188                    boolean success = updateOomAdjLocked(cpr.proc);
9189                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9190                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9191                    // NOTE: there is still a race here where a signal could be
9192                    // pending on the process even though we managed to update its
9193                    // adj level.  Not sure what to do about this, but at least
9194                    // the race is now smaller.
9195                    if (!success) {
9196                        // Uh oh...  it looks like the provider's process
9197                        // has been killed on us.  We need to wait for a new
9198                        // process to be started, and make sure its death
9199                        // doesn't kill our process.
9200                        Slog.i(TAG,
9201                                "Existing provider " + cpr.name.flattenToShortString()
9202                                + " is crashing; detaching " + r);
9203                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9204                        checkTime(startTime, "getContentProviderImpl: before appDied");
9205                        appDiedLocked(cpr.proc);
9206                        checkTime(startTime, "getContentProviderImpl: after appDied");
9207                        if (!lastRef) {
9208                            // This wasn't the last ref our process had on
9209                            // the provider...  we have now been killed, bail.
9210                            return null;
9211                        }
9212                        providerRunning = false;
9213                        conn = null;
9214                    }
9215                }
9216
9217                Binder.restoreCallingIdentity(origId);
9218            }
9219
9220            boolean singleton;
9221            if (!providerRunning) {
9222                try {
9223                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9224                    cpi = AppGlobals.getPackageManager().
9225                        resolveContentProvider(name,
9226                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9227                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9228                } catch (RemoteException ex) {
9229                }
9230                if (cpi == null) {
9231                    return null;
9232                }
9233                // If the provider is a singleton AND
9234                // (it's a call within the same user || the provider is a
9235                // privileged app)
9236                // Then allow connecting to the singleton provider
9237                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9238                        cpi.name, cpi.flags)
9239                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9240                if (singleton) {
9241                    userId = UserHandle.USER_OWNER;
9242                }
9243                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9244                checkTime(startTime, "getContentProviderImpl: got app info for user");
9245
9246                String msg;
9247                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9248                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9249                        != null) {
9250                    throw new SecurityException(msg);
9251                }
9252                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9253
9254                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9255                        && !cpi.processName.equals("system")) {
9256                    // If this content provider does not run in the system
9257                    // process, and the system is not yet ready to run other
9258                    // processes, then fail fast instead of hanging.
9259                    throw new IllegalArgumentException(
9260                            "Attempt to launch content provider before system ready");
9261                }
9262
9263                // Make sure that the user who owns this provider is started.  If not,
9264                // we don't want to allow it to run.
9265                if (mStartedUsers.get(userId) == null) {
9266                    Slog.w(TAG, "Unable to launch app "
9267                            + cpi.applicationInfo.packageName + "/"
9268                            + cpi.applicationInfo.uid + " for provider "
9269                            + name + ": user " + userId + " is stopped");
9270                    return null;
9271                }
9272
9273                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9274                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9275                cpr = mProviderMap.getProviderByClass(comp, userId);
9276                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9277                final boolean firstClass = cpr == null;
9278                if (firstClass) {
9279                    final long ident = Binder.clearCallingIdentity();
9280                    try {
9281                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9282                        ApplicationInfo ai =
9283                            AppGlobals.getPackageManager().
9284                                getApplicationInfo(
9285                                        cpi.applicationInfo.packageName,
9286                                        STOCK_PM_FLAGS, userId);
9287                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9288                        if (ai == null) {
9289                            Slog.w(TAG, "No package info for content provider "
9290                                    + cpi.name);
9291                            return null;
9292                        }
9293                        ai = getAppInfoForUser(ai, userId);
9294                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9295                    } catch (RemoteException ex) {
9296                        // pm is in same process, this will never happen.
9297                    } finally {
9298                        Binder.restoreCallingIdentity(ident);
9299                    }
9300                }
9301
9302                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9303
9304                if (r != null && cpr.canRunHere(r)) {
9305                    // If this is a multiprocess provider, then just return its
9306                    // info and allow the caller to instantiate it.  Only do
9307                    // this if the provider is the same user as the caller's
9308                    // process, or can run as root (so can be in any process).
9309                    return cpr.newHolder(null);
9310                }
9311
9312                if (DEBUG_PROVIDER) {
9313                    RuntimeException e = new RuntimeException("here");
9314                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9315                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9316                }
9317
9318                // This is single process, and our app is now connecting to it.
9319                // See if we are already in the process of launching this
9320                // provider.
9321                final int N = mLaunchingProviders.size();
9322                int i;
9323                for (i=0; i<N; i++) {
9324                    if (mLaunchingProviders.get(i) == cpr) {
9325                        break;
9326                    }
9327                }
9328
9329                // If the provider is not already being launched, then get it
9330                // started.
9331                if (i >= N) {
9332                    final long origId = Binder.clearCallingIdentity();
9333
9334                    try {
9335                        // Content provider is now in use, its package can't be stopped.
9336                        try {
9337                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9338                            AppGlobals.getPackageManager().setPackageStoppedState(
9339                                    cpr.appInfo.packageName, false, userId);
9340                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9341                        } catch (RemoteException e) {
9342                        } catch (IllegalArgumentException e) {
9343                            Slog.w(TAG, "Failed trying to unstop package "
9344                                    + cpr.appInfo.packageName + ": " + e);
9345                        }
9346
9347                        // Use existing process if already started
9348                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9349                        ProcessRecord proc = getProcessRecordLocked(
9350                                cpi.processName, cpr.appInfo.uid, false);
9351                        if (proc != null && proc.thread != null) {
9352                            if (DEBUG_PROVIDER) {
9353                                Slog.d(TAG, "Installing in existing process " + proc);
9354                            }
9355                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9356                            proc.pubProviders.put(cpi.name, cpr);
9357                            try {
9358                                proc.thread.scheduleInstallProvider(cpi);
9359                            } catch (RemoteException e) {
9360                            }
9361                        } else {
9362                            checkTime(startTime, "getContentProviderImpl: before start process");
9363                            proc = startProcessLocked(cpi.processName,
9364                                    cpr.appInfo, false, 0, "content provider",
9365                                    new ComponentName(cpi.applicationInfo.packageName,
9366                                            cpi.name), false, false, false);
9367                            checkTime(startTime, "getContentProviderImpl: after start process");
9368                            if (proc == null) {
9369                                Slog.w(TAG, "Unable to launch app "
9370                                        + cpi.applicationInfo.packageName + "/"
9371                                        + cpi.applicationInfo.uid + " for provider "
9372                                        + name + ": process is bad");
9373                                return null;
9374                            }
9375                        }
9376                        cpr.launchingApp = proc;
9377                        mLaunchingProviders.add(cpr);
9378                    } finally {
9379                        Binder.restoreCallingIdentity(origId);
9380                    }
9381                }
9382
9383                checkTime(startTime, "getContentProviderImpl: updating data structures");
9384
9385                // Make sure the provider is published (the same provider class
9386                // may be published under multiple names).
9387                if (firstClass) {
9388                    mProviderMap.putProviderByClass(comp, cpr);
9389                }
9390
9391                mProviderMap.putProviderByName(name, cpr);
9392                conn = incProviderCountLocked(r, cpr, token, stable);
9393                if (conn != null) {
9394                    conn.waiting = true;
9395                }
9396            }
9397            checkTime(startTime, "getContentProviderImpl: done!");
9398        }
9399
9400        // Wait for the provider to be published...
9401        synchronized (cpr) {
9402            while (cpr.provider == null) {
9403                if (cpr.launchingApp == null) {
9404                    Slog.w(TAG, "Unable to launch app "
9405                            + cpi.applicationInfo.packageName + "/"
9406                            + cpi.applicationInfo.uid + " for provider "
9407                            + name + ": launching app became null");
9408                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9409                            UserHandle.getUserId(cpi.applicationInfo.uid),
9410                            cpi.applicationInfo.packageName,
9411                            cpi.applicationInfo.uid, name);
9412                    return null;
9413                }
9414                try {
9415                    if (DEBUG_MU) {
9416                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9417                                + cpr.launchingApp);
9418                    }
9419                    if (conn != null) {
9420                        conn.waiting = true;
9421                    }
9422                    cpr.wait();
9423                } catch (InterruptedException ex) {
9424                } finally {
9425                    if (conn != null) {
9426                        conn.waiting = false;
9427                    }
9428                }
9429            }
9430        }
9431        return cpr != null ? cpr.newHolder(conn) : null;
9432    }
9433
9434    @Override
9435    public final ContentProviderHolder getContentProvider(
9436            IApplicationThread caller, String name, int userId, boolean stable) {
9437        enforceNotIsolatedCaller("getContentProvider");
9438        if (caller == null) {
9439            String msg = "null IApplicationThread when getting content provider "
9440                    + name;
9441            Slog.w(TAG, msg);
9442            throw new SecurityException(msg);
9443        }
9444        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9445        // with cross-user grant.
9446        return getContentProviderImpl(caller, name, null, stable, userId);
9447    }
9448
9449    public ContentProviderHolder getContentProviderExternal(
9450            String name, int userId, IBinder token) {
9451        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9452            "Do not have permission in call getContentProviderExternal()");
9453        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9454                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9455        return getContentProviderExternalUnchecked(name, token, userId);
9456    }
9457
9458    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9459            IBinder token, int userId) {
9460        return getContentProviderImpl(null, name, token, true, userId);
9461    }
9462
9463    /**
9464     * Drop a content provider from a ProcessRecord's bookkeeping
9465     */
9466    public void removeContentProvider(IBinder connection, boolean stable) {
9467        enforceNotIsolatedCaller("removeContentProvider");
9468        long ident = Binder.clearCallingIdentity();
9469        try {
9470            synchronized (this) {
9471                ContentProviderConnection conn;
9472                try {
9473                    conn = (ContentProviderConnection)connection;
9474                } catch (ClassCastException e) {
9475                    String msg ="removeContentProvider: " + connection
9476                            + " not a ContentProviderConnection";
9477                    Slog.w(TAG, msg);
9478                    throw new IllegalArgumentException(msg);
9479                }
9480                if (conn == null) {
9481                    throw new NullPointerException("connection is null");
9482                }
9483                if (decProviderCountLocked(conn, null, null, stable)) {
9484                    updateOomAdjLocked();
9485                }
9486            }
9487        } finally {
9488            Binder.restoreCallingIdentity(ident);
9489        }
9490    }
9491
9492    public void removeContentProviderExternal(String name, IBinder token) {
9493        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9494            "Do not have permission in call removeContentProviderExternal()");
9495        int userId = UserHandle.getCallingUserId();
9496        long ident = Binder.clearCallingIdentity();
9497        try {
9498            removeContentProviderExternalUnchecked(name, token, userId);
9499        } finally {
9500            Binder.restoreCallingIdentity(ident);
9501        }
9502    }
9503
9504    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9505        synchronized (this) {
9506            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9507            if(cpr == null) {
9508                //remove from mProvidersByClass
9509                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9510                return;
9511            }
9512
9513            //update content provider record entry info
9514            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9515            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9516            if (localCpr.hasExternalProcessHandles()) {
9517                if (localCpr.removeExternalProcessHandleLocked(token)) {
9518                    updateOomAdjLocked();
9519                } else {
9520                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9521                            + " with no external reference for token: "
9522                            + token + ".");
9523                }
9524            } else {
9525                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9526                        + " with no external references.");
9527            }
9528        }
9529    }
9530
9531    public final void publishContentProviders(IApplicationThread caller,
9532            List<ContentProviderHolder> providers) {
9533        if (providers == null) {
9534            return;
9535        }
9536
9537        enforceNotIsolatedCaller("publishContentProviders");
9538        synchronized (this) {
9539            final ProcessRecord r = getRecordForAppLocked(caller);
9540            if (DEBUG_MU)
9541                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9542            if (r == null) {
9543                throw new SecurityException(
9544                        "Unable to find app for caller " + caller
9545                      + " (pid=" + Binder.getCallingPid()
9546                      + ") when publishing content providers");
9547            }
9548
9549            final long origId = Binder.clearCallingIdentity();
9550
9551            final int N = providers.size();
9552            for (int i=0; i<N; i++) {
9553                ContentProviderHolder src = providers.get(i);
9554                if (src == null || src.info == null || src.provider == null) {
9555                    continue;
9556                }
9557                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9558                if (DEBUG_MU)
9559                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9560                if (dst != null) {
9561                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9562                    mProviderMap.putProviderByClass(comp, dst);
9563                    String names[] = dst.info.authority.split(";");
9564                    for (int j = 0; j < names.length; j++) {
9565                        mProviderMap.putProviderByName(names[j], dst);
9566                    }
9567
9568                    int NL = mLaunchingProviders.size();
9569                    int j;
9570                    for (j=0; j<NL; j++) {
9571                        if (mLaunchingProviders.get(j) == dst) {
9572                            mLaunchingProviders.remove(j);
9573                            j--;
9574                            NL--;
9575                        }
9576                    }
9577                    synchronized (dst) {
9578                        dst.provider = src.provider;
9579                        dst.proc = r;
9580                        dst.notifyAll();
9581                    }
9582                    updateOomAdjLocked(r);
9583                }
9584            }
9585
9586            Binder.restoreCallingIdentity(origId);
9587        }
9588    }
9589
9590    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9591        ContentProviderConnection conn;
9592        try {
9593            conn = (ContentProviderConnection)connection;
9594        } catch (ClassCastException e) {
9595            String msg ="refContentProvider: " + connection
9596                    + " not a ContentProviderConnection";
9597            Slog.w(TAG, msg);
9598            throw new IllegalArgumentException(msg);
9599        }
9600        if (conn == null) {
9601            throw new NullPointerException("connection is null");
9602        }
9603
9604        synchronized (this) {
9605            if (stable > 0) {
9606                conn.numStableIncs += stable;
9607            }
9608            stable = conn.stableCount + stable;
9609            if (stable < 0) {
9610                throw new IllegalStateException("stableCount < 0: " + stable);
9611            }
9612
9613            if (unstable > 0) {
9614                conn.numUnstableIncs += unstable;
9615            }
9616            unstable = conn.unstableCount + unstable;
9617            if (unstable < 0) {
9618                throw new IllegalStateException("unstableCount < 0: " + unstable);
9619            }
9620
9621            if ((stable+unstable) <= 0) {
9622                throw new IllegalStateException("ref counts can't go to zero here: stable="
9623                        + stable + " unstable=" + unstable);
9624            }
9625            conn.stableCount = stable;
9626            conn.unstableCount = unstable;
9627            return !conn.dead;
9628        }
9629    }
9630
9631    public void unstableProviderDied(IBinder connection) {
9632        ContentProviderConnection conn;
9633        try {
9634            conn = (ContentProviderConnection)connection;
9635        } catch (ClassCastException e) {
9636            String msg ="refContentProvider: " + connection
9637                    + " not a ContentProviderConnection";
9638            Slog.w(TAG, msg);
9639            throw new IllegalArgumentException(msg);
9640        }
9641        if (conn == null) {
9642            throw new NullPointerException("connection is null");
9643        }
9644
9645        // Safely retrieve the content provider associated with the connection.
9646        IContentProvider provider;
9647        synchronized (this) {
9648            provider = conn.provider.provider;
9649        }
9650
9651        if (provider == null) {
9652            // Um, yeah, we're way ahead of you.
9653            return;
9654        }
9655
9656        // Make sure the caller is being honest with us.
9657        if (provider.asBinder().pingBinder()) {
9658            // Er, no, still looks good to us.
9659            synchronized (this) {
9660                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9661                        + " says " + conn + " died, but we don't agree");
9662                return;
9663            }
9664        }
9665
9666        // Well look at that!  It's dead!
9667        synchronized (this) {
9668            if (conn.provider.provider != provider) {
9669                // But something changed...  good enough.
9670                return;
9671            }
9672
9673            ProcessRecord proc = conn.provider.proc;
9674            if (proc == null || proc.thread == null) {
9675                // Seems like the process is already cleaned up.
9676                return;
9677            }
9678
9679            // As far as we're concerned, this is just like receiving a
9680            // death notification...  just a bit prematurely.
9681            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9682                    + ") early provider death");
9683            final long ident = Binder.clearCallingIdentity();
9684            try {
9685                appDiedLocked(proc);
9686            } finally {
9687                Binder.restoreCallingIdentity(ident);
9688            }
9689        }
9690    }
9691
9692    @Override
9693    public void appNotRespondingViaProvider(IBinder connection) {
9694        enforceCallingPermission(
9695                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9696
9697        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9698        if (conn == null) {
9699            Slog.w(TAG, "ContentProviderConnection is null");
9700            return;
9701        }
9702
9703        final ProcessRecord host = conn.provider.proc;
9704        if (host == null) {
9705            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9706            return;
9707        }
9708
9709        final long token = Binder.clearCallingIdentity();
9710        try {
9711            appNotResponding(host, null, null, false, "ContentProvider not responding");
9712        } finally {
9713            Binder.restoreCallingIdentity(token);
9714        }
9715    }
9716
9717    public final void installSystemProviders() {
9718        List<ProviderInfo> providers;
9719        synchronized (this) {
9720            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9721            providers = generateApplicationProvidersLocked(app);
9722            if (providers != null) {
9723                for (int i=providers.size()-1; i>=0; i--) {
9724                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9725                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9726                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9727                                + ": not system .apk");
9728                        providers.remove(i);
9729                    }
9730                }
9731            }
9732        }
9733        if (providers != null) {
9734            mSystemThread.installSystemProviders(providers);
9735        }
9736
9737        mCoreSettingsObserver = new CoreSettingsObserver(this);
9738
9739        //mUsageStatsService.monitorPackages();
9740    }
9741
9742    /**
9743     * Allows apps to retrieve the MIME type of a URI.
9744     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9745     * users, then it does not need permission to access the ContentProvider.
9746     * Either, it needs cross-user uri grants.
9747     *
9748     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9749     *
9750     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9751     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9752     */
9753    public String getProviderMimeType(Uri uri, int userId) {
9754        enforceNotIsolatedCaller("getProviderMimeType");
9755        final String name = uri.getAuthority();
9756        int callingUid = Binder.getCallingUid();
9757        int callingPid = Binder.getCallingPid();
9758        long ident = 0;
9759        boolean clearedIdentity = false;
9760        userId = unsafeConvertIncomingUser(userId);
9761        if (canClearIdentity(callingPid, callingUid, userId)) {
9762            clearedIdentity = true;
9763            ident = Binder.clearCallingIdentity();
9764        }
9765        ContentProviderHolder holder = null;
9766        try {
9767            holder = getContentProviderExternalUnchecked(name, null, userId);
9768            if (holder != null) {
9769                return holder.provider.getType(uri);
9770            }
9771        } catch (RemoteException e) {
9772            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9773            return null;
9774        } finally {
9775            // We need to clear the identity to call removeContentProviderExternalUnchecked
9776            if (!clearedIdentity) {
9777                ident = Binder.clearCallingIdentity();
9778            }
9779            try {
9780                if (holder != null) {
9781                    removeContentProviderExternalUnchecked(name, null, userId);
9782                }
9783            } finally {
9784                Binder.restoreCallingIdentity(ident);
9785            }
9786        }
9787
9788        return null;
9789    }
9790
9791    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9792        if (UserHandle.getUserId(callingUid) == userId) {
9793            return true;
9794        }
9795        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9796                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9797                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9798                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9799                return true;
9800        }
9801        return false;
9802    }
9803
9804    // =========================================================
9805    // GLOBAL MANAGEMENT
9806    // =========================================================
9807
9808    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9809            boolean isolated, int isolatedUid) {
9810        String proc = customProcess != null ? customProcess : info.processName;
9811        BatteryStatsImpl.Uid.Proc ps = null;
9812        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9813        int uid = info.uid;
9814        if (isolated) {
9815            if (isolatedUid == 0) {
9816                int userId = UserHandle.getUserId(uid);
9817                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9818                while (true) {
9819                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9820                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9821                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9822                    }
9823                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9824                    mNextIsolatedProcessUid++;
9825                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9826                        // No process for this uid, use it.
9827                        break;
9828                    }
9829                    stepsLeft--;
9830                    if (stepsLeft <= 0) {
9831                        return null;
9832                    }
9833                }
9834            } else {
9835                // Special case for startIsolatedProcess (internal only), where
9836                // the uid of the isolated process is specified by the caller.
9837                uid = isolatedUid;
9838            }
9839        }
9840        return new ProcessRecord(stats, info, proc, uid);
9841    }
9842
9843    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9844            String abiOverride) {
9845        ProcessRecord app;
9846        if (!isolated) {
9847            app = getProcessRecordLocked(info.processName, info.uid, true);
9848        } else {
9849            app = null;
9850        }
9851
9852        if (app == null) {
9853            app = newProcessRecordLocked(info, null, isolated, 0);
9854            mProcessNames.put(info.processName, app.uid, app);
9855            if (isolated) {
9856                mIsolatedProcesses.put(app.uid, app);
9857            }
9858            updateLruProcessLocked(app, false, null);
9859            updateOomAdjLocked();
9860        }
9861
9862        // This package really, really can not be stopped.
9863        try {
9864            AppGlobals.getPackageManager().setPackageStoppedState(
9865                    info.packageName, false, UserHandle.getUserId(app.uid));
9866        } catch (RemoteException e) {
9867        } catch (IllegalArgumentException e) {
9868            Slog.w(TAG, "Failed trying to unstop package "
9869                    + info.packageName + ": " + e);
9870        }
9871
9872        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9873                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9874            app.persistent = true;
9875            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9876        }
9877        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9878            mPersistentStartingProcesses.add(app);
9879            startProcessLocked(app, "added application", app.processName, abiOverride,
9880                    null /* entryPoint */, null /* entryPointArgs */);
9881        }
9882
9883        return app;
9884    }
9885
9886    public void unhandledBack() {
9887        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9888                "unhandledBack()");
9889
9890        synchronized(this) {
9891            final long origId = Binder.clearCallingIdentity();
9892            try {
9893                getFocusedStack().unhandledBackLocked();
9894            } finally {
9895                Binder.restoreCallingIdentity(origId);
9896            }
9897        }
9898    }
9899
9900    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9901        enforceNotIsolatedCaller("openContentUri");
9902        final int userId = UserHandle.getCallingUserId();
9903        String name = uri.getAuthority();
9904        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9905        ParcelFileDescriptor pfd = null;
9906        if (cph != null) {
9907            // We record the binder invoker's uid in thread-local storage before
9908            // going to the content provider to open the file.  Later, in the code
9909            // that handles all permissions checks, we look for this uid and use
9910            // that rather than the Activity Manager's own uid.  The effect is that
9911            // we do the check against the caller's permissions even though it looks
9912            // to the content provider like the Activity Manager itself is making
9913            // the request.
9914            sCallerIdentity.set(new Identity(
9915                    Binder.getCallingPid(), Binder.getCallingUid()));
9916            try {
9917                pfd = cph.provider.openFile(null, uri, "r", null);
9918            } catch (FileNotFoundException e) {
9919                // do nothing; pfd will be returned null
9920            } finally {
9921                // Ensure that whatever happens, we clean up the identity state
9922                sCallerIdentity.remove();
9923            }
9924
9925            // We've got the fd now, so we're done with the provider.
9926            removeContentProviderExternalUnchecked(name, null, userId);
9927        } else {
9928            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9929        }
9930        return pfd;
9931    }
9932
9933    // Actually is sleeping or shutting down or whatever else in the future
9934    // is an inactive state.
9935    public boolean isSleepingOrShuttingDown() {
9936        return isSleeping() || mShuttingDown;
9937    }
9938
9939    public boolean isSleeping() {
9940        return mSleeping;
9941    }
9942
9943    void goingToSleep() {
9944        synchronized(this) {
9945            mWentToSleep = true;
9946            goToSleepIfNeededLocked();
9947        }
9948    }
9949
9950    void finishRunningVoiceLocked() {
9951        if (mRunningVoice) {
9952            mRunningVoice = false;
9953            goToSleepIfNeededLocked();
9954        }
9955    }
9956
9957    void goToSleepIfNeededLocked() {
9958        if (mWentToSleep && !mRunningVoice) {
9959            if (!mSleeping) {
9960                mSleeping = true;
9961                mStackSupervisor.goingToSleepLocked();
9962
9963                // Initialize the wake times of all processes.
9964                checkExcessivePowerUsageLocked(false);
9965                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9966                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9967                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9968            }
9969        }
9970    }
9971
9972    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9973        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9974            // Never persist the home stack.
9975            return;
9976        }
9977        mTaskPersister.wakeup(task, flush);
9978    }
9979
9980    @Override
9981    public boolean shutdown(int timeout) {
9982        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9983                != PackageManager.PERMISSION_GRANTED) {
9984            throw new SecurityException("Requires permission "
9985                    + android.Manifest.permission.SHUTDOWN);
9986        }
9987
9988        boolean timedout = false;
9989
9990        synchronized(this) {
9991            mShuttingDown = true;
9992            updateEventDispatchingLocked();
9993            timedout = mStackSupervisor.shutdownLocked(timeout);
9994        }
9995
9996        mAppOpsService.shutdown();
9997        if (mUsageStatsService != null) {
9998            mUsageStatsService.prepareShutdown();
9999        }
10000        mBatteryStatsService.shutdown();
10001        synchronized (this) {
10002            mProcessStats.shutdownLocked();
10003        }
10004        notifyTaskPersisterLocked(null, true);
10005
10006        return timedout;
10007    }
10008
10009    public final void activitySlept(IBinder token) {
10010        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10011
10012        final long origId = Binder.clearCallingIdentity();
10013
10014        synchronized (this) {
10015            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10016            if (r != null) {
10017                mStackSupervisor.activitySleptLocked(r);
10018            }
10019        }
10020
10021        Binder.restoreCallingIdentity(origId);
10022    }
10023
10024    private String lockScreenShownToString() {
10025        switch (mLockScreenShown) {
10026            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10027            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10028            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10029            default: return "Unknown=" + mLockScreenShown;
10030        }
10031    }
10032
10033    void logLockScreen(String msg) {
10034        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10035                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10036                mWentToSleep + " mSleeping=" + mSleeping);
10037    }
10038
10039    void comeOutOfSleepIfNeededLocked() {
10040        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10041            if (mSleeping) {
10042                mSleeping = false;
10043                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10044            }
10045        }
10046    }
10047
10048    void wakingUp() {
10049        synchronized(this) {
10050            mWentToSleep = false;
10051            comeOutOfSleepIfNeededLocked();
10052        }
10053    }
10054
10055    void startRunningVoiceLocked() {
10056        if (!mRunningVoice) {
10057            mRunningVoice = true;
10058            comeOutOfSleepIfNeededLocked();
10059        }
10060    }
10061
10062    private void updateEventDispatchingLocked() {
10063        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10064    }
10065
10066    public void setLockScreenShown(boolean shown) {
10067        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10068                != PackageManager.PERMISSION_GRANTED) {
10069            throw new SecurityException("Requires permission "
10070                    + android.Manifest.permission.DEVICE_POWER);
10071        }
10072
10073        synchronized(this) {
10074            long ident = Binder.clearCallingIdentity();
10075            try {
10076                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10077                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10078                comeOutOfSleepIfNeededLocked();
10079            } finally {
10080                Binder.restoreCallingIdentity(ident);
10081            }
10082        }
10083    }
10084
10085    @Override
10086    public void stopAppSwitches() {
10087        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10088                != PackageManager.PERMISSION_GRANTED) {
10089            throw new SecurityException("Requires permission "
10090                    + android.Manifest.permission.STOP_APP_SWITCHES);
10091        }
10092
10093        synchronized(this) {
10094            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10095                    + APP_SWITCH_DELAY_TIME;
10096            mDidAppSwitch = false;
10097            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10098            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10099            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10100        }
10101    }
10102
10103    public void resumeAppSwitches() {
10104        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10105                != PackageManager.PERMISSION_GRANTED) {
10106            throw new SecurityException("Requires permission "
10107                    + android.Manifest.permission.STOP_APP_SWITCHES);
10108        }
10109
10110        synchronized(this) {
10111            // Note that we don't execute any pending app switches... we will
10112            // let those wait until either the timeout, or the next start
10113            // activity request.
10114            mAppSwitchesAllowedTime = 0;
10115        }
10116    }
10117
10118    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10119            int callingPid, int callingUid, String name) {
10120        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10121            return true;
10122        }
10123
10124        int perm = checkComponentPermission(
10125                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10126                sourceUid, -1, true);
10127        if (perm == PackageManager.PERMISSION_GRANTED) {
10128            return true;
10129        }
10130
10131        // If the actual IPC caller is different from the logical source, then
10132        // also see if they are allowed to control app switches.
10133        if (callingUid != -1 && callingUid != sourceUid) {
10134            perm = checkComponentPermission(
10135                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10136                    callingUid, -1, true);
10137            if (perm == PackageManager.PERMISSION_GRANTED) {
10138                return true;
10139            }
10140        }
10141
10142        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10143        return false;
10144    }
10145
10146    public void setDebugApp(String packageName, boolean waitForDebugger,
10147            boolean persistent) {
10148        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10149                "setDebugApp()");
10150
10151        long ident = Binder.clearCallingIdentity();
10152        try {
10153            // Note that this is not really thread safe if there are multiple
10154            // callers into it at the same time, but that's not a situation we
10155            // care about.
10156            if (persistent) {
10157                final ContentResolver resolver = mContext.getContentResolver();
10158                Settings.Global.putString(
10159                    resolver, Settings.Global.DEBUG_APP,
10160                    packageName);
10161                Settings.Global.putInt(
10162                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10163                    waitForDebugger ? 1 : 0);
10164            }
10165
10166            synchronized (this) {
10167                if (!persistent) {
10168                    mOrigDebugApp = mDebugApp;
10169                    mOrigWaitForDebugger = mWaitForDebugger;
10170                }
10171                mDebugApp = packageName;
10172                mWaitForDebugger = waitForDebugger;
10173                mDebugTransient = !persistent;
10174                if (packageName != null) {
10175                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10176                            false, UserHandle.USER_ALL, "set debug app");
10177                }
10178            }
10179        } finally {
10180            Binder.restoreCallingIdentity(ident);
10181        }
10182    }
10183
10184    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10185        synchronized (this) {
10186            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10187            if (!isDebuggable) {
10188                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10189                    throw new SecurityException("Process not debuggable: " + app.packageName);
10190                }
10191            }
10192
10193            mOpenGlTraceApp = processName;
10194        }
10195    }
10196
10197    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10198        synchronized (this) {
10199            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10200            if (!isDebuggable) {
10201                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10202                    throw new SecurityException("Process not debuggable: " + app.packageName);
10203                }
10204            }
10205            mProfileApp = processName;
10206            mProfileFile = profilerInfo.profileFile;
10207            if (mProfileFd != null) {
10208                try {
10209                    mProfileFd.close();
10210                } catch (IOException e) {
10211                }
10212                mProfileFd = null;
10213            }
10214            mProfileFd = profilerInfo.profileFd;
10215            mSamplingInterval = profilerInfo.samplingInterval;
10216            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10217            mProfileType = 0;
10218        }
10219    }
10220
10221    @Override
10222    public void setAlwaysFinish(boolean enabled) {
10223        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10224                "setAlwaysFinish()");
10225
10226        Settings.Global.putInt(
10227                mContext.getContentResolver(),
10228                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10229
10230        synchronized (this) {
10231            mAlwaysFinishActivities = enabled;
10232        }
10233    }
10234
10235    @Override
10236    public void setActivityController(IActivityController controller) {
10237        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10238                "setActivityController()");
10239        synchronized (this) {
10240            mController = controller;
10241            Watchdog.getInstance().setActivityController(controller);
10242        }
10243    }
10244
10245    @Override
10246    public void setUserIsMonkey(boolean userIsMonkey) {
10247        synchronized (this) {
10248            synchronized (mPidsSelfLocked) {
10249                final int callingPid = Binder.getCallingPid();
10250                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10251                if (precessRecord == null) {
10252                    throw new SecurityException("Unknown process: " + callingPid);
10253                }
10254                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10255                    throw new SecurityException("Only an instrumentation process "
10256                            + "with a UiAutomation can call setUserIsMonkey");
10257                }
10258            }
10259            mUserIsMonkey = userIsMonkey;
10260        }
10261    }
10262
10263    @Override
10264    public boolean isUserAMonkey() {
10265        synchronized (this) {
10266            // If there is a controller also implies the user is a monkey.
10267            return (mUserIsMonkey || mController != null);
10268        }
10269    }
10270
10271    public void requestBugReport() {
10272        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10273        SystemProperties.set("ctl.start", "bugreport");
10274    }
10275
10276    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10277        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10278    }
10279
10280    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10281        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10282            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10283        }
10284        return KEY_DISPATCHING_TIMEOUT;
10285    }
10286
10287    @Override
10288    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10289        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10290                != PackageManager.PERMISSION_GRANTED) {
10291            throw new SecurityException("Requires permission "
10292                    + android.Manifest.permission.FILTER_EVENTS);
10293        }
10294        ProcessRecord proc;
10295        long timeout;
10296        synchronized (this) {
10297            synchronized (mPidsSelfLocked) {
10298                proc = mPidsSelfLocked.get(pid);
10299            }
10300            timeout = getInputDispatchingTimeoutLocked(proc);
10301        }
10302
10303        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10304            return -1;
10305        }
10306
10307        return timeout;
10308    }
10309
10310    /**
10311     * Handle input dispatching timeouts.
10312     * Returns whether input dispatching should be aborted or not.
10313     */
10314    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10315            final ActivityRecord activity, final ActivityRecord parent,
10316            final boolean aboveSystem, String reason) {
10317        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10318                != PackageManager.PERMISSION_GRANTED) {
10319            throw new SecurityException("Requires permission "
10320                    + android.Manifest.permission.FILTER_EVENTS);
10321        }
10322
10323        final String annotation;
10324        if (reason == null) {
10325            annotation = "Input dispatching timed out";
10326        } else {
10327            annotation = "Input dispatching timed out (" + reason + ")";
10328        }
10329
10330        if (proc != null) {
10331            synchronized (this) {
10332                if (proc.debugging) {
10333                    return false;
10334                }
10335
10336                if (mDidDexOpt) {
10337                    // Give more time since we were dexopting.
10338                    mDidDexOpt = false;
10339                    return false;
10340                }
10341
10342                if (proc.instrumentationClass != null) {
10343                    Bundle info = new Bundle();
10344                    info.putString("shortMsg", "keyDispatchingTimedOut");
10345                    info.putString("longMsg", annotation);
10346                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10347                    return true;
10348                }
10349            }
10350            mHandler.post(new Runnable() {
10351                @Override
10352                public void run() {
10353                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10354                }
10355            });
10356        }
10357
10358        return true;
10359    }
10360
10361    public Bundle getAssistContextExtras(int requestType) {
10362        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10363                UserHandle.getCallingUserId());
10364        if (pae == null) {
10365            return null;
10366        }
10367        synchronized (pae) {
10368            while (!pae.haveResult) {
10369                try {
10370                    pae.wait();
10371                } catch (InterruptedException e) {
10372                }
10373            }
10374            if (pae.result != null) {
10375                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10376            }
10377        }
10378        synchronized (this) {
10379            mPendingAssistExtras.remove(pae);
10380            mHandler.removeCallbacks(pae);
10381        }
10382        return pae.extras;
10383    }
10384
10385    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10386            int userHandle) {
10387        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10388                "getAssistContextExtras()");
10389        PendingAssistExtras pae;
10390        Bundle extras = new Bundle();
10391        synchronized (this) {
10392            ActivityRecord activity = getFocusedStack().mResumedActivity;
10393            if (activity == null) {
10394                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10395                return null;
10396            }
10397            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10398            if (activity.app == null || activity.app.thread == null) {
10399                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10400                return null;
10401            }
10402            if (activity.app.pid == Binder.getCallingPid()) {
10403                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10404                return null;
10405            }
10406            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10407            try {
10408                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10409                        requestType);
10410                mPendingAssistExtras.add(pae);
10411                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10412            } catch (RemoteException e) {
10413                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10414                return null;
10415            }
10416            return pae;
10417        }
10418    }
10419
10420    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10421        PendingAssistExtras pae = (PendingAssistExtras)token;
10422        synchronized (pae) {
10423            pae.result = extras;
10424            pae.haveResult = true;
10425            pae.notifyAll();
10426            if (pae.intent == null) {
10427                // Caller is just waiting for the result.
10428                return;
10429            }
10430        }
10431
10432        // We are now ready to launch the assist activity.
10433        synchronized (this) {
10434            boolean exists = mPendingAssistExtras.remove(pae);
10435            mHandler.removeCallbacks(pae);
10436            if (!exists) {
10437                // Timed out.
10438                return;
10439            }
10440        }
10441        pae.intent.replaceExtras(extras);
10442        if (pae.hint != null) {
10443            pae.intent.putExtra(pae.hint, true);
10444        }
10445        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10446                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10447                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10448        closeSystemDialogs("assist");
10449        try {
10450            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10451        } catch (ActivityNotFoundException e) {
10452            Slog.w(TAG, "No activity to handle assist action.", e);
10453        }
10454    }
10455
10456    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10457        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10458    }
10459
10460    public void registerProcessObserver(IProcessObserver observer) {
10461        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10462                "registerProcessObserver()");
10463        synchronized (this) {
10464            mProcessObservers.register(observer);
10465        }
10466    }
10467
10468    @Override
10469    public void unregisterProcessObserver(IProcessObserver observer) {
10470        synchronized (this) {
10471            mProcessObservers.unregister(observer);
10472        }
10473    }
10474
10475    @Override
10476    public boolean convertFromTranslucent(IBinder token) {
10477        final long origId = Binder.clearCallingIdentity();
10478        try {
10479            synchronized (this) {
10480                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10481                if (r == null) {
10482                    return false;
10483                }
10484                final boolean translucentChanged = r.changeWindowTranslucency(true);
10485                if (translucentChanged) {
10486                    r.task.stack.releaseBackgroundResources();
10487                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10488                }
10489                mWindowManager.setAppFullscreen(token, true);
10490                return translucentChanged;
10491            }
10492        } finally {
10493            Binder.restoreCallingIdentity(origId);
10494        }
10495    }
10496
10497    @Override
10498    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10499        final long origId = Binder.clearCallingIdentity();
10500        try {
10501            synchronized (this) {
10502                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10503                if (r == null) {
10504                    return false;
10505                }
10506                int index = r.task.mActivities.lastIndexOf(r);
10507                if (index > 0) {
10508                    ActivityRecord under = r.task.mActivities.get(index - 1);
10509                    under.returningOptions = options;
10510                }
10511                final boolean translucentChanged = r.changeWindowTranslucency(false);
10512                if (translucentChanged) {
10513                    r.task.stack.convertToTranslucent(r);
10514                }
10515                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10516                mWindowManager.setAppFullscreen(token, false);
10517                return translucentChanged;
10518            }
10519        } finally {
10520            Binder.restoreCallingIdentity(origId);
10521        }
10522    }
10523
10524    @Override
10525    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10526        final long origId = Binder.clearCallingIdentity();
10527        try {
10528            synchronized (this) {
10529                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10530                if (r != null) {
10531                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10532                }
10533            }
10534            return false;
10535        } finally {
10536            Binder.restoreCallingIdentity(origId);
10537        }
10538    }
10539
10540    @Override
10541    public boolean isBackgroundVisibleBehind(IBinder token) {
10542        final long origId = Binder.clearCallingIdentity();
10543        try {
10544            synchronized (this) {
10545                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10546                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10547                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10548                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10549                return visible;
10550            }
10551        } finally {
10552            Binder.restoreCallingIdentity(origId);
10553        }
10554    }
10555
10556    @Override
10557    public ActivityOptions getActivityOptions(IBinder token) {
10558        final long origId = Binder.clearCallingIdentity();
10559        try {
10560            synchronized (this) {
10561                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10562                if (r != null) {
10563                    final ActivityOptions activityOptions = r.pendingOptions;
10564                    r.pendingOptions = null;
10565                    return activityOptions;
10566                }
10567                return null;
10568            }
10569        } finally {
10570            Binder.restoreCallingIdentity(origId);
10571        }
10572    }
10573
10574    @Override
10575    public void setImmersive(IBinder token, boolean immersive) {
10576        synchronized(this) {
10577            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10578            if (r == null) {
10579                throw new IllegalArgumentException();
10580            }
10581            r.immersive = immersive;
10582
10583            // update associated state if we're frontmost
10584            if (r == mFocusedActivity) {
10585                if (DEBUG_IMMERSIVE) {
10586                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10587                }
10588                applyUpdateLockStateLocked(r);
10589            }
10590        }
10591    }
10592
10593    @Override
10594    public boolean isImmersive(IBinder token) {
10595        synchronized (this) {
10596            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10597            if (r == null) {
10598                throw new IllegalArgumentException();
10599            }
10600            return r.immersive;
10601        }
10602    }
10603
10604    public boolean isTopActivityImmersive() {
10605        enforceNotIsolatedCaller("startActivity");
10606        synchronized (this) {
10607            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10608            return (r != null) ? r.immersive : false;
10609        }
10610    }
10611
10612    @Override
10613    public boolean isTopOfTask(IBinder token) {
10614        synchronized (this) {
10615            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10616            if (r == null) {
10617                throw new IllegalArgumentException();
10618            }
10619            return r.task.getTopActivity() == r;
10620        }
10621    }
10622
10623    public final void enterSafeMode() {
10624        synchronized(this) {
10625            // It only makes sense to do this before the system is ready
10626            // and started launching other packages.
10627            if (!mSystemReady) {
10628                try {
10629                    AppGlobals.getPackageManager().enterSafeMode();
10630                } catch (RemoteException e) {
10631                }
10632            }
10633
10634            mSafeMode = true;
10635        }
10636    }
10637
10638    public final void showSafeModeOverlay() {
10639        View v = LayoutInflater.from(mContext).inflate(
10640                com.android.internal.R.layout.safe_mode, null);
10641        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10642        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10643        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10644        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10645        lp.gravity = Gravity.BOTTOM | Gravity.START;
10646        lp.format = v.getBackground().getOpacity();
10647        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10648                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10649        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10650        ((WindowManager)mContext.getSystemService(
10651                Context.WINDOW_SERVICE)).addView(v, lp);
10652    }
10653
10654    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10655        if (!(sender instanceof PendingIntentRecord)) {
10656            return;
10657        }
10658        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10659        synchronized (stats) {
10660            if (mBatteryStatsService.isOnBattery()) {
10661                mBatteryStatsService.enforceCallingPermission();
10662                PendingIntentRecord rec = (PendingIntentRecord)sender;
10663                int MY_UID = Binder.getCallingUid();
10664                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10665                BatteryStatsImpl.Uid.Pkg pkg =
10666                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10667                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10668                pkg.incWakeupsLocked();
10669            }
10670        }
10671    }
10672
10673    public boolean killPids(int[] pids, String pReason, boolean secure) {
10674        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10675            throw new SecurityException("killPids only available to the system");
10676        }
10677        String reason = (pReason == null) ? "Unknown" : pReason;
10678        // XXX Note: don't acquire main activity lock here, because the window
10679        // manager calls in with its locks held.
10680
10681        boolean killed = false;
10682        synchronized (mPidsSelfLocked) {
10683            int[] types = new int[pids.length];
10684            int worstType = 0;
10685            for (int i=0; i<pids.length; i++) {
10686                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10687                if (proc != null) {
10688                    int type = proc.setAdj;
10689                    types[i] = type;
10690                    if (type > worstType) {
10691                        worstType = type;
10692                    }
10693                }
10694            }
10695
10696            // If the worst oom_adj is somewhere in the cached proc LRU range,
10697            // then constrain it so we will kill all cached procs.
10698            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10699                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10700                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10701            }
10702
10703            // If this is not a secure call, don't let it kill processes that
10704            // are important.
10705            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10706                worstType = ProcessList.SERVICE_ADJ;
10707            }
10708
10709            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10710            for (int i=0; i<pids.length; i++) {
10711                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10712                if (proc == null) {
10713                    continue;
10714                }
10715                int adj = proc.setAdj;
10716                if (adj >= worstType && !proc.killedByAm) {
10717                    proc.kill(reason, true);
10718                    killed = true;
10719                }
10720            }
10721        }
10722        return killed;
10723    }
10724
10725    @Override
10726    public void killUid(int uid, String reason) {
10727        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10728            throw new SecurityException("killUid only available to the system");
10729        }
10730        synchronized (this) {
10731            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10732                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10733                    reason != null ? reason : "kill uid");
10734        }
10735    }
10736
10737    @Override
10738    public boolean killProcessesBelowForeground(String reason) {
10739        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10740            throw new SecurityException("killProcessesBelowForeground() only available to system");
10741        }
10742
10743        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10744    }
10745
10746    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10747        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10748            throw new SecurityException("killProcessesBelowAdj() only available to system");
10749        }
10750
10751        boolean killed = false;
10752        synchronized (mPidsSelfLocked) {
10753            final int size = mPidsSelfLocked.size();
10754            for (int i = 0; i < size; i++) {
10755                final int pid = mPidsSelfLocked.keyAt(i);
10756                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10757                if (proc == null) continue;
10758
10759                final int adj = proc.setAdj;
10760                if (adj > belowAdj && !proc.killedByAm) {
10761                    proc.kill(reason, true);
10762                    killed = true;
10763                }
10764            }
10765        }
10766        return killed;
10767    }
10768
10769    @Override
10770    public void hang(final IBinder who, boolean allowRestart) {
10771        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10772                != PackageManager.PERMISSION_GRANTED) {
10773            throw new SecurityException("Requires permission "
10774                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10775        }
10776
10777        final IBinder.DeathRecipient death = new DeathRecipient() {
10778            @Override
10779            public void binderDied() {
10780                synchronized (this) {
10781                    notifyAll();
10782                }
10783            }
10784        };
10785
10786        try {
10787            who.linkToDeath(death, 0);
10788        } catch (RemoteException e) {
10789            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10790            return;
10791        }
10792
10793        synchronized (this) {
10794            Watchdog.getInstance().setAllowRestart(allowRestart);
10795            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10796            synchronized (death) {
10797                while (who.isBinderAlive()) {
10798                    try {
10799                        death.wait();
10800                    } catch (InterruptedException e) {
10801                    }
10802                }
10803            }
10804            Watchdog.getInstance().setAllowRestart(true);
10805        }
10806    }
10807
10808    @Override
10809    public void restart() {
10810        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10811                != PackageManager.PERMISSION_GRANTED) {
10812            throw new SecurityException("Requires permission "
10813                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10814        }
10815
10816        Log.i(TAG, "Sending shutdown broadcast...");
10817
10818        BroadcastReceiver br = new BroadcastReceiver() {
10819            @Override public void onReceive(Context context, Intent intent) {
10820                // Now the broadcast is done, finish up the low-level shutdown.
10821                Log.i(TAG, "Shutting down activity manager...");
10822                shutdown(10000);
10823                Log.i(TAG, "Shutdown complete, restarting!");
10824                Process.killProcess(Process.myPid());
10825                System.exit(10);
10826            }
10827        };
10828
10829        // First send the high-level shut down broadcast.
10830        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10831        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10832        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10833        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10834        mContext.sendOrderedBroadcastAsUser(intent,
10835                UserHandle.ALL, null, br, mHandler, 0, null, null);
10836        */
10837        br.onReceive(mContext, intent);
10838    }
10839
10840    private long getLowRamTimeSinceIdle(long now) {
10841        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10842    }
10843
10844    @Override
10845    public void performIdleMaintenance() {
10846        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10847                != PackageManager.PERMISSION_GRANTED) {
10848            throw new SecurityException("Requires permission "
10849                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10850        }
10851
10852        synchronized (this) {
10853            final long now = SystemClock.uptimeMillis();
10854            final long timeSinceLastIdle = now - mLastIdleTime;
10855            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10856            mLastIdleTime = now;
10857            mLowRamTimeSinceLastIdle = 0;
10858            if (mLowRamStartTime != 0) {
10859                mLowRamStartTime = now;
10860            }
10861
10862            StringBuilder sb = new StringBuilder(128);
10863            sb.append("Idle maintenance over ");
10864            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10865            sb.append(" low RAM for ");
10866            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10867            Slog.i(TAG, sb.toString());
10868
10869            // If at least 1/3 of our time since the last idle period has been spent
10870            // with RAM low, then we want to kill processes.
10871            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10872
10873            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10874                ProcessRecord proc = mLruProcesses.get(i);
10875                if (proc.notCachedSinceIdle) {
10876                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10877                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10878                        if (doKilling && proc.initialIdlePss != 0
10879                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10880                            proc.kill("idle maint (pss " + proc.lastPss
10881                                    + " from " + proc.initialIdlePss + ")", true);
10882                        }
10883                    }
10884                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10885                    proc.notCachedSinceIdle = true;
10886                    proc.initialIdlePss = 0;
10887                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10888                            isSleeping(), now);
10889                }
10890            }
10891
10892            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10893            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10894        }
10895    }
10896
10897    private void retrieveSettings() {
10898        final ContentResolver resolver = mContext.getContentResolver();
10899        String debugApp = Settings.Global.getString(
10900            resolver, Settings.Global.DEBUG_APP);
10901        boolean waitForDebugger = Settings.Global.getInt(
10902            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10903        boolean alwaysFinishActivities = Settings.Global.getInt(
10904            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10905        boolean forceRtl = Settings.Global.getInt(
10906                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10907        // Transfer any global setting for forcing RTL layout, into a System Property
10908        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10909
10910        Configuration configuration = new Configuration();
10911        Settings.System.getConfiguration(resolver, configuration);
10912        if (forceRtl) {
10913            // This will take care of setting the correct layout direction flags
10914            configuration.setLayoutDirection(configuration.locale);
10915        }
10916
10917        synchronized (this) {
10918            mDebugApp = mOrigDebugApp = debugApp;
10919            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10920            mAlwaysFinishActivities = alwaysFinishActivities;
10921            // This happens before any activities are started, so we can
10922            // change mConfiguration in-place.
10923            updateConfigurationLocked(configuration, null, false, true);
10924            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10925        }
10926    }
10927
10928    /** Loads resources after the current configuration has been set. */
10929    private void loadResourcesOnSystemReady() {
10930        final Resources res = mContext.getResources();
10931        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10932        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10933        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10934    }
10935
10936    public boolean testIsSystemReady() {
10937        // no need to synchronize(this) just to read & return the value
10938        return mSystemReady;
10939    }
10940
10941    private static File getCalledPreBootReceiversFile() {
10942        File dataDir = Environment.getDataDirectory();
10943        File systemDir = new File(dataDir, "system");
10944        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10945        return fname;
10946    }
10947
10948    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10949        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10950        File file = getCalledPreBootReceiversFile();
10951        FileInputStream fis = null;
10952        try {
10953            fis = new FileInputStream(file);
10954            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10955            int fvers = dis.readInt();
10956            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10957                String vers = dis.readUTF();
10958                String codename = dis.readUTF();
10959                String build = dis.readUTF();
10960                if (android.os.Build.VERSION.RELEASE.equals(vers)
10961                        && android.os.Build.VERSION.CODENAME.equals(codename)
10962                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10963                    int num = dis.readInt();
10964                    while (num > 0) {
10965                        num--;
10966                        String pkg = dis.readUTF();
10967                        String cls = dis.readUTF();
10968                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10969                    }
10970                }
10971            }
10972        } catch (FileNotFoundException e) {
10973        } catch (IOException e) {
10974            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10975        } finally {
10976            if (fis != null) {
10977                try {
10978                    fis.close();
10979                } catch (IOException e) {
10980                }
10981            }
10982        }
10983        return lastDoneReceivers;
10984    }
10985
10986    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10987        File file = getCalledPreBootReceiversFile();
10988        FileOutputStream fos = null;
10989        DataOutputStream dos = null;
10990        try {
10991            fos = new FileOutputStream(file);
10992            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10993            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10994            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10995            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10996            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10997            dos.writeInt(list.size());
10998            for (int i=0; i<list.size(); i++) {
10999                dos.writeUTF(list.get(i).getPackageName());
11000                dos.writeUTF(list.get(i).getClassName());
11001            }
11002        } catch (IOException e) {
11003            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11004            file.delete();
11005        } finally {
11006            FileUtils.sync(fos);
11007            if (dos != null) {
11008                try {
11009                    dos.close();
11010                } catch (IOException e) {
11011                    // TODO Auto-generated catch block
11012                    e.printStackTrace();
11013                }
11014            }
11015        }
11016    }
11017
11018    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11019            ArrayList<ComponentName> doneReceivers, int userId) {
11020        boolean waitingUpdate = false;
11021        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11022        List<ResolveInfo> ris = null;
11023        try {
11024            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11025                    intent, null, 0, userId);
11026        } catch (RemoteException e) {
11027        }
11028        if (ris != null) {
11029            for (int i=ris.size()-1; i>=0; i--) {
11030                if ((ris.get(i).activityInfo.applicationInfo.flags
11031                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11032                    ris.remove(i);
11033                }
11034            }
11035            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11036
11037            // For User 0, load the version number. When delivering to a new user, deliver
11038            // to all receivers.
11039            if (userId == UserHandle.USER_OWNER) {
11040                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11041                for (int i=0; i<ris.size(); i++) {
11042                    ActivityInfo ai = ris.get(i).activityInfo;
11043                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11044                    if (lastDoneReceivers.contains(comp)) {
11045                        // We already did the pre boot receiver for this app with the current
11046                        // platform version, so don't do it again...
11047                        ris.remove(i);
11048                        i--;
11049                        // ...however, do keep it as one that has been done, so we don't
11050                        // forget about it when rewriting the file of last done receivers.
11051                        doneReceivers.add(comp);
11052                    }
11053                }
11054            }
11055
11056            // If primary user, send broadcast to all available users, else just to userId
11057            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11058                    : new int[] { userId };
11059            for (int i = 0; i < ris.size(); i++) {
11060                ActivityInfo ai = ris.get(i).activityInfo;
11061                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11062                doneReceivers.add(comp);
11063                intent.setComponent(comp);
11064                for (int j=0; j<users.length; j++) {
11065                    IIntentReceiver finisher = null;
11066                    // On last receiver and user, set up a completion callback
11067                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11068                        finisher = new IIntentReceiver.Stub() {
11069                            public void performReceive(Intent intent, int resultCode,
11070                                    String data, Bundle extras, boolean ordered,
11071                                    boolean sticky, int sendingUser) {
11072                                // The raw IIntentReceiver interface is called
11073                                // with the AM lock held, so redispatch to
11074                                // execute our code without the lock.
11075                                mHandler.post(onFinishCallback);
11076                            }
11077                        };
11078                    }
11079                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11080                            + " for user " + users[j]);
11081                    broadcastIntentLocked(null, null, intent, null, finisher,
11082                            0, null, null, null, AppOpsManager.OP_NONE,
11083                            true, false, MY_PID, Process.SYSTEM_UID,
11084                            users[j]);
11085                    if (finisher != null) {
11086                        waitingUpdate = true;
11087                    }
11088                }
11089            }
11090        }
11091
11092        return waitingUpdate;
11093    }
11094
11095    public void systemReady(final Runnable goingCallback) {
11096        synchronized(this) {
11097            if (mSystemReady) {
11098                // If we're done calling all the receivers, run the next "boot phase" passed in
11099                // by the SystemServer
11100                if (goingCallback != null) {
11101                    goingCallback.run();
11102                }
11103                return;
11104            }
11105
11106            // Make sure we have the current profile info, since it is needed for
11107            // security checks.
11108            updateCurrentProfileIdsLocked();
11109
11110            if (mRecentTasks == null) {
11111                mRecentTasks = mTaskPersister.restoreTasksLocked();
11112                if (!mRecentTasks.isEmpty()) {
11113                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11114                }
11115                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11116                mTaskPersister.startPersisting();
11117            }
11118
11119            // Check to see if there are any update receivers to run.
11120            if (!mDidUpdate) {
11121                if (mWaitingUpdate) {
11122                    return;
11123                }
11124                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11125                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11126                    public void run() {
11127                        synchronized (ActivityManagerService.this) {
11128                            mDidUpdate = true;
11129                        }
11130                        writeLastDonePreBootReceivers(doneReceivers);
11131                        showBootMessage(mContext.getText(
11132                                R.string.android_upgrading_complete),
11133                                false);
11134                        systemReady(goingCallback);
11135                    }
11136                }, doneReceivers, UserHandle.USER_OWNER);
11137
11138                if (mWaitingUpdate) {
11139                    return;
11140                }
11141                mDidUpdate = true;
11142            }
11143
11144            mAppOpsService.systemReady();
11145            mSystemReady = true;
11146        }
11147
11148        ArrayList<ProcessRecord> procsToKill = null;
11149        synchronized(mPidsSelfLocked) {
11150            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11151                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11152                if (!isAllowedWhileBooting(proc.info)){
11153                    if (procsToKill == null) {
11154                        procsToKill = new ArrayList<ProcessRecord>();
11155                    }
11156                    procsToKill.add(proc);
11157                }
11158            }
11159        }
11160
11161        synchronized(this) {
11162            if (procsToKill != null) {
11163                for (int i=procsToKill.size()-1; i>=0; i--) {
11164                    ProcessRecord proc = procsToKill.get(i);
11165                    Slog.i(TAG, "Removing system update proc: " + proc);
11166                    removeProcessLocked(proc, true, false, "system update done");
11167                }
11168            }
11169
11170            // Now that we have cleaned up any update processes, we
11171            // are ready to start launching real processes and know that
11172            // we won't trample on them any more.
11173            mProcessesReady = true;
11174        }
11175
11176        Slog.i(TAG, "System now ready");
11177        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11178            SystemClock.uptimeMillis());
11179
11180        synchronized(this) {
11181            // Make sure we have no pre-ready processes sitting around.
11182
11183            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11184                ResolveInfo ri = mContext.getPackageManager()
11185                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11186                                STOCK_PM_FLAGS);
11187                CharSequence errorMsg = null;
11188                if (ri != null) {
11189                    ActivityInfo ai = ri.activityInfo;
11190                    ApplicationInfo app = ai.applicationInfo;
11191                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11192                        mTopAction = Intent.ACTION_FACTORY_TEST;
11193                        mTopData = null;
11194                        mTopComponent = new ComponentName(app.packageName,
11195                                ai.name);
11196                    } else {
11197                        errorMsg = mContext.getResources().getText(
11198                                com.android.internal.R.string.factorytest_not_system);
11199                    }
11200                } else {
11201                    errorMsg = mContext.getResources().getText(
11202                            com.android.internal.R.string.factorytest_no_action);
11203                }
11204                if (errorMsg != null) {
11205                    mTopAction = null;
11206                    mTopData = null;
11207                    mTopComponent = null;
11208                    Message msg = Message.obtain();
11209                    msg.what = SHOW_FACTORY_ERROR_MSG;
11210                    msg.getData().putCharSequence("msg", errorMsg);
11211                    mHandler.sendMessage(msg);
11212                }
11213            }
11214        }
11215
11216        retrieveSettings();
11217        loadResourcesOnSystemReady();
11218
11219        synchronized (this) {
11220            readGrantedUriPermissionsLocked();
11221        }
11222
11223        if (goingCallback != null) goingCallback.run();
11224
11225        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11226                Integer.toString(mCurrentUserId), mCurrentUserId);
11227        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11228                Integer.toString(mCurrentUserId), mCurrentUserId);
11229        mSystemServiceManager.startUser(mCurrentUserId);
11230
11231        synchronized (this) {
11232            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11233                try {
11234                    List apps = AppGlobals.getPackageManager().
11235                        getPersistentApplications(STOCK_PM_FLAGS);
11236                    if (apps != null) {
11237                        int N = apps.size();
11238                        int i;
11239                        for (i=0; i<N; i++) {
11240                            ApplicationInfo info
11241                                = (ApplicationInfo)apps.get(i);
11242                            if (info != null &&
11243                                    !info.packageName.equals("android")) {
11244                                addAppLocked(info, false, null /* ABI override */);
11245                            }
11246                        }
11247                    }
11248                } catch (RemoteException ex) {
11249                    // pm is in same process, this will never happen.
11250                }
11251            }
11252
11253            // Start up initial activity.
11254            mBooting = true;
11255            startHomeActivityLocked(mCurrentUserId);
11256
11257            try {
11258                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11259                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11260                            + " data partition or your device will be unstable.");
11261                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11262                }
11263            } catch (RemoteException e) {
11264            }
11265
11266            if (!Build.isFingerprintConsistent()) {
11267                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11268                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11269            }
11270
11271            long ident = Binder.clearCallingIdentity();
11272            try {
11273                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11274                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11275                        | Intent.FLAG_RECEIVER_FOREGROUND);
11276                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11277                broadcastIntentLocked(null, null, intent,
11278                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11279                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11280                intent = new Intent(Intent.ACTION_USER_STARTING);
11281                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11282                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11283                broadcastIntentLocked(null, null, intent,
11284                        null, new IIntentReceiver.Stub() {
11285                            @Override
11286                            public void performReceive(Intent intent, int resultCode, String data,
11287                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11288                                    throws RemoteException {
11289                            }
11290                        }, 0, null, null,
11291                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11292                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11293            } catch (Throwable t) {
11294                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11295            } finally {
11296                Binder.restoreCallingIdentity(ident);
11297            }
11298            mStackSupervisor.resumeTopActivitiesLocked();
11299            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11300        }
11301    }
11302
11303    private boolean makeAppCrashingLocked(ProcessRecord app,
11304            String shortMsg, String longMsg, String stackTrace) {
11305        app.crashing = true;
11306        app.crashingReport = generateProcessError(app,
11307                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11308        startAppProblemLocked(app);
11309        app.stopFreezingAllLocked();
11310        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11311    }
11312
11313    private void makeAppNotRespondingLocked(ProcessRecord app,
11314            String activity, String shortMsg, String longMsg) {
11315        app.notResponding = true;
11316        app.notRespondingReport = generateProcessError(app,
11317                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11318                activity, shortMsg, longMsg, null);
11319        startAppProblemLocked(app);
11320        app.stopFreezingAllLocked();
11321    }
11322
11323    /**
11324     * Generate a process error record, suitable for attachment to a ProcessRecord.
11325     *
11326     * @param app The ProcessRecord in which the error occurred.
11327     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11328     *                      ActivityManager.AppErrorStateInfo
11329     * @param activity The activity associated with the crash, if known.
11330     * @param shortMsg Short message describing the crash.
11331     * @param longMsg Long message describing the crash.
11332     * @param stackTrace Full crash stack trace, may be null.
11333     *
11334     * @return Returns a fully-formed AppErrorStateInfo record.
11335     */
11336    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11337            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11338        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11339
11340        report.condition = condition;
11341        report.processName = app.processName;
11342        report.pid = app.pid;
11343        report.uid = app.info.uid;
11344        report.tag = activity;
11345        report.shortMsg = shortMsg;
11346        report.longMsg = longMsg;
11347        report.stackTrace = stackTrace;
11348
11349        return report;
11350    }
11351
11352    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11353        synchronized (this) {
11354            app.crashing = false;
11355            app.crashingReport = null;
11356            app.notResponding = false;
11357            app.notRespondingReport = null;
11358            if (app.anrDialog == fromDialog) {
11359                app.anrDialog = null;
11360            }
11361            if (app.waitDialog == fromDialog) {
11362                app.waitDialog = null;
11363            }
11364            if (app.pid > 0 && app.pid != MY_PID) {
11365                handleAppCrashLocked(app, null, null, null);
11366                app.kill("user request after error", true);
11367            }
11368        }
11369    }
11370
11371    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11372            String stackTrace) {
11373        long now = SystemClock.uptimeMillis();
11374
11375        Long crashTime;
11376        if (!app.isolated) {
11377            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11378        } else {
11379            crashTime = null;
11380        }
11381        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11382            // This process loses!
11383            Slog.w(TAG, "Process " + app.info.processName
11384                    + " has crashed too many times: killing!");
11385            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11386                    app.userId, app.info.processName, app.uid);
11387            mStackSupervisor.handleAppCrashLocked(app);
11388            if (!app.persistent) {
11389                // We don't want to start this process again until the user
11390                // explicitly does so...  but for persistent process, we really
11391                // need to keep it running.  If a persistent process is actually
11392                // repeatedly crashing, then badness for everyone.
11393                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11394                        app.info.processName);
11395                if (!app.isolated) {
11396                    // XXX We don't have a way to mark isolated processes
11397                    // as bad, since they don't have a peristent identity.
11398                    mBadProcesses.put(app.info.processName, app.uid,
11399                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11400                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11401                }
11402                app.bad = true;
11403                app.removed = true;
11404                // Don't let services in this process be restarted and potentially
11405                // annoy the user repeatedly.  Unless it is persistent, since those
11406                // processes run critical code.
11407                removeProcessLocked(app, false, false, "crash");
11408                mStackSupervisor.resumeTopActivitiesLocked();
11409                return false;
11410            }
11411            mStackSupervisor.resumeTopActivitiesLocked();
11412        } else {
11413            mStackSupervisor.finishTopRunningActivityLocked(app);
11414        }
11415
11416        // Bump up the crash count of any services currently running in the proc.
11417        for (int i=app.services.size()-1; i>=0; i--) {
11418            // Any services running in the application need to be placed
11419            // back in the pending list.
11420            ServiceRecord sr = app.services.valueAt(i);
11421            sr.crashCount++;
11422        }
11423
11424        // If the crashing process is what we consider to be the "home process" and it has been
11425        // replaced by a third-party app, clear the package preferred activities from packages
11426        // with a home activity running in the process to prevent a repeatedly crashing app
11427        // from blocking the user to manually clear the list.
11428        final ArrayList<ActivityRecord> activities = app.activities;
11429        if (app == mHomeProcess && activities.size() > 0
11430                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11431            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11432                final ActivityRecord r = activities.get(activityNdx);
11433                if (r.isHomeActivity()) {
11434                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11435                    try {
11436                        ActivityThread.getPackageManager()
11437                                .clearPackagePreferredActivities(r.packageName);
11438                    } catch (RemoteException c) {
11439                        // pm is in same process, this will never happen.
11440                    }
11441                }
11442            }
11443        }
11444
11445        if (!app.isolated) {
11446            // XXX Can't keep track of crash times for isolated processes,
11447            // because they don't have a perisistent identity.
11448            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11449        }
11450
11451        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11452        return true;
11453    }
11454
11455    void startAppProblemLocked(ProcessRecord app) {
11456        // If this app is not running under the current user, then we
11457        // can't give it a report button because that would require
11458        // launching the report UI under a different user.
11459        app.errorReportReceiver = null;
11460
11461        for (int userId : mCurrentProfileIds) {
11462            if (app.userId == userId) {
11463                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11464                        mContext, app.info.packageName, app.info.flags);
11465            }
11466        }
11467        skipCurrentReceiverLocked(app);
11468    }
11469
11470    void skipCurrentReceiverLocked(ProcessRecord app) {
11471        for (BroadcastQueue queue : mBroadcastQueues) {
11472            queue.skipCurrentReceiverLocked(app);
11473        }
11474    }
11475
11476    /**
11477     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11478     * The application process will exit immediately after this call returns.
11479     * @param app object of the crashing app, null for the system server
11480     * @param crashInfo describing the exception
11481     */
11482    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11483        ProcessRecord r = findAppProcess(app, "Crash");
11484        final String processName = app == null ? "system_server"
11485                : (r == null ? "unknown" : r.processName);
11486
11487        handleApplicationCrashInner("crash", r, processName, crashInfo);
11488    }
11489
11490    /* Native crash reporting uses this inner version because it needs to be somewhat
11491     * decoupled from the AM-managed cleanup lifecycle
11492     */
11493    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11494            ApplicationErrorReport.CrashInfo crashInfo) {
11495        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11496                UserHandle.getUserId(Binder.getCallingUid()), processName,
11497                r == null ? -1 : r.info.flags,
11498                crashInfo.exceptionClassName,
11499                crashInfo.exceptionMessage,
11500                crashInfo.throwFileName,
11501                crashInfo.throwLineNumber);
11502
11503        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11504
11505        crashApplication(r, crashInfo);
11506    }
11507
11508    public void handleApplicationStrictModeViolation(
11509            IBinder app,
11510            int violationMask,
11511            StrictMode.ViolationInfo info) {
11512        ProcessRecord r = findAppProcess(app, "StrictMode");
11513        if (r == null) {
11514            return;
11515        }
11516
11517        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11518            Integer stackFingerprint = info.hashCode();
11519            boolean logIt = true;
11520            synchronized (mAlreadyLoggedViolatedStacks) {
11521                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11522                    logIt = false;
11523                    // TODO: sub-sample into EventLog for these, with
11524                    // the info.durationMillis?  Then we'd get
11525                    // the relative pain numbers, without logging all
11526                    // the stack traces repeatedly.  We'd want to do
11527                    // likewise in the client code, which also does
11528                    // dup suppression, before the Binder call.
11529                } else {
11530                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11531                        mAlreadyLoggedViolatedStacks.clear();
11532                    }
11533                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11534                }
11535            }
11536            if (logIt) {
11537                logStrictModeViolationToDropBox(r, info);
11538            }
11539        }
11540
11541        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11542            AppErrorResult result = new AppErrorResult();
11543            synchronized (this) {
11544                final long origId = Binder.clearCallingIdentity();
11545
11546                Message msg = Message.obtain();
11547                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11548                HashMap<String, Object> data = new HashMap<String, Object>();
11549                data.put("result", result);
11550                data.put("app", r);
11551                data.put("violationMask", violationMask);
11552                data.put("info", info);
11553                msg.obj = data;
11554                mHandler.sendMessage(msg);
11555
11556                Binder.restoreCallingIdentity(origId);
11557            }
11558            int res = result.get();
11559            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11560        }
11561    }
11562
11563    // Depending on the policy in effect, there could be a bunch of
11564    // these in quick succession so we try to batch these together to
11565    // minimize disk writes, number of dropbox entries, and maximize
11566    // compression, by having more fewer, larger records.
11567    private void logStrictModeViolationToDropBox(
11568            ProcessRecord process,
11569            StrictMode.ViolationInfo info) {
11570        if (info == null) {
11571            return;
11572        }
11573        final boolean isSystemApp = process == null ||
11574                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11575                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11576        final String processName = process == null ? "unknown" : process.processName;
11577        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11578        final DropBoxManager dbox = (DropBoxManager)
11579                mContext.getSystemService(Context.DROPBOX_SERVICE);
11580
11581        // Exit early if the dropbox isn't configured to accept this report type.
11582        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11583
11584        boolean bufferWasEmpty;
11585        boolean needsFlush;
11586        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11587        synchronized (sb) {
11588            bufferWasEmpty = sb.length() == 0;
11589            appendDropBoxProcessHeaders(process, processName, sb);
11590            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11591            sb.append("System-App: ").append(isSystemApp).append("\n");
11592            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11593            if (info.violationNumThisLoop != 0) {
11594                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11595            }
11596            if (info.numAnimationsRunning != 0) {
11597                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11598            }
11599            if (info.broadcastIntentAction != null) {
11600                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11601            }
11602            if (info.durationMillis != -1) {
11603                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11604            }
11605            if (info.numInstances != -1) {
11606                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11607            }
11608            if (info.tags != null) {
11609                for (String tag : info.tags) {
11610                    sb.append("Span-Tag: ").append(tag).append("\n");
11611                }
11612            }
11613            sb.append("\n");
11614            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11615                sb.append(info.crashInfo.stackTrace);
11616            }
11617            sb.append("\n");
11618
11619            // Only buffer up to ~64k.  Various logging bits truncate
11620            // things at 128k.
11621            needsFlush = (sb.length() > 64 * 1024);
11622        }
11623
11624        // Flush immediately if the buffer's grown too large, or this
11625        // is a non-system app.  Non-system apps are isolated with a
11626        // different tag & policy and not batched.
11627        //
11628        // Batching is useful during internal testing with
11629        // StrictMode settings turned up high.  Without batching,
11630        // thousands of separate files could be created on boot.
11631        if (!isSystemApp || needsFlush) {
11632            new Thread("Error dump: " + dropboxTag) {
11633                @Override
11634                public void run() {
11635                    String report;
11636                    synchronized (sb) {
11637                        report = sb.toString();
11638                        sb.delete(0, sb.length());
11639                        sb.trimToSize();
11640                    }
11641                    if (report.length() != 0) {
11642                        dbox.addText(dropboxTag, report);
11643                    }
11644                }
11645            }.start();
11646            return;
11647        }
11648
11649        // System app batching:
11650        if (!bufferWasEmpty) {
11651            // An existing dropbox-writing thread is outstanding, so
11652            // we don't need to start it up.  The existing thread will
11653            // catch the buffer appends we just did.
11654            return;
11655        }
11656
11657        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11658        // (After this point, we shouldn't access AMS internal data structures.)
11659        new Thread("Error dump: " + dropboxTag) {
11660            @Override
11661            public void run() {
11662                // 5 second sleep to let stacks arrive and be batched together
11663                try {
11664                    Thread.sleep(5000);  // 5 seconds
11665                } catch (InterruptedException e) {}
11666
11667                String errorReport;
11668                synchronized (mStrictModeBuffer) {
11669                    errorReport = mStrictModeBuffer.toString();
11670                    if (errorReport.length() == 0) {
11671                        return;
11672                    }
11673                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11674                    mStrictModeBuffer.trimToSize();
11675                }
11676                dbox.addText(dropboxTag, errorReport);
11677            }
11678        }.start();
11679    }
11680
11681    /**
11682     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11683     * @param app object of the crashing app, null for the system server
11684     * @param tag reported by the caller
11685     * @param system whether this wtf is coming from the system
11686     * @param crashInfo describing the context of the error
11687     * @return true if the process should exit immediately (WTF is fatal)
11688     */
11689    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11690            final ApplicationErrorReport.CrashInfo crashInfo) {
11691        final int callingUid = Binder.getCallingUid();
11692        final int callingPid = Binder.getCallingPid();
11693
11694        if (system) {
11695            // If this is coming from the system, we could very well have low-level
11696            // system locks held, so we want to do this all asynchronously.  And we
11697            // never want this to become fatal, so there is that too.
11698            mHandler.post(new Runnable() {
11699                @Override public void run() {
11700                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11701                }
11702            });
11703            return false;
11704        }
11705
11706        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11707                crashInfo);
11708
11709        if (r != null && r.pid != Process.myPid() &&
11710                Settings.Global.getInt(mContext.getContentResolver(),
11711                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11712            crashApplication(r, crashInfo);
11713            return true;
11714        } else {
11715            return false;
11716        }
11717    }
11718
11719    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11720            final ApplicationErrorReport.CrashInfo crashInfo) {
11721        final ProcessRecord r = findAppProcess(app, "WTF");
11722        final String processName = app == null ? "system_server"
11723                : (r == null ? "unknown" : r.processName);
11724
11725        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11726                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11727
11728        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11729
11730        return r;
11731    }
11732
11733    /**
11734     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11735     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11736     */
11737    private ProcessRecord findAppProcess(IBinder app, String reason) {
11738        if (app == null) {
11739            return null;
11740        }
11741
11742        synchronized (this) {
11743            final int NP = mProcessNames.getMap().size();
11744            for (int ip=0; ip<NP; ip++) {
11745                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11746                final int NA = apps.size();
11747                for (int ia=0; ia<NA; ia++) {
11748                    ProcessRecord p = apps.valueAt(ia);
11749                    if (p.thread != null && p.thread.asBinder() == app) {
11750                        return p;
11751                    }
11752                }
11753            }
11754
11755            Slog.w(TAG, "Can't find mystery application for " + reason
11756                    + " from pid=" + Binder.getCallingPid()
11757                    + " uid=" + Binder.getCallingUid() + ": " + app);
11758            return null;
11759        }
11760    }
11761
11762    /**
11763     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11764     * to append various headers to the dropbox log text.
11765     */
11766    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11767            StringBuilder sb) {
11768        // Watchdog thread ends up invoking this function (with
11769        // a null ProcessRecord) to add the stack file to dropbox.
11770        // Do not acquire a lock on this (am) in such cases, as it
11771        // could cause a potential deadlock, if and when watchdog
11772        // is invoked due to unavailability of lock on am and it
11773        // would prevent watchdog from killing system_server.
11774        if (process == null) {
11775            sb.append("Process: ").append(processName).append("\n");
11776            return;
11777        }
11778        // Note: ProcessRecord 'process' is guarded by the service
11779        // instance.  (notably process.pkgList, which could otherwise change
11780        // concurrently during execution of this method)
11781        synchronized (this) {
11782            sb.append("Process: ").append(processName).append("\n");
11783            int flags = process.info.flags;
11784            IPackageManager pm = AppGlobals.getPackageManager();
11785            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11786            for (int ip=0; ip<process.pkgList.size(); ip++) {
11787                String pkg = process.pkgList.keyAt(ip);
11788                sb.append("Package: ").append(pkg);
11789                try {
11790                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11791                    if (pi != null) {
11792                        sb.append(" v").append(pi.versionCode);
11793                        if (pi.versionName != null) {
11794                            sb.append(" (").append(pi.versionName).append(")");
11795                        }
11796                    }
11797                } catch (RemoteException e) {
11798                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11799                }
11800                sb.append("\n");
11801            }
11802        }
11803    }
11804
11805    private static String processClass(ProcessRecord process) {
11806        if (process == null || process.pid == MY_PID) {
11807            return "system_server";
11808        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11809            return "system_app";
11810        } else {
11811            return "data_app";
11812        }
11813    }
11814
11815    /**
11816     * Write a description of an error (crash, WTF, ANR) to the drop box.
11817     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11818     * @param process which caused the error, null means the system server
11819     * @param activity which triggered the error, null if unknown
11820     * @param parent activity related to the error, null if unknown
11821     * @param subject line related to the error, null if absent
11822     * @param report in long form describing the error, null if absent
11823     * @param logFile to include in the report, null if none
11824     * @param crashInfo giving an application stack trace, null if absent
11825     */
11826    public void addErrorToDropBox(String eventType,
11827            ProcessRecord process, String processName, ActivityRecord activity,
11828            ActivityRecord parent, String subject,
11829            final String report, final File logFile,
11830            final ApplicationErrorReport.CrashInfo crashInfo) {
11831        // NOTE -- this must never acquire the ActivityManagerService lock,
11832        // otherwise the watchdog may be prevented from resetting the system.
11833
11834        final String dropboxTag = processClass(process) + "_" + eventType;
11835        final DropBoxManager dbox = (DropBoxManager)
11836                mContext.getSystemService(Context.DROPBOX_SERVICE);
11837
11838        // Exit early if the dropbox isn't configured to accept this report type.
11839        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11840
11841        final StringBuilder sb = new StringBuilder(1024);
11842        appendDropBoxProcessHeaders(process, processName, sb);
11843        if (activity != null) {
11844            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11845        }
11846        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11847            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11848        }
11849        if (parent != null && parent != activity) {
11850            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11851        }
11852        if (subject != null) {
11853            sb.append("Subject: ").append(subject).append("\n");
11854        }
11855        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11856        if (Debug.isDebuggerConnected()) {
11857            sb.append("Debugger: Connected\n");
11858        }
11859        sb.append("\n");
11860
11861        // Do the rest in a worker thread to avoid blocking the caller on I/O
11862        // (After this point, we shouldn't access AMS internal data structures.)
11863        Thread worker = new Thread("Error dump: " + dropboxTag) {
11864            @Override
11865            public void run() {
11866                if (report != null) {
11867                    sb.append(report);
11868                }
11869                if (logFile != null) {
11870                    try {
11871                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11872                                    "\n\n[[TRUNCATED]]"));
11873                    } catch (IOException e) {
11874                        Slog.e(TAG, "Error reading " + logFile, e);
11875                    }
11876                }
11877                if (crashInfo != null && crashInfo.stackTrace != null) {
11878                    sb.append(crashInfo.stackTrace);
11879                }
11880
11881                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11882                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11883                if (lines > 0) {
11884                    sb.append("\n");
11885
11886                    // Merge several logcat streams, and take the last N lines
11887                    InputStreamReader input = null;
11888                    try {
11889                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11890                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11891                                "-b", "crash",
11892                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11893
11894                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11895                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11896                        input = new InputStreamReader(logcat.getInputStream());
11897
11898                        int num;
11899                        char[] buf = new char[8192];
11900                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11901                    } catch (IOException e) {
11902                        Slog.e(TAG, "Error running logcat", e);
11903                    } finally {
11904                        if (input != null) try { input.close(); } catch (IOException e) {}
11905                    }
11906                }
11907
11908                dbox.addText(dropboxTag, sb.toString());
11909            }
11910        };
11911
11912        if (process == null) {
11913            // If process is null, we are being called from some internal code
11914            // and may be about to die -- run this synchronously.
11915            worker.run();
11916        } else {
11917            worker.start();
11918        }
11919    }
11920
11921    /**
11922     * Bring up the "unexpected error" dialog box for a crashing app.
11923     * Deal with edge cases (intercepts from instrumented applications,
11924     * ActivityController, error intent receivers, that sort of thing).
11925     * @param r the application crashing
11926     * @param crashInfo describing the failure
11927     */
11928    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11929        long timeMillis = System.currentTimeMillis();
11930        String shortMsg = crashInfo.exceptionClassName;
11931        String longMsg = crashInfo.exceptionMessage;
11932        String stackTrace = crashInfo.stackTrace;
11933        if (shortMsg != null && longMsg != null) {
11934            longMsg = shortMsg + ": " + longMsg;
11935        } else if (shortMsg != null) {
11936            longMsg = shortMsg;
11937        }
11938
11939        AppErrorResult result = new AppErrorResult();
11940        synchronized (this) {
11941            if (mController != null) {
11942                try {
11943                    String name = r != null ? r.processName : null;
11944                    int pid = r != null ? r.pid : Binder.getCallingPid();
11945                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11946                    if (!mController.appCrashed(name, pid,
11947                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11948                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11949                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11950                            Slog.w(TAG, "Skip killing native crashed app " + name
11951                                    + "(" + pid + ") during testing");
11952                        } else {
11953                            Slog.w(TAG, "Force-killing crashed app " + name
11954                                    + " at watcher's request");
11955                            if (r != null) {
11956                                r.kill("crash", true);
11957                            } else {
11958                                // Huh.
11959                                Process.killProcess(pid);
11960                                Process.killProcessGroup(uid, pid);
11961                            }
11962                        }
11963                        return;
11964                    }
11965                } catch (RemoteException e) {
11966                    mController = null;
11967                    Watchdog.getInstance().setActivityController(null);
11968                }
11969            }
11970
11971            final long origId = Binder.clearCallingIdentity();
11972
11973            // If this process is running instrumentation, finish it.
11974            if (r != null && r.instrumentationClass != null) {
11975                Slog.w(TAG, "Error in app " + r.processName
11976                      + " running instrumentation " + r.instrumentationClass + ":");
11977                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11978                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11979                Bundle info = new Bundle();
11980                info.putString("shortMsg", shortMsg);
11981                info.putString("longMsg", longMsg);
11982                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11983                Binder.restoreCallingIdentity(origId);
11984                return;
11985            }
11986
11987            // If we can't identify the process or it's already exceeded its crash quota,
11988            // quit right away without showing a crash dialog.
11989            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11990                Binder.restoreCallingIdentity(origId);
11991                return;
11992            }
11993
11994            Message msg = Message.obtain();
11995            msg.what = SHOW_ERROR_MSG;
11996            HashMap data = new HashMap();
11997            data.put("result", result);
11998            data.put("app", r);
11999            msg.obj = data;
12000            mHandler.sendMessage(msg);
12001
12002            Binder.restoreCallingIdentity(origId);
12003        }
12004
12005        int res = result.get();
12006
12007        Intent appErrorIntent = null;
12008        synchronized (this) {
12009            if (r != null && !r.isolated) {
12010                // XXX Can't keep track of crash time for isolated processes,
12011                // since they don't have a persistent identity.
12012                mProcessCrashTimes.put(r.info.processName, r.uid,
12013                        SystemClock.uptimeMillis());
12014            }
12015            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12016                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12017            }
12018        }
12019
12020        if (appErrorIntent != null) {
12021            try {
12022                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12023            } catch (ActivityNotFoundException e) {
12024                Slog.w(TAG, "bug report receiver dissappeared", e);
12025            }
12026        }
12027    }
12028
12029    Intent createAppErrorIntentLocked(ProcessRecord r,
12030            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12031        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12032        if (report == null) {
12033            return null;
12034        }
12035        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12036        result.setComponent(r.errorReportReceiver);
12037        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12038        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12039        return result;
12040    }
12041
12042    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12043            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12044        if (r.errorReportReceiver == null) {
12045            return null;
12046        }
12047
12048        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12049            return null;
12050        }
12051
12052        ApplicationErrorReport report = new ApplicationErrorReport();
12053        report.packageName = r.info.packageName;
12054        report.installerPackageName = r.errorReportReceiver.getPackageName();
12055        report.processName = r.processName;
12056        report.time = timeMillis;
12057        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12058
12059        if (r.crashing || r.forceCrashReport) {
12060            report.type = ApplicationErrorReport.TYPE_CRASH;
12061            report.crashInfo = crashInfo;
12062        } else if (r.notResponding) {
12063            report.type = ApplicationErrorReport.TYPE_ANR;
12064            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12065
12066            report.anrInfo.activity = r.notRespondingReport.tag;
12067            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12068            report.anrInfo.info = r.notRespondingReport.longMsg;
12069        }
12070
12071        return report;
12072    }
12073
12074    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12075        enforceNotIsolatedCaller("getProcessesInErrorState");
12076        // assume our apps are happy - lazy create the list
12077        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12078
12079        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12080                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12081        int userId = UserHandle.getUserId(Binder.getCallingUid());
12082
12083        synchronized (this) {
12084
12085            // iterate across all processes
12086            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12087                ProcessRecord app = mLruProcesses.get(i);
12088                if (!allUsers && app.userId != userId) {
12089                    continue;
12090                }
12091                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12092                    // This one's in trouble, so we'll generate a report for it
12093                    // crashes are higher priority (in case there's a crash *and* an anr)
12094                    ActivityManager.ProcessErrorStateInfo report = null;
12095                    if (app.crashing) {
12096                        report = app.crashingReport;
12097                    } else if (app.notResponding) {
12098                        report = app.notRespondingReport;
12099                    }
12100
12101                    if (report != null) {
12102                        if (errList == null) {
12103                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12104                        }
12105                        errList.add(report);
12106                    } else {
12107                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12108                                " crashing = " + app.crashing +
12109                                " notResponding = " + app.notResponding);
12110                    }
12111                }
12112            }
12113        }
12114
12115        return errList;
12116    }
12117
12118    static int procStateToImportance(int procState, int memAdj,
12119            ActivityManager.RunningAppProcessInfo currApp) {
12120        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12121        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12122            currApp.lru = memAdj;
12123        } else {
12124            currApp.lru = 0;
12125        }
12126        return imp;
12127    }
12128
12129    private void fillInProcMemInfo(ProcessRecord app,
12130            ActivityManager.RunningAppProcessInfo outInfo) {
12131        outInfo.pid = app.pid;
12132        outInfo.uid = app.info.uid;
12133        if (mHeavyWeightProcess == app) {
12134            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12135        }
12136        if (app.persistent) {
12137            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12138        }
12139        if (app.activities.size() > 0) {
12140            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12141        }
12142        outInfo.lastTrimLevel = app.trimMemoryLevel;
12143        int adj = app.curAdj;
12144        int procState = app.curProcState;
12145        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12146        outInfo.importanceReasonCode = app.adjTypeCode;
12147        outInfo.processState = app.curProcState;
12148    }
12149
12150    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12151        enforceNotIsolatedCaller("getRunningAppProcesses");
12152        // Lazy instantiation of list
12153        List<ActivityManager.RunningAppProcessInfo> runList = null;
12154        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12155                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12156        int userId = UserHandle.getUserId(Binder.getCallingUid());
12157        synchronized (this) {
12158            // Iterate across all processes
12159            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12160                ProcessRecord app = mLruProcesses.get(i);
12161                if (!allUsers && app.userId != userId) {
12162                    continue;
12163                }
12164                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12165                    // Generate process state info for running application
12166                    ActivityManager.RunningAppProcessInfo currApp =
12167                        new ActivityManager.RunningAppProcessInfo(app.processName,
12168                                app.pid, app.getPackageList());
12169                    fillInProcMemInfo(app, currApp);
12170                    if (app.adjSource instanceof ProcessRecord) {
12171                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12172                        currApp.importanceReasonImportance =
12173                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12174                                        app.adjSourceProcState);
12175                    } else if (app.adjSource instanceof ActivityRecord) {
12176                        ActivityRecord r = (ActivityRecord)app.adjSource;
12177                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12178                    }
12179                    if (app.adjTarget instanceof ComponentName) {
12180                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12181                    }
12182                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12183                    //        + " lru=" + currApp.lru);
12184                    if (runList == null) {
12185                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12186                    }
12187                    runList.add(currApp);
12188                }
12189            }
12190        }
12191        return runList;
12192    }
12193
12194    public List<ApplicationInfo> getRunningExternalApplications() {
12195        enforceNotIsolatedCaller("getRunningExternalApplications");
12196        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12197        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12198        if (runningApps != null && runningApps.size() > 0) {
12199            Set<String> extList = new HashSet<String>();
12200            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12201                if (app.pkgList != null) {
12202                    for (String pkg : app.pkgList) {
12203                        extList.add(pkg);
12204                    }
12205                }
12206            }
12207            IPackageManager pm = AppGlobals.getPackageManager();
12208            for (String pkg : extList) {
12209                try {
12210                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12211                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12212                        retList.add(info);
12213                    }
12214                } catch (RemoteException e) {
12215                }
12216            }
12217        }
12218        return retList;
12219    }
12220
12221    @Override
12222    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12223        enforceNotIsolatedCaller("getMyMemoryState");
12224        synchronized (this) {
12225            ProcessRecord proc;
12226            synchronized (mPidsSelfLocked) {
12227                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12228            }
12229            fillInProcMemInfo(proc, outInfo);
12230        }
12231    }
12232
12233    @Override
12234    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12235        if (checkCallingPermission(android.Manifest.permission.DUMP)
12236                != PackageManager.PERMISSION_GRANTED) {
12237            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12238                    + Binder.getCallingPid()
12239                    + ", uid=" + Binder.getCallingUid()
12240                    + " without permission "
12241                    + android.Manifest.permission.DUMP);
12242            return;
12243        }
12244
12245        boolean dumpAll = false;
12246        boolean dumpClient = false;
12247        String dumpPackage = null;
12248
12249        int opti = 0;
12250        while (opti < args.length) {
12251            String opt = args[opti];
12252            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12253                break;
12254            }
12255            opti++;
12256            if ("-a".equals(opt)) {
12257                dumpAll = true;
12258            } else if ("-c".equals(opt)) {
12259                dumpClient = true;
12260            } else if ("-h".equals(opt)) {
12261                pw.println("Activity manager dump options:");
12262                pw.println("  [-a] [-c] [-h] [cmd] ...");
12263                pw.println("  cmd may be one of:");
12264                pw.println("    a[ctivities]: activity stack state");
12265                pw.println("    r[recents]: recent activities state");
12266                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12267                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12268                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12269                pw.println("    o[om]: out of memory management");
12270                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12271                pw.println("    provider [COMP_SPEC]: provider client-side state");
12272                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12273                pw.println("    service [COMP_SPEC]: service client-side state");
12274                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12275                pw.println("    all: dump all activities");
12276                pw.println("    top: dump the top activity");
12277                pw.println("    write: write all pending state to storage");
12278                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12279                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12280                pw.println("    a partial substring in a component name, a");
12281                pw.println("    hex object identifier.");
12282                pw.println("  -a: include all available server state.");
12283                pw.println("  -c: include client state.");
12284                return;
12285            } else {
12286                pw.println("Unknown argument: " + opt + "; use -h for help");
12287            }
12288        }
12289
12290        long origId = Binder.clearCallingIdentity();
12291        boolean more = false;
12292        // Is the caller requesting to dump a particular piece of data?
12293        if (opti < args.length) {
12294            String cmd = args[opti];
12295            opti++;
12296            if ("activities".equals(cmd) || "a".equals(cmd)) {
12297                synchronized (this) {
12298                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12299                }
12300            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12301                synchronized (this) {
12302                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12303                }
12304            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12305                String[] newArgs;
12306                String name;
12307                if (opti >= args.length) {
12308                    name = null;
12309                    newArgs = EMPTY_STRING_ARRAY;
12310                } else {
12311                    name = args[opti];
12312                    opti++;
12313                    newArgs = new String[args.length - opti];
12314                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12315                            args.length - opti);
12316                }
12317                synchronized (this) {
12318                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12319                }
12320            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12321                String[] newArgs;
12322                String name;
12323                if (opti >= args.length) {
12324                    name = null;
12325                    newArgs = EMPTY_STRING_ARRAY;
12326                } else {
12327                    name = args[opti];
12328                    opti++;
12329                    newArgs = new String[args.length - opti];
12330                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12331                            args.length - opti);
12332                }
12333                synchronized (this) {
12334                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12335                }
12336            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12337                String[] newArgs;
12338                String name;
12339                if (opti >= args.length) {
12340                    name = null;
12341                    newArgs = EMPTY_STRING_ARRAY;
12342                } else {
12343                    name = args[opti];
12344                    opti++;
12345                    newArgs = new String[args.length - opti];
12346                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12347                            args.length - opti);
12348                }
12349                synchronized (this) {
12350                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12351                }
12352            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12353                synchronized (this) {
12354                    dumpOomLocked(fd, pw, args, opti, true);
12355                }
12356            } else if ("provider".equals(cmd)) {
12357                String[] newArgs;
12358                String name;
12359                if (opti >= args.length) {
12360                    name = null;
12361                    newArgs = EMPTY_STRING_ARRAY;
12362                } else {
12363                    name = args[opti];
12364                    opti++;
12365                    newArgs = new String[args.length - opti];
12366                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12367                }
12368                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12369                    pw.println("No providers match: " + name);
12370                    pw.println("Use -h for help.");
12371                }
12372            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12373                synchronized (this) {
12374                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12375                }
12376            } else if ("service".equals(cmd)) {
12377                String[] newArgs;
12378                String name;
12379                if (opti >= args.length) {
12380                    name = null;
12381                    newArgs = EMPTY_STRING_ARRAY;
12382                } else {
12383                    name = args[opti];
12384                    opti++;
12385                    newArgs = new String[args.length - opti];
12386                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12387                            args.length - opti);
12388                }
12389                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12390                    pw.println("No services match: " + name);
12391                    pw.println("Use -h for help.");
12392                }
12393            } else if ("package".equals(cmd)) {
12394                String[] newArgs;
12395                if (opti >= args.length) {
12396                    pw.println("package: no package name specified");
12397                    pw.println("Use -h for help.");
12398                } else {
12399                    dumpPackage = args[opti];
12400                    opti++;
12401                    newArgs = new String[args.length - opti];
12402                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12403                            args.length - opti);
12404                    args = newArgs;
12405                    opti = 0;
12406                    more = true;
12407                }
12408            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12409                synchronized (this) {
12410                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12411                }
12412            } else if ("write".equals(cmd)) {
12413                mTaskPersister.flush();
12414                pw.println("All tasks persisted.");
12415                return;
12416            } else {
12417                // Dumping a single activity?
12418                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12419                    pw.println("Bad activity command, or no activities match: " + cmd);
12420                    pw.println("Use -h for help.");
12421                }
12422            }
12423            if (!more) {
12424                Binder.restoreCallingIdentity(origId);
12425                return;
12426            }
12427        }
12428
12429        // No piece of data specified, dump everything.
12430        synchronized (this) {
12431            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12432            pw.println();
12433            if (dumpAll) {
12434                pw.println("-------------------------------------------------------------------------------");
12435            }
12436            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12437            pw.println();
12438            if (dumpAll) {
12439                pw.println("-------------------------------------------------------------------------------");
12440            }
12441            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12442            pw.println();
12443            if (dumpAll) {
12444                pw.println("-------------------------------------------------------------------------------");
12445            }
12446            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12447            pw.println();
12448            if (dumpAll) {
12449                pw.println("-------------------------------------------------------------------------------");
12450            }
12451            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12452            pw.println();
12453            if (dumpAll) {
12454                pw.println("-------------------------------------------------------------------------------");
12455            }
12456            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12457            pw.println();
12458            if (dumpAll) {
12459                pw.println("-------------------------------------------------------------------------------");
12460            }
12461            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12462        }
12463        Binder.restoreCallingIdentity(origId);
12464    }
12465
12466    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12467            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12468        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12469
12470        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12471                dumpPackage);
12472        boolean needSep = printedAnything;
12473
12474        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12475                dumpPackage, needSep, "  mFocusedActivity: ");
12476        if (printed) {
12477            printedAnything = true;
12478            needSep = false;
12479        }
12480
12481        if (dumpPackage == null) {
12482            if (needSep) {
12483                pw.println();
12484            }
12485            needSep = true;
12486            printedAnything = true;
12487            mStackSupervisor.dump(pw, "  ");
12488        }
12489
12490        if (!printedAnything) {
12491            pw.println("  (nothing)");
12492        }
12493    }
12494
12495    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12496            int opti, boolean dumpAll, String dumpPackage) {
12497        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12498
12499        boolean printedAnything = false;
12500
12501        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12502            boolean printedHeader = false;
12503
12504            final int N = mRecentTasks.size();
12505            for (int i=0; i<N; i++) {
12506                TaskRecord tr = mRecentTasks.get(i);
12507                if (dumpPackage != null) {
12508                    if (tr.realActivity == null ||
12509                            !dumpPackage.equals(tr.realActivity)) {
12510                        continue;
12511                    }
12512                }
12513                if (!printedHeader) {
12514                    pw.println("  Recent tasks:");
12515                    printedHeader = true;
12516                    printedAnything = true;
12517                }
12518                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12519                        pw.println(tr);
12520                if (dumpAll) {
12521                    mRecentTasks.get(i).dump(pw, "    ");
12522                }
12523            }
12524        }
12525
12526        if (!printedAnything) {
12527            pw.println("  (nothing)");
12528        }
12529    }
12530
12531    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12532            int opti, boolean dumpAll, String dumpPackage) {
12533        boolean needSep = false;
12534        boolean printedAnything = false;
12535        int numPers = 0;
12536
12537        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12538
12539        if (dumpAll) {
12540            final int NP = mProcessNames.getMap().size();
12541            for (int ip=0; ip<NP; ip++) {
12542                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12543                final int NA = procs.size();
12544                for (int ia=0; ia<NA; ia++) {
12545                    ProcessRecord r = procs.valueAt(ia);
12546                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12547                        continue;
12548                    }
12549                    if (!needSep) {
12550                        pw.println("  All known processes:");
12551                        needSep = true;
12552                        printedAnything = true;
12553                    }
12554                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12555                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12556                        pw.print(" "); pw.println(r);
12557                    r.dump(pw, "    ");
12558                    if (r.persistent) {
12559                        numPers++;
12560                    }
12561                }
12562            }
12563        }
12564
12565        if (mIsolatedProcesses.size() > 0) {
12566            boolean printed = false;
12567            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12568                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12569                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12570                    continue;
12571                }
12572                if (!printed) {
12573                    if (needSep) {
12574                        pw.println();
12575                    }
12576                    pw.println("  Isolated process list (sorted by uid):");
12577                    printedAnything = true;
12578                    printed = true;
12579                    needSep = true;
12580                }
12581                pw.println(String.format("%sIsolated #%2d: %s",
12582                        "    ", i, r.toString()));
12583            }
12584        }
12585
12586        if (mLruProcesses.size() > 0) {
12587            if (needSep) {
12588                pw.println();
12589            }
12590            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12591                    pw.print(" total, non-act at ");
12592                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12593                    pw.print(", non-svc at ");
12594                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12595                    pw.println("):");
12596            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12597            needSep = true;
12598            printedAnything = true;
12599        }
12600
12601        if (dumpAll || dumpPackage != null) {
12602            synchronized (mPidsSelfLocked) {
12603                boolean printed = false;
12604                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12605                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12606                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12607                        continue;
12608                    }
12609                    if (!printed) {
12610                        if (needSep) pw.println();
12611                        needSep = true;
12612                        pw.println("  PID mappings:");
12613                        printed = true;
12614                        printedAnything = true;
12615                    }
12616                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12617                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12618                }
12619            }
12620        }
12621
12622        if (mForegroundProcesses.size() > 0) {
12623            synchronized (mPidsSelfLocked) {
12624                boolean printed = false;
12625                for (int i=0; i<mForegroundProcesses.size(); i++) {
12626                    ProcessRecord r = mPidsSelfLocked.get(
12627                            mForegroundProcesses.valueAt(i).pid);
12628                    if (dumpPackage != null && (r == null
12629                            || !r.pkgList.containsKey(dumpPackage))) {
12630                        continue;
12631                    }
12632                    if (!printed) {
12633                        if (needSep) pw.println();
12634                        needSep = true;
12635                        pw.println("  Foreground Processes:");
12636                        printed = true;
12637                        printedAnything = true;
12638                    }
12639                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12640                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12641                }
12642            }
12643        }
12644
12645        if (mPersistentStartingProcesses.size() > 0) {
12646            if (needSep) pw.println();
12647            needSep = true;
12648            printedAnything = true;
12649            pw.println("  Persisent processes that are starting:");
12650            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12651                    "Starting Norm", "Restarting PERS", dumpPackage);
12652        }
12653
12654        if (mRemovedProcesses.size() > 0) {
12655            if (needSep) pw.println();
12656            needSep = true;
12657            printedAnything = true;
12658            pw.println("  Processes that are being removed:");
12659            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12660                    "Removed Norm", "Removed PERS", dumpPackage);
12661        }
12662
12663        if (mProcessesOnHold.size() > 0) {
12664            if (needSep) pw.println();
12665            needSep = true;
12666            printedAnything = true;
12667            pw.println("  Processes that are on old until the system is ready:");
12668            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12669                    "OnHold Norm", "OnHold PERS", dumpPackage);
12670        }
12671
12672        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12673
12674        if (mProcessCrashTimes.getMap().size() > 0) {
12675            boolean printed = false;
12676            long now = SystemClock.uptimeMillis();
12677            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12678            final int NP = pmap.size();
12679            for (int ip=0; ip<NP; ip++) {
12680                String pname = pmap.keyAt(ip);
12681                SparseArray<Long> uids = pmap.valueAt(ip);
12682                final int N = uids.size();
12683                for (int i=0; i<N; i++) {
12684                    int puid = uids.keyAt(i);
12685                    ProcessRecord r = mProcessNames.get(pname, puid);
12686                    if (dumpPackage != null && (r == null
12687                            || !r.pkgList.containsKey(dumpPackage))) {
12688                        continue;
12689                    }
12690                    if (!printed) {
12691                        if (needSep) pw.println();
12692                        needSep = true;
12693                        pw.println("  Time since processes crashed:");
12694                        printed = true;
12695                        printedAnything = true;
12696                    }
12697                    pw.print("    Process "); pw.print(pname);
12698                            pw.print(" uid "); pw.print(puid);
12699                            pw.print(": last crashed ");
12700                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12701                            pw.println(" ago");
12702                }
12703            }
12704        }
12705
12706        if (mBadProcesses.getMap().size() > 0) {
12707            boolean printed = false;
12708            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12709            final int NP = pmap.size();
12710            for (int ip=0; ip<NP; ip++) {
12711                String pname = pmap.keyAt(ip);
12712                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12713                final int N = uids.size();
12714                for (int i=0; i<N; i++) {
12715                    int puid = uids.keyAt(i);
12716                    ProcessRecord r = mProcessNames.get(pname, puid);
12717                    if (dumpPackage != null && (r == null
12718                            || !r.pkgList.containsKey(dumpPackage))) {
12719                        continue;
12720                    }
12721                    if (!printed) {
12722                        if (needSep) pw.println();
12723                        needSep = true;
12724                        pw.println("  Bad processes:");
12725                        printedAnything = true;
12726                    }
12727                    BadProcessInfo info = uids.valueAt(i);
12728                    pw.print("    Bad process "); pw.print(pname);
12729                            pw.print(" uid "); pw.print(puid);
12730                            pw.print(": crashed at time "); pw.println(info.time);
12731                    if (info.shortMsg != null) {
12732                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12733                    }
12734                    if (info.longMsg != null) {
12735                        pw.print("      Long msg: "); pw.println(info.longMsg);
12736                    }
12737                    if (info.stack != null) {
12738                        pw.println("      Stack:");
12739                        int lastPos = 0;
12740                        for (int pos=0; pos<info.stack.length(); pos++) {
12741                            if (info.stack.charAt(pos) == '\n') {
12742                                pw.print("        ");
12743                                pw.write(info.stack, lastPos, pos-lastPos);
12744                                pw.println();
12745                                lastPos = pos+1;
12746                            }
12747                        }
12748                        if (lastPos < info.stack.length()) {
12749                            pw.print("        ");
12750                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12751                            pw.println();
12752                        }
12753                    }
12754                }
12755            }
12756        }
12757
12758        if (dumpPackage == null) {
12759            pw.println();
12760            needSep = false;
12761            pw.println("  mStartedUsers:");
12762            for (int i=0; i<mStartedUsers.size(); i++) {
12763                UserStartedState uss = mStartedUsers.valueAt(i);
12764                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12765                        pw.print(": "); uss.dump("", pw);
12766            }
12767            pw.print("  mStartedUserArray: [");
12768            for (int i=0; i<mStartedUserArray.length; i++) {
12769                if (i > 0) pw.print(", ");
12770                pw.print(mStartedUserArray[i]);
12771            }
12772            pw.println("]");
12773            pw.print("  mUserLru: [");
12774            for (int i=0; i<mUserLru.size(); i++) {
12775                if (i > 0) pw.print(", ");
12776                pw.print(mUserLru.get(i));
12777            }
12778            pw.println("]");
12779            if (dumpAll) {
12780                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12781            }
12782            synchronized (mUserProfileGroupIdsSelfLocked) {
12783                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12784                    pw.println("  mUserProfileGroupIds:");
12785                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12786                        pw.print("    User #");
12787                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12788                        pw.print(" -> profile #");
12789                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12790                    }
12791                }
12792            }
12793        }
12794        if (mHomeProcess != null && (dumpPackage == null
12795                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12796            if (needSep) {
12797                pw.println();
12798                needSep = false;
12799            }
12800            pw.println("  mHomeProcess: " + mHomeProcess);
12801        }
12802        if (mPreviousProcess != null && (dumpPackage == null
12803                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12804            if (needSep) {
12805                pw.println();
12806                needSep = false;
12807            }
12808            pw.println("  mPreviousProcess: " + mPreviousProcess);
12809        }
12810        if (dumpAll) {
12811            StringBuilder sb = new StringBuilder(128);
12812            sb.append("  mPreviousProcessVisibleTime: ");
12813            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12814            pw.println(sb);
12815        }
12816        if (mHeavyWeightProcess != null && (dumpPackage == null
12817                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12818            if (needSep) {
12819                pw.println();
12820                needSep = false;
12821            }
12822            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12823        }
12824        if (dumpPackage == null) {
12825            pw.println("  mConfiguration: " + mConfiguration);
12826        }
12827        if (dumpAll) {
12828            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12829            if (mCompatModePackages.getPackages().size() > 0) {
12830                boolean printed = false;
12831                for (Map.Entry<String, Integer> entry
12832                        : mCompatModePackages.getPackages().entrySet()) {
12833                    String pkg = entry.getKey();
12834                    int mode = entry.getValue();
12835                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12836                        continue;
12837                    }
12838                    if (!printed) {
12839                        pw.println("  mScreenCompatPackages:");
12840                        printed = true;
12841                    }
12842                    pw.print("    "); pw.print(pkg); pw.print(": ");
12843                            pw.print(mode); pw.println();
12844                }
12845            }
12846        }
12847        if (dumpPackage == null) {
12848            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12849                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12850                        + " mLockScreenShown " + lockScreenShownToString());
12851            }
12852            if (mShuttingDown || mRunningVoice) {
12853                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12854            }
12855        }
12856        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12857                || mOrigWaitForDebugger) {
12858            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12859                    || dumpPackage.equals(mOrigDebugApp)) {
12860                if (needSep) {
12861                    pw.println();
12862                    needSep = false;
12863                }
12864                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12865                        + " mDebugTransient=" + mDebugTransient
12866                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12867            }
12868        }
12869        if (mOpenGlTraceApp != null) {
12870            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12871                if (needSep) {
12872                    pw.println();
12873                    needSep = false;
12874                }
12875                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12876            }
12877        }
12878        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12879                || mProfileFd != null) {
12880            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12881                if (needSep) {
12882                    pw.println();
12883                    needSep = false;
12884                }
12885                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12886                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12887                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12888                        + mAutoStopProfiler);
12889                pw.println("  mProfileType=" + mProfileType);
12890            }
12891        }
12892        if (dumpPackage == null) {
12893            if (mAlwaysFinishActivities || mController != null) {
12894                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12895                        + " mController=" + mController);
12896            }
12897            if (dumpAll) {
12898                pw.println("  Total persistent processes: " + numPers);
12899                pw.println("  mProcessesReady=" + mProcessesReady
12900                        + " mSystemReady=" + mSystemReady
12901                        + " mBooted=" + mBooted
12902                        + " mFactoryTest=" + mFactoryTest);
12903                pw.println("  mBooting=" + mBooting
12904                        + " mCallFinishBooting=" + mCallFinishBooting
12905                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12906                pw.print("  mLastPowerCheckRealtime=");
12907                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12908                        pw.println("");
12909                pw.print("  mLastPowerCheckUptime=");
12910                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12911                        pw.println("");
12912                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12913                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12914                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12915                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12916                        + " (" + mLruProcesses.size() + " total)"
12917                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12918                        + " mNumServiceProcs=" + mNumServiceProcs
12919                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12920                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12921                        + " mLastMemoryLevel" + mLastMemoryLevel
12922                        + " mLastNumProcesses" + mLastNumProcesses);
12923                long now = SystemClock.uptimeMillis();
12924                pw.print("  mLastIdleTime=");
12925                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12926                        pw.print(" mLowRamSinceLastIdle=");
12927                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12928                        pw.println();
12929            }
12930        }
12931
12932        if (!printedAnything) {
12933            pw.println("  (nothing)");
12934        }
12935    }
12936
12937    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12938            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12939        if (mProcessesToGc.size() > 0) {
12940            boolean printed = false;
12941            long now = SystemClock.uptimeMillis();
12942            for (int i=0; i<mProcessesToGc.size(); i++) {
12943                ProcessRecord proc = mProcessesToGc.get(i);
12944                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12945                    continue;
12946                }
12947                if (!printed) {
12948                    if (needSep) pw.println();
12949                    needSep = true;
12950                    pw.println("  Processes that are waiting to GC:");
12951                    printed = true;
12952                }
12953                pw.print("    Process "); pw.println(proc);
12954                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12955                        pw.print(", last gced=");
12956                        pw.print(now-proc.lastRequestedGc);
12957                        pw.print(" ms ago, last lowMem=");
12958                        pw.print(now-proc.lastLowMemory);
12959                        pw.println(" ms ago");
12960
12961            }
12962        }
12963        return needSep;
12964    }
12965
12966    void printOomLevel(PrintWriter pw, String name, int adj) {
12967        pw.print("    ");
12968        if (adj >= 0) {
12969            pw.print(' ');
12970            if (adj < 10) pw.print(' ');
12971        } else {
12972            if (adj > -10) pw.print(' ');
12973        }
12974        pw.print(adj);
12975        pw.print(": ");
12976        pw.print(name);
12977        pw.print(" (");
12978        pw.print(mProcessList.getMemLevel(adj)/1024);
12979        pw.println(" kB)");
12980    }
12981
12982    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12983            int opti, boolean dumpAll) {
12984        boolean needSep = false;
12985
12986        if (mLruProcesses.size() > 0) {
12987            if (needSep) pw.println();
12988            needSep = true;
12989            pw.println("  OOM levels:");
12990            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12991            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12992            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12993            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12994            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12995            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12996            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12997            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12998            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12999            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13000            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13001            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13002            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13003            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13004
13005            if (needSep) pw.println();
13006            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13007                    pw.print(" total, non-act at ");
13008                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13009                    pw.print(", non-svc at ");
13010                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13011                    pw.println("):");
13012            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13013            needSep = true;
13014        }
13015
13016        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13017
13018        pw.println();
13019        pw.println("  mHomeProcess: " + mHomeProcess);
13020        pw.println("  mPreviousProcess: " + mPreviousProcess);
13021        if (mHeavyWeightProcess != null) {
13022            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13023        }
13024
13025        return true;
13026    }
13027
13028    /**
13029     * There are three ways to call this:
13030     *  - no provider specified: dump all the providers
13031     *  - a flattened component name that matched an existing provider was specified as the
13032     *    first arg: dump that one provider
13033     *  - the first arg isn't the flattened component name of an existing provider:
13034     *    dump all providers whose component contains the first arg as a substring
13035     */
13036    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13037            int opti, boolean dumpAll) {
13038        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13039    }
13040
13041    static class ItemMatcher {
13042        ArrayList<ComponentName> components;
13043        ArrayList<String> strings;
13044        ArrayList<Integer> objects;
13045        boolean all;
13046
13047        ItemMatcher() {
13048            all = true;
13049        }
13050
13051        void build(String name) {
13052            ComponentName componentName = ComponentName.unflattenFromString(name);
13053            if (componentName != null) {
13054                if (components == null) {
13055                    components = new ArrayList<ComponentName>();
13056                }
13057                components.add(componentName);
13058                all = false;
13059            } else {
13060                int objectId = 0;
13061                // Not a '/' separated full component name; maybe an object ID?
13062                try {
13063                    objectId = Integer.parseInt(name, 16);
13064                    if (objects == null) {
13065                        objects = new ArrayList<Integer>();
13066                    }
13067                    objects.add(objectId);
13068                    all = false;
13069                } catch (RuntimeException e) {
13070                    // Not an integer; just do string match.
13071                    if (strings == null) {
13072                        strings = new ArrayList<String>();
13073                    }
13074                    strings.add(name);
13075                    all = false;
13076                }
13077            }
13078        }
13079
13080        int build(String[] args, int opti) {
13081            for (; opti<args.length; opti++) {
13082                String name = args[opti];
13083                if ("--".equals(name)) {
13084                    return opti+1;
13085                }
13086                build(name);
13087            }
13088            return opti;
13089        }
13090
13091        boolean match(Object object, ComponentName comp) {
13092            if (all) {
13093                return true;
13094            }
13095            if (components != null) {
13096                for (int i=0; i<components.size(); i++) {
13097                    if (components.get(i).equals(comp)) {
13098                        return true;
13099                    }
13100                }
13101            }
13102            if (objects != null) {
13103                for (int i=0; i<objects.size(); i++) {
13104                    if (System.identityHashCode(object) == objects.get(i)) {
13105                        return true;
13106                    }
13107                }
13108            }
13109            if (strings != null) {
13110                String flat = comp.flattenToString();
13111                for (int i=0; i<strings.size(); i++) {
13112                    if (flat.contains(strings.get(i))) {
13113                        return true;
13114                    }
13115                }
13116            }
13117            return false;
13118        }
13119    }
13120
13121    /**
13122     * There are three things that cmd can be:
13123     *  - a flattened component name that matches an existing activity
13124     *  - the cmd arg isn't the flattened component name of an existing activity:
13125     *    dump all activity whose component contains the cmd as a substring
13126     *  - A hex number of the ActivityRecord object instance.
13127     */
13128    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13129            int opti, boolean dumpAll) {
13130        ArrayList<ActivityRecord> activities;
13131
13132        synchronized (this) {
13133            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13134        }
13135
13136        if (activities.size() <= 0) {
13137            return false;
13138        }
13139
13140        String[] newArgs = new String[args.length - opti];
13141        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13142
13143        TaskRecord lastTask = null;
13144        boolean needSep = false;
13145        for (int i=activities.size()-1; i>=0; i--) {
13146            ActivityRecord r = activities.get(i);
13147            if (needSep) {
13148                pw.println();
13149            }
13150            needSep = true;
13151            synchronized (this) {
13152                if (lastTask != r.task) {
13153                    lastTask = r.task;
13154                    pw.print("TASK "); pw.print(lastTask.affinity);
13155                            pw.print(" id="); pw.println(lastTask.taskId);
13156                    if (dumpAll) {
13157                        lastTask.dump(pw, "  ");
13158                    }
13159                }
13160            }
13161            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13162        }
13163        return true;
13164    }
13165
13166    /**
13167     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13168     * there is a thread associated with the activity.
13169     */
13170    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13171            final ActivityRecord r, String[] args, boolean dumpAll) {
13172        String innerPrefix = prefix + "  ";
13173        synchronized (this) {
13174            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13175                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13176                    pw.print(" pid=");
13177                    if (r.app != null) pw.println(r.app.pid);
13178                    else pw.println("(not running)");
13179            if (dumpAll) {
13180                r.dump(pw, innerPrefix);
13181            }
13182        }
13183        if (r.app != null && r.app.thread != null) {
13184            // flush anything that is already in the PrintWriter since the thread is going
13185            // to write to the file descriptor directly
13186            pw.flush();
13187            try {
13188                TransferPipe tp = new TransferPipe();
13189                try {
13190                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13191                            r.appToken, innerPrefix, args);
13192                    tp.go(fd);
13193                } finally {
13194                    tp.kill();
13195                }
13196            } catch (IOException e) {
13197                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13198            } catch (RemoteException e) {
13199                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13200            }
13201        }
13202    }
13203
13204    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13205            int opti, boolean dumpAll, String dumpPackage) {
13206        boolean needSep = false;
13207        boolean onlyHistory = false;
13208        boolean printedAnything = false;
13209
13210        if ("history".equals(dumpPackage)) {
13211            if (opti < args.length && "-s".equals(args[opti])) {
13212                dumpAll = false;
13213            }
13214            onlyHistory = true;
13215            dumpPackage = null;
13216        }
13217
13218        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13219        if (!onlyHistory && dumpAll) {
13220            if (mRegisteredReceivers.size() > 0) {
13221                boolean printed = false;
13222                Iterator it = mRegisteredReceivers.values().iterator();
13223                while (it.hasNext()) {
13224                    ReceiverList r = (ReceiverList)it.next();
13225                    if (dumpPackage != null && (r.app == null ||
13226                            !dumpPackage.equals(r.app.info.packageName))) {
13227                        continue;
13228                    }
13229                    if (!printed) {
13230                        pw.println("  Registered Receivers:");
13231                        needSep = true;
13232                        printed = true;
13233                        printedAnything = true;
13234                    }
13235                    pw.print("  * "); pw.println(r);
13236                    r.dump(pw, "    ");
13237                }
13238            }
13239
13240            if (mReceiverResolver.dump(pw, needSep ?
13241                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13242                    "    ", dumpPackage, false)) {
13243                needSep = true;
13244                printedAnything = true;
13245            }
13246        }
13247
13248        for (BroadcastQueue q : mBroadcastQueues) {
13249            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13250            printedAnything |= needSep;
13251        }
13252
13253        needSep = true;
13254
13255        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13256            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13257                if (needSep) {
13258                    pw.println();
13259                }
13260                needSep = true;
13261                printedAnything = true;
13262                pw.print("  Sticky broadcasts for user ");
13263                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13264                StringBuilder sb = new StringBuilder(128);
13265                for (Map.Entry<String, ArrayList<Intent>> ent
13266                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13267                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13268                    if (dumpAll) {
13269                        pw.println(":");
13270                        ArrayList<Intent> intents = ent.getValue();
13271                        final int N = intents.size();
13272                        for (int i=0; i<N; i++) {
13273                            sb.setLength(0);
13274                            sb.append("    Intent: ");
13275                            intents.get(i).toShortString(sb, false, true, false, false);
13276                            pw.println(sb.toString());
13277                            Bundle bundle = intents.get(i).getExtras();
13278                            if (bundle != null) {
13279                                pw.print("      ");
13280                                pw.println(bundle.toString());
13281                            }
13282                        }
13283                    } else {
13284                        pw.println("");
13285                    }
13286                }
13287            }
13288        }
13289
13290        if (!onlyHistory && dumpAll) {
13291            pw.println();
13292            for (BroadcastQueue queue : mBroadcastQueues) {
13293                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13294                        + queue.mBroadcastsScheduled);
13295            }
13296            pw.println("  mHandler:");
13297            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13298            needSep = true;
13299            printedAnything = true;
13300        }
13301
13302        if (!printedAnything) {
13303            pw.println("  (nothing)");
13304        }
13305    }
13306
13307    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13308            int opti, boolean dumpAll, String dumpPackage) {
13309        boolean needSep;
13310        boolean printedAnything = false;
13311
13312        ItemMatcher matcher = new ItemMatcher();
13313        matcher.build(args, opti);
13314
13315        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13316
13317        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13318        printedAnything |= needSep;
13319
13320        if (mLaunchingProviders.size() > 0) {
13321            boolean printed = false;
13322            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13323                ContentProviderRecord r = mLaunchingProviders.get(i);
13324                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13325                    continue;
13326                }
13327                if (!printed) {
13328                    if (needSep) pw.println();
13329                    needSep = true;
13330                    pw.println("  Launching content providers:");
13331                    printed = true;
13332                    printedAnything = true;
13333                }
13334                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13335                        pw.println(r);
13336            }
13337        }
13338
13339        if (mGrantedUriPermissions.size() > 0) {
13340            boolean printed = false;
13341            int dumpUid = -2;
13342            if (dumpPackage != null) {
13343                try {
13344                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13345                } catch (NameNotFoundException e) {
13346                    dumpUid = -1;
13347                }
13348            }
13349            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13350                int uid = mGrantedUriPermissions.keyAt(i);
13351                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13352                    continue;
13353                }
13354                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13355                if (!printed) {
13356                    if (needSep) pw.println();
13357                    needSep = true;
13358                    pw.println("  Granted Uri Permissions:");
13359                    printed = true;
13360                    printedAnything = true;
13361                }
13362                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13363                for (UriPermission perm : perms.values()) {
13364                    pw.print("    "); pw.println(perm);
13365                    if (dumpAll) {
13366                        perm.dump(pw, "      ");
13367                    }
13368                }
13369            }
13370        }
13371
13372        if (!printedAnything) {
13373            pw.println("  (nothing)");
13374        }
13375    }
13376
13377    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13378            int opti, boolean dumpAll, String dumpPackage) {
13379        boolean printed = false;
13380
13381        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13382
13383        if (mIntentSenderRecords.size() > 0) {
13384            Iterator<WeakReference<PendingIntentRecord>> it
13385                    = mIntentSenderRecords.values().iterator();
13386            while (it.hasNext()) {
13387                WeakReference<PendingIntentRecord> ref = it.next();
13388                PendingIntentRecord rec = ref != null ? ref.get(): null;
13389                if (dumpPackage != null && (rec == null
13390                        || !dumpPackage.equals(rec.key.packageName))) {
13391                    continue;
13392                }
13393                printed = true;
13394                if (rec != null) {
13395                    pw.print("  * "); pw.println(rec);
13396                    if (dumpAll) {
13397                        rec.dump(pw, "    ");
13398                    }
13399                } else {
13400                    pw.print("  * "); pw.println(ref);
13401                }
13402            }
13403        }
13404
13405        if (!printed) {
13406            pw.println("  (nothing)");
13407        }
13408    }
13409
13410    private static final int dumpProcessList(PrintWriter pw,
13411            ActivityManagerService service, List list,
13412            String prefix, String normalLabel, String persistentLabel,
13413            String dumpPackage) {
13414        int numPers = 0;
13415        final int N = list.size()-1;
13416        for (int i=N; i>=0; i--) {
13417            ProcessRecord r = (ProcessRecord)list.get(i);
13418            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13419                continue;
13420            }
13421            pw.println(String.format("%s%s #%2d: %s",
13422                    prefix, (r.persistent ? persistentLabel : normalLabel),
13423                    i, r.toString()));
13424            if (r.persistent) {
13425                numPers++;
13426            }
13427        }
13428        return numPers;
13429    }
13430
13431    private static final boolean dumpProcessOomList(PrintWriter pw,
13432            ActivityManagerService service, List<ProcessRecord> origList,
13433            String prefix, String normalLabel, String persistentLabel,
13434            boolean inclDetails, String dumpPackage) {
13435
13436        ArrayList<Pair<ProcessRecord, Integer>> list
13437                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13438        for (int i=0; i<origList.size(); i++) {
13439            ProcessRecord r = origList.get(i);
13440            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13441                continue;
13442            }
13443            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13444        }
13445
13446        if (list.size() <= 0) {
13447            return false;
13448        }
13449
13450        Comparator<Pair<ProcessRecord, Integer>> comparator
13451                = new Comparator<Pair<ProcessRecord, Integer>>() {
13452            @Override
13453            public int compare(Pair<ProcessRecord, Integer> object1,
13454                    Pair<ProcessRecord, Integer> object2) {
13455                if (object1.first.setAdj != object2.first.setAdj) {
13456                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13457                }
13458                if (object1.second.intValue() != object2.second.intValue()) {
13459                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13460                }
13461                return 0;
13462            }
13463        };
13464
13465        Collections.sort(list, comparator);
13466
13467        final long curRealtime = SystemClock.elapsedRealtime();
13468        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13469        final long curUptime = SystemClock.uptimeMillis();
13470        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13471
13472        for (int i=list.size()-1; i>=0; i--) {
13473            ProcessRecord r = list.get(i).first;
13474            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13475            char schedGroup;
13476            switch (r.setSchedGroup) {
13477                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13478                    schedGroup = 'B';
13479                    break;
13480                case Process.THREAD_GROUP_DEFAULT:
13481                    schedGroup = 'F';
13482                    break;
13483                default:
13484                    schedGroup = '?';
13485                    break;
13486            }
13487            char foreground;
13488            if (r.foregroundActivities) {
13489                foreground = 'A';
13490            } else if (r.foregroundServices) {
13491                foreground = 'S';
13492            } else {
13493                foreground = ' ';
13494            }
13495            String procState = ProcessList.makeProcStateString(r.curProcState);
13496            pw.print(prefix);
13497            pw.print(r.persistent ? persistentLabel : normalLabel);
13498            pw.print(" #");
13499            int num = (origList.size()-1)-list.get(i).second;
13500            if (num < 10) pw.print(' ');
13501            pw.print(num);
13502            pw.print(": ");
13503            pw.print(oomAdj);
13504            pw.print(' ');
13505            pw.print(schedGroup);
13506            pw.print('/');
13507            pw.print(foreground);
13508            pw.print('/');
13509            pw.print(procState);
13510            pw.print(" trm:");
13511            if (r.trimMemoryLevel < 10) pw.print(' ');
13512            pw.print(r.trimMemoryLevel);
13513            pw.print(' ');
13514            pw.print(r.toShortString());
13515            pw.print(" (");
13516            pw.print(r.adjType);
13517            pw.println(')');
13518            if (r.adjSource != null || r.adjTarget != null) {
13519                pw.print(prefix);
13520                pw.print("    ");
13521                if (r.adjTarget instanceof ComponentName) {
13522                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13523                } else if (r.adjTarget != null) {
13524                    pw.print(r.adjTarget.toString());
13525                } else {
13526                    pw.print("{null}");
13527                }
13528                pw.print("<=");
13529                if (r.adjSource instanceof ProcessRecord) {
13530                    pw.print("Proc{");
13531                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13532                    pw.println("}");
13533                } else if (r.adjSource != null) {
13534                    pw.println(r.adjSource.toString());
13535                } else {
13536                    pw.println("{null}");
13537                }
13538            }
13539            if (inclDetails) {
13540                pw.print(prefix);
13541                pw.print("    ");
13542                pw.print("oom: max="); pw.print(r.maxAdj);
13543                pw.print(" curRaw="); pw.print(r.curRawAdj);
13544                pw.print(" setRaw="); pw.print(r.setRawAdj);
13545                pw.print(" cur="); pw.print(r.curAdj);
13546                pw.print(" set="); pw.println(r.setAdj);
13547                pw.print(prefix);
13548                pw.print("    ");
13549                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13550                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13551                pw.print(" lastPss="); pw.print(r.lastPss);
13552                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13553                pw.print(prefix);
13554                pw.print("    ");
13555                pw.print("cached="); pw.print(r.cached);
13556                pw.print(" empty="); pw.print(r.empty);
13557                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13558
13559                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13560                    if (r.lastWakeTime != 0) {
13561                        long wtime;
13562                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13563                        synchronized (stats) {
13564                            wtime = stats.getProcessWakeTime(r.info.uid,
13565                                    r.pid, curRealtime);
13566                        }
13567                        long timeUsed = wtime - r.lastWakeTime;
13568                        pw.print(prefix);
13569                        pw.print("    ");
13570                        pw.print("keep awake over ");
13571                        TimeUtils.formatDuration(realtimeSince, pw);
13572                        pw.print(" used ");
13573                        TimeUtils.formatDuration(timeUsed, pw);
13574                        pw.print(" (");
13575                        pw.print((timeUsed*100)/realtimeSince);
13576                        pw.println("%)");
13577                    }
13578                    if (r.lastCpuTime != 0) {
13579                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13580                        pw.print(prefix);
13581                        pw.print("    ");
13582                        pw.print("run cpu over ");
13583                        TimeUtils.formatDuration(uptimeSince, pw);
13584                        pw.print(" used ");
13585                        TimeUtils.formatDuration(timeUsed, pw);
13586                        pw.print(" (");
13587                        pw.print((timeUsed*100)/uptimeSince);
13588                        pw.println("%)");
13589                    }
13590                }
13591            }
13592        }
13593        return true;
13594    }
13595
13596    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13597            String[] args) {
13598        ArrayList<ProcessRecord> procs;
13599        synchronized (this) {
13600            if (args != null && args.length > start
13601                    && args[start].charAt(0) != '-') {
13602                procs = new ArrayList<ProcessRecord>();
13603                int pid = -1;
13604                try {
13605                    pid = Integer.parseInt(args[start]);
13606                } catch (NumberFormatException e) {
13607                }
13608                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13609                    ProcessRecord proc = mLruProcesses.get(i);
13610                    if (proc.pid == pid) {
13611                        procs.add(proc);
13612                    } else if (allPkgs && proc.pkgList != null
13613                            && proc.pkgList.containsKey(args[start])) {
13614                        procs.add(proc);
13615                    } else if (proc.processName.equals(args[start])) {
13616                        procs.add(proc);
13617                    }
13618                }
13619                if (procs.size() <= 0) {
13620                    return null;
13621                }
13622            } else {
13623                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13624            }
13625        }
13626        return procs;
13627    }
13628
13629    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13630            PrintWriter pw, String[] args) {
13631        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13632        if (procs == null) {
13633            pw.println("No process found for: " + args[0]);
13634            return;
13635        }
13636
13637        long uptime = SystemClock.uptimeMillis();
13638        long realtime = SystemClock.elapsedRealtime();
13639        pw.println("Applications Graphics Acceleration Info:");
13640        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13641
13642        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13643            ProcessRecord r = procs.get(i);
13644            if (r.thread != null) {
13645                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13646                pw.flush();
13647                try {
13648                    TransferPipe tp = new TransferPipe();
13649                    try {
13650                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13651                        tp.go(fd);
13652                    } finally {
13653                        tp.kill();
13654                    }
13655                } catch (IOException e) {
13656                    pw.println("Failure while dumping the app: " + r);
13657                    pw.flush();
13658                } catch (RemoteException e) {
13659                    pw.println("Got a RemoteException while dumping the app " + r);
13660                    pw.flush();
13661                }
13662            }
13663        }
13664    }
13665
13666    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13667        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13668        if (procs == null) {
13669            pw.println("No process found for: " + args[0]);
13670            return;
13671        }
13672
13673        pw.println("Applications Database Info:");
13674
13675        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13676            ProcessRecord r = procs.get(i);
13677            if (r.thread != null) {
13678                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13679                pw.flush();
13680                try {
13681                    TransferPipe tp = new TransferPipe();
13682                    try {
13683                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13684                        tp.go(fd);
13685                    } finally {
13686                        tp.kill();
13687                    }
13688                } catch (IOException e) {
13689                    pw.println("Failure while dumping the app: " + r);
13690                    pw.flush();
13691                } catch (RemoteException e) {
13692                    pw.println("Got a RemoteException while dumping the app " + r);
13693                    pw.flush();
13694                }
13695            }
13696        }
13697    }
13698
13699    final static class MemItem {
13700        final boolean isProc;
13701        final String label;
13702        final String shortLabel;
13703        final long pss;
13704        final int id;
13705        final boolean hasActivities;
13706        ArrayList<MemItem> subitems;
13707
13708        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13709                boolean _hasActivities) {
13710            isProc = true;
13711            label = _label;
13712            shortLabel = _shortLabel;
13713            pss = _pss;
13714            id = _id;
13715            hasActivities = _hasActivities;
13716        }
13717
13718        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13719            isProc = false;
13720            label = _label;
13721            shortLabel = _shortLabel;
13722            pss = _pss;
13723            id = _id;
13724            hasActivities = false;
13725        }
13726    }
13727
13728    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13729            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13730        if (sort && !isCompact) {
13731            Collections.sort(items, new Comparator<MemItem>() {
13732                @Override
13733                public int compare(MemItem lhs, MemItem rhs) {
13734                    if (lhs.pss < rhs.pss) {
13735                        return 1;
13736                    } else if (lhs.pss > rhs.pss) {
13737                        return -1;
13738                    }
13739                    return 0;
13740                }
13741            });
13742        }
13743
13744        for (int i=0; i<items.size(); i++) {
13745            MemItem mi = items.get(i);
13746            if (!isCompact) {
13747                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13748            } else if (mi.isProc) {
13749                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13750                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13751                pw.println(mi.hasActivities ? ",a" : ",e");
13752            } else {
13753                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13754                pw.println(mi.pss);
13755            }
13756            if (mi.subitems != null) {
13757                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13758                        true, isCompact);
13759            }
13760        }
13761    }
13762
13763    // These are in KB.
13764    static final long[] DUMP_MEM_BUCKETS = new long[] {
13765        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13766        120*1024, 160*1024, 200*1024,
13767        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13768        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13769    };
13770
13771    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13772            boolean stackLike) {
13773        int start = label.lastIndexOf('.');
13774        if (start >= 0) start++;
13775        else start = 0;
13776        int end = label.length();
13777        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13778            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13779                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13780                out.append(bucket);
13781                out.append(stackLike ? "MB." : "MB ");
13782                out.append(label, start, end);
13783                return;
13784            }
13785        }
13786        out.append(memKB/1024);
13787        out.append(stackLike ? "MB." : "MB ");
13788        out.append(label, start, end);
13789    }
13790
13791    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13792            ProcessList.NATIVE_ADJ,
13793            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13794            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13795            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13796            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13797            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13798            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13799    };
13800    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13801            "Native",
13802            "System", "Persistent", "Persistent Service", "Foreground",
13803            "Visible", "Perceptible",
13804            "Heavy Weight", "Backup",
13805            "A Services", "Home",
13806            "Previous", "B Services", "Cached"
13807    };
13808    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13809            "native",
13810            "sys", "pers", "persvc", "fore",
13811            "vis", "percept",
13812            "heavy", "backup",
13813            "servicea", "home",
13814            "prev", "serviceb", "cached"
13815    };
13816
13817    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13818            long realtime, boolean isCheckinRequest, boolean isCompact) {
13819        if (isCheckinRequest || isCompact) {
13820            // short checkin version
13821            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13822        } else {
13823            pw.println("Applications Memory Usage (kB):");
13824            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13825        }
13826    }
13827
13828    private static final int KSM_SHARED = 0;
13829    private static final int KSM_SHARING = 1;
13830    private static final int KSM_UNSHARED = 2;
13831    private static final int KSM_VOLATILE = 3;
13832
13833    private final long[] getKsmInfo() {
13834        long[] longOut = new long[4];
13835        final int[] SINGLE_LONG_FORMAT = new int[] {
13836            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13837        };
13838        long[] longTmp = new long[1];
13839        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13840                SINGLE_LONG_FORMAT, null, longTmp, null);
13841        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13842        longTmp[0] = 0;
13843        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13844                SINGLE_LONG_FORMAT, null, longTmp, null);
13845        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13846        longTmp[0] = 0;
13847        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13848                SINGLE_LONG_FORMAT, null, longTmp, null);
13849        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13850        longTmp[0] = 0;
13851        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13852                SINGLE_LONG_FORMAT, null, longTmp, null);
13853        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13854        return longOut;
13855    }
13856
13857    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13858            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13859        boolean dumpDetails = false;
13860        boolean dumpFullDetails = false;
13861        boolean dumpDalvik = false;
13862        boolean oomOnly = false;
13863        boolean isCompact = false;
13864        boolean localOnly = false;
13865        boolean packages = false;
13866
13867        int opti = 0;
13868        while (opti < args.length) {
13869            String opt = args[opti];
13870            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13871                break;
13872            }
13873            opti++;
13874            if ("-a".equals(opt)) {
13875                dumpDetails = true;
13876                dumpFullDetails = true;
13877                dumpDalvik = true;
13878            } else if ("-d".equals(opt)) {
13879                dumpDalvik = true;
13880            } else if ("-c".equals(opt)) {
13881                isCompact = true;
13882            } else if ("--oom".equals(opt)) {
13883                oomOnly = true;
13884            } else if ("--local".equals(opt)) {
13885                localOnly = true;
13886            } else if ("--package".equals(opt)) {
13887                packages = true;
13888            } else if ("-h".equals(opt)) {
13889                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13890                pw.println("  -a: include all available information for each process.");
13891                pw.println("  -d: include dalvik details when dumping process details.");
13892                pw.println("  -c: dump in a compact machine-parseable representation.");
13893                pw.println("  --oom: only show processes organized by oom adj.");
13894                pw.println("  --local: only collect details locally, don't call process.");
13895                pw.println("  --package: interpret process arg as package, dumping all");
13896                pw.println("             processes that have loaded that package.");
13897                pw.println("If [process] is specified it can be the name or ");
13898                pw.println("pid of a specific process to dump.");
13899                return;
13900            } else {
13901                pw.println("Unknown argument: " + opt + "; use -h for help");
13902            }
13903        }
13904
13905        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13906        long uptime = SystemClock.uptimeMillis();
13907        long realtime = SystemClock.elapsedRealtime();
13908        final long[] tmpLong = new long[1];
13909
13910        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13911        if (procs == null) {
13912            // No Java processes.  Maybe they want to print a native process.
13913            if (args != null && args.length > opti
13914                    && args[opti].charAt(0) != '-') {
13915                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13916                        = new ArrayList<ProcessCpuTracker.Stats>();
13917                updateCpuStatsNow();
13918                int findPid = -1;
13919                try {
13920                    findPid = Integer.parseInt(args[opti]);
13921                } catch (NumberFormatException e) {
13922                }
13923                synchronized (mProcessCpuTracker) {
13924                    final int N = mProcessCpuTracker.countStats();
13925                    for (int i=0; i<N; i++) {
13926                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13927                        if (st.pid == findPid || (st.baseName != null
13928                                && st.baseName.equals(args[opti]))) {
13929                            nativeProcs.add(st);
13930                        }
13931                    }
13932                }
13933                if (nativeProcs.size() > 0) {
13934                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13935                            isCompact);
13936                    Debug.MemoryInfo mi = null;
13937                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13938                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13939                        final int pid = r.pid;
13940                        if (!isCheckinRequest && dumpDetails) {
13941                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13942                        }
13943                        if (mi == null) {
13944                            mi = new Debug.MemoryInfo();
13945                        }
13946                        if (dumpDetails || (!brief && !oomOnly)) {
13947                            Debug.getMemoryInfo(pid, mi);
13948                        } else {
13949                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13950                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13951                        }
13952                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13953                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13954                        if (isCheckinRequest) {
13955                            pw.println();
13956                        }
13957                    }
13958                    return;
13959                }
13960            }
13961            pw.println("No process found for: " + args[opti]);
13962            return;
13963        }
13964
13965        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13966            dumpDetails = true;
13967        }
13968
13969        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13970
13971        String[] innerArgs = new String[args.length-opti];
13972        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13973
13974        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13975        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13976        long nativePss = 0;
13977        long dalvikPss = 0;
13978        long otherPss = 0;
13979        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13980
13981        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13982        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13983                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13984
13985        long totalPss = 0;
13986        long cachedPss = 0;
13987
13988        Debug.MemoryInfo mi = null;
13989        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13990            final ProcessRecord r = procs.get(i);
13991            final IApplicationThread thread;
13992            final int pid;
13993            final int oomAdj;
13994            final boolean hasActivities;
13995            synchronized (this) {
13996                thread = r.thread;
13997                pid = r.pid;
13998                oomAdj = r.getSetAdjWithServices();
13999                hasActivities = r.activities.size() > 0;
14000            }
14001            if (thread != null) {
14002                if (!isCheckinRequest && dumpDetails) {
14003                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14004                }
14005                if (mi == null) {
14006                    mi = new Debug.MemoryInfo();
14007                }
14008                if (dumpDetails || (!brief && !oomOnly)) {
14009                    Debug.getMemoryInfo(pid, mi);
14010                } else {
14011                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14012                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14013                }
14014                if (dumpDetails) {
14015                    if (localOnly) {
14016                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14017                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14018                        if (isCheckinRequest) {
14019                            pw.println();
14020                        }
14021                    } else {
14022                        try {
14023                            pw.flush();
14024                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14025                                    dumpDalvik, innerArgs);
14026                        } catch (RemoteException e) {
14027                            if (!isCheckinRequest) {
14028                                pw.println("Got RemoteException!");
14029                                pw.flush();
14030                            }
14031                        }
14032                    }
14033                }
14034
14035                final long myTotalPss = mi.getTotalPss();
14036                final long myTotalUss = mi.getTotalUss();
14037
14038                synchronized (this) {
14039                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14040                        // Record this for posterity if the process has been stable.
14041                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14042                    }
14043                }
14044
14045                if (!isCheckinRequest && mi != null) {
14046                    totalPss += myTotalPss;
14047                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14048                            (hasActivities ? " / activities)" : ")"),
14049                            r.processName, myTotalPss, pid, hasActivities);
14050                    procMems.add(pssItem);
14051                    procMemsMap.put(pid, pssItem);
14052
14053                    nativePss += mi.nativePss;
14054                    dalvikPss += mi.dalvikPss;
14055                    otherPss += mi.otherPss;
14056                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14057                        long mem = mi.getOtherPss(j);
14058                        miscPss[j] += mem;
14059                        otherPss -= mem;
14060                    }
14061
14062                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14063                        cachedPss += myTotalPss;
14064                    }
14065
14066                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14067                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14068                                || oomIndex == (oomPss.length-1)) {
14069                            oomPss[oomIndex] += myTotalPss;
14070                            if (oomProcs[oomIndex] == null) {
14071                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14072                            }
14073                            oomProcs[oomIndex].add(pssItem);
14074                            break;
14075                        }
14076                    }
14077                }
14078            }
14079        }
14080
14081        long nativeProcTotalPss = 0;
14082
14083        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14084            // If we are showing aggregations, also look for native processes to
14085            // include so that our aggregations are more accurate.
14086            updateCpuStatsNow();
14087            synchronized (mProcessCpuTracker) {
14088                final int N = mProcessCpuTracker.countStats();
14089                for (int i=0; i<N; i++) {
14090                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14091                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14092                        if (mi == null) {
14093                            mi = new Debug.MemoryInfo();
14094                        }
14095                        if (!brief && !oomOnly) {
14096                            Debug.getMemoryInfo(st.pid, mi);
14097                        } else {
14098                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14099                            mi.nativePrivateDirty = (int)tmpLong[0];
14100                        }
14101
14102                        final long myTotalPss = mi.getTotalPss();
14103                        totalPss += myTotalPss;
14104                        nativeProcTotalPss += myTotalPss;
14105
14106                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14107                                st.name, myTotalPss, st.pid, false);
14108                        procMems.add(pssItem);
14109
14110                        nativePss += mi.nativePss;
14111                        dalvikPss += mi.dalvikPss;
14112                        otherPss += mi.otherPss;
14113                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14114                            long mem = mi.getOtherPss(j);
14115                            miscPss[j] += mem;
14116                            otherPss -= mem;
14117                        }
14118                        oomPss[0] += myTotalPss;
14119                        if (oomProcs[0] == null) {
14120                            oomProcs[0] = new ArrayList<MemItem>();
14121                        }
14122                        oomProcs[0].add(pssItem);
14123                    }
14124                }
14125            }
14126
14127            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14128
14129            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14130            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14131            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14132            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14133                String label = Debug.MemoryInfo.getOtherLabel(j);
14134                catMems.add(new MemItem(label, label, miscPss[j], j));
14135            }
14136
14137            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14138            for (int j=0; j<oomPss.length; j++) {
14139                if (oomPss[j] != 0) {
14140                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14141                            : DUMP_MEM_OOM_LABEL[j];
14142                    MemItem item = new MemItem(label, label, oomPss[j],
14143                            DUMP_MEM_OOM_ADJ[j]);
14144                    item.subitems = oomProcs[j];
14145                    oomMems.add(item);
14146                }
14147            }
14148
14149            if (!brief && !oomOnly && !isCompact) {
14150                pw.println();
14151                pw.println("Total PSS by process:");
14152                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14153                pw.println();
14154            }
14155            if (!isCompact) {
14156                pw.println("Total PSS by OOM adjustment:");
14157            }
14158            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14159            if (!brief && !oomOnly) {
14160                PrintWriter out = categoryPw != null ? categoryPw : pw;
14161                if (!isCompact) {
14162                    out.println();
14163                    out.println("Total PSS by category:");
14164                }
14165                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14166            }
14167            if (!isCompact) {
14168                pw.println();
14169            }
14170            MemInfoReader memInfo = new MemInfoReader();
14171            memInfo.readMemInfo();
14172            if (nativeProcTotalPss > 0) {
14173                synchronized (this) {
14174                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14175                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14176                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14177                }
14178            }
14179            if (!brief) {
14180                if (!isCompact) {
14181                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14182                    pw.print(" kB (status ");
14183                    switch (mLastMemoryLevel) {
14184                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14185                            pw.println("normal)");
14186                            break;
14187                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14188                            pw.println("moderate)");
14189                            break;
14190                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14191                            pw.println("low)");
14192                            break;
14193                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14194                            pw.println("critical)");
14195                            break;
14196                        default:
14197                            pw.print(mLastMemoryLevel);
14198                            pw.println(")");
14199                            break;
14200                    }
14201                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14202                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14203                            pw.print(cachedPss); pw.print(" cached pss + ");
14204                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14205                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14206                } else {
14207                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14208                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14209                            + memInfo.getFreeSizeKb()); pw.print(",");
14210                    pw.println(totalPss - cachedPss);
14211                }
14212            }
14213            if (!isCompact) {
14214                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14215                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14216                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14217                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14218                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14219                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14220                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14221            }
14222            if (!brief) {
14223                if (memInfo.getZramTotalSizeKb() != 0) {
14224                    if (!isCompact) {
14225                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14226                                pw.print(" kB physical used for ");
14227                                pw.print(memInfo.getSwapTotalSizeKb()
14228                                        - memInfo.getSwapFreeSizeKb());
14229                                pw.print(" kB in swap (");
14230                                pw.print(memInfo.getSwapTotalSizeKb());
14231                                pw.println(" kB total swap)");
14232                    } else {
14233                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14234                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14235                                pw.println(memInfo.getSwapFreeSizeKb());
14236                    }
14237                }
14238                final long[] ksm = getKsmInfo();
14239                if (!isCompact) {
14240                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14241                            || ksm[KSM_VOLATILE] != 0) {
14242                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14243                                pw.print(" kB saved from shared ");
14244                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14245                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14246                                pw.print(" kB unshared; ");
14247                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14248                    }
14249                    pw.print("   Tuning: ");
14250                    pw.print(ActivityManager.staticGetMemoryClass());
14251                    pw.print(" (large ");
14252                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14253                    pw.print("), oom ");
14254                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14255                    pw.print(" kB");
14256                    pw.print(", restore limit ");
14257                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14258                    pw.print(" kB");
14259                    if (ActivityManager.isLowRamDeviceStatic()) {
14260                        pw.print(" (low-ram)");
14261                    }
14262                    if (ActivityManager.isHighEndGfx()) {
14263                        pw.print(" (high-end-gfx)");
14264                    }
14265                    pw.println();
14266                } else {
14267                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14268                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14269                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14270                    pw.print("tuning,");
14271                    pw.print(ActivityManager.staticGetMemoryClass());
14272                    pw.print(',');
14273                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14274                    pw.print(',');
14275                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14276                    if (ActivityManager.isLowRamDeviceStatic()) {
14277                        pw.print(",low-ram");
14278                    }
14279                    if (ActivityManager.isHighEndGfx()) {
14280                        pw.print(",high-end-gfx");
14281                    }
14282                    pw.println();
14283                }
14284            }
14285        }
14286    }
14287
14288    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14289            String name) {
14290        sb.append("  ");
14291        sb.append(ProcessList.makeOomAdjString(oomAdj));
14292        sb.append(' ');
14293        sb.append(ProcessList.makeProcStateString(procState));
14294        sb.append(' ');
14295        ProcessList.appendRamKb(sb, pss);
14296        sb.append(" kB: ");
14297        sb.append(name);
14298    }
14299
14300    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14301        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14302        sb.append(" (");
14303        sb.append(mi.pid);
14304        sb.append(") ");
14305        sb.append(mi.adjType);
14306        sb.append('\n');
14307        if (mi.adjReason != null) {
14308            sb.append("                      ");
14309            sb.append(mi.adjReason);
14310            sb.append('\n');
14311        }
14312    }
14313
14314    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14315        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14316        for (int i=0, N=memInfos.size(); i<N; i++) {
14317            ProcessMemInfo mi = memInfos.get(i);
14318            infoMap.put(mi.pid, mi);
14319        }
14320        updateCpuStatsNow();
14321        synchronized (mProcessCpuTracker) {
14322            final int N = mProcessCpuTracker.countStats();
14323            for (int i=0; i<N; i++) {
14324                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14325                if (st.vsize > 0) {
14326                    long pss = Debug.getPss(st.pid, null);
14327                    if (pss > 0) {
14328                        if (infoMap.indexOfKey(st.pid) < 0) {
14329                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14330                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14331                            mi.pss = pss;
14332                            memInfos.add(mi);
14333                        }
14334                    }
14335                }
14336            }
14337        }
14338
14339        long totalPss = 0;
14340        for (int i=0, N=memInfos.size(); i<N; i++) {
14341            ProcessMemInfo mi = memInfos.get(i);
14342            if (mi.pss == 0) {
14343                mi.pss = Debug.getPss(mi.pid, null);
14344            }
14345            totalPss += mi.pss;
14346        }
14347        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14348            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14349                if (lhs.oomAdj != rhs.oomAdj) {
14350                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14351                }
14352                if (lhs.pss != rhs.pss) {
14353                    return lhs.pss < rhs.pss ? 1 : -1;
14354                }
14355                return 0;
14356            }
14357        });
14358
14359        StringBuilder tag = new StringBuilder(128);
14360        StringBuilder stack = new StringBuilder(128);
14361        tag.append("Low on memory -- ");
14362        appendMemBucket(tag, totalPss, "total", false);
14363        appendMemBucket(stack, totalPss, "total", true);
14364
14365        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14366        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14367        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14368
14369        boolean firstLine = true;
14370        int lastOomAdj = Integer.MIN_VALUE;
14371        long extraNativeRam = 0;
14372        long cachedPss = 0;
14373        for (int i=0, N=memInfos.size(); i<N; i++) {
14374            ProcessMemInfo mi = memInfos.get(i);
14375
14376            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14377                cachedPss += mi.pss;
14378            }
14379
14380            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14381                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14382                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14383                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14384                if (lastOomAdj != mi.oomAdj) {
14385                    lastOomAdj = mi.oomAdj;
14386                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14387                        tag.append(" / ");
14388                    }
14389                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14390                        if (firstLine) {
14391                            stack.append(":");
14392                            firstLine = false;
14393                        }
14394                        stack.append("\n\t at ");
14395                    } else {
14396                        stack.append("$");
14397                    }
14398                } else {
14399                    tag.append(" ");
14400                    stack.append("$");
14401                }
14402                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14403                    appendMemBucket(tag, mi.pss, mi.name, false);
14404                }
14405                appendMemBucket(stack, mi.pss, mi.name, true);
14406                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14407                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14408                    stack.append("(");
14409                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14410                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14411                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14412                            stack.append(":");
14413                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14414                        }
14415                    }
14416                    stack.append(")");
14417                }
14418            }
14419
14420            appendMemInfo(fullNativeBuilder, mi);
14421            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14422                // The short form only has native processes that are >= 1MB.
14423                if (mi.pss >= 1000) {
14424                    appendMemInfo(shortNativeBuilder, mi);
14425                } else {
14426                    extraNativeRam += mi.pss;
14427                }
14428            } else {
14429                // Short form has all other details, but if we have collected RAM
14430                // from smaller native processes let's dump a summary of that.
14431                if (extraNativeRam > 0) {
14432                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14433                            -1, extraNativeRam, "(Other native)");
14434                    shortNativeBuilder.append('\n');
14435                    extraNativeRam = 0;
14436                }
14437                appendMemInfo(fullJavaBuilder, mi);
14438            }
14439        }
14440
14441        fullJavaBuilder.append("           ");
14442        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14443        fullJavaBuilder.append(" kB: TOTAL\n");
14444
14445        MemInfoReader memInfo = new MemInfoReader();
14446        memInfo.readMemInfo();
14447        final long[] infos = memInfo.getRawInfo();
14448
14449        StringBuilder memInfoBuilder = new StringBuilder(1024);
14450        Debug.getMemInfo(infos);
14451        memInfoBuilder.append("  MemInfo: ");
14452        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14453        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14454        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14455        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14456        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14457        memInfoBuilder.append("           ");
14458        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14459        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14460        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14461        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14462        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14463            memInfoBuilder.append("  ZRAM: ");
14464            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14465            memInfoBuilder.append(" kB RAM, ");
14466            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14467            memInfoBuilder.append(" kB swap total, ");
14468            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14469            memInfoBuilder.append(" kB swap free\n");
14470        }
14471        final long[] ksm = getKsmInfo();
14472        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14473                || ksm[KSM_VOLATILE] != 0) {
14474            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14475            memInfoBuilder.append(" kB saved from shared ");
14476            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14477            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14478            memInfoBuilder.append(" kB unshared; ");
14479            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14480        }
14481        memInfoBuilder.append("  Free RAM: ");
14482        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14483                + memInfo.getFreeSizeKb());
14484        memInfoBuilder.append(" kB\n");
14485        memInfoBuilder.append("  Used RAM: ");
14486        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14487        memInfoBuilder.append(" kB\n");
14488        memInfoBuilder.append("  Lost RAM: ");
14489        memInfoBuilder.append(memInfo.getTotalSizeKb()
14490                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14491                - memInfo.getKernelUsedSizeKb());
14492        memInfoBuilder.append(" kB\n");
14493        Slog.i(TAG, "Low on memory:");
14494        Slog.i(TAG, shortNativeBuilder.toString());
14495        Slog.i(TAG, fullJavaBuilder.toString());
14496        Slog.i(TAG, memInfoBuilder.toString());
14497
14498        StringBuilder dropBuilder = new StringBuilder(1024);
14499        /*
14500        StringWriter oomSw = new StringWriter();
14501        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14502        StringWriter catSw = new StringWriter();
14503        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14504        String[] emptyArgs = new String[] { };
14505        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14506        oomPw.flush();
14507        String oomString = oomSw.toString();
14508        */
14509        dropBuilder.append("Low on memory:");
14510        dropBuilder.append(stack);
14511        dropBuilder.append('\n');
14512        dropBuilder.append(fullNativeBuilder);
14513        dropBuilder.append(fullJavaBuilder);
14514        dropBuilder.append('\n');
14515        dropBuilder.append(memInfoBuilder);
14516        dropBuilder.append('\n');
14517        /*
14518        dropBuilder.append(oomString);
14519        dropBuilder.append('\n');
14520        */
14521        StringWriter catSw = new StringWriter();
14522        synchronized (ActivityManagerService.this) {
14523            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14524            String[] emptyArgs = new String[] { };
14525            catPw.println();
14526            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14527            catPw.println();
14528            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14529                    false, false, null);
14530            catPw.println();
14531            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14532            catPw.flush();
14533        }
14534        dropBuilder.append(catSw.toString());
14535        addErrorToDropBox("lowmem", null, "system_server", null,
14536                null, tag.toString(), dropBuilder.toString(), null, null);
14537        //Slog.i(TAG, "Sent to dropbox:");
14538        //Slog.i(TAG, dropBuilder.toString());
14539        synchronized (ActivityManagerService.this) {
14540            long now = SystemClock.uptimeMillis();
14541            if (mLastMemUsageReportTime < now) {
14542                mLastMemUsageReportTime = now;
14543            }
14544        }
14545    }
14546
14547    /**
14548     * Searches array of arguments for the specified string
14549     * @param args array of argument strings
14550     * @param value value to search for
14551     * @return true if the value is contained in the array
14552     */
14553    private static boolean scanArgs(String[] args, String value) {
14554        if (args != null) {
14555            for (String arg : args) {
14556                if (value.equals(arg)) {
14557                    return true;
14558                }
14559            }
14560        }
14561        return false;
14562    }
14563
14564    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14565            ContentProviderRecord cpr, boolean always) {
14566        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14567
14568        if (!inLaunching || always) {
14569            synchronized (cpr) {
14570                cpr.launchingApp = null;
14571                cpr.notifyAll();
14572            }
14573            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14574            String names[] = cpr.info.authority.split(";");
14575            for (int j = 0; j < names.length; j++) {
14576                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14577            }
14578        }
14579
14580        for (int i=0; i<cpr.connections.size(); i++) {
14581            ContentProviderConnection conn = cpr.connections.get(i);
14582            if (conn.waiting) {
14583                // If this connection is waiting for the provider, then we don't
14584                // need to mess with its process unless we are always removing
14585                // or for some reason the provider is not currently launching.
14586                if (inLaunching && !always) {
14587                    continue;
14588                }
14589            }
14590            ProcessRecord capp = conn.client;
14591            conn.dead = true;
14592            if (conn.stableCount > 0) {
14593                if (!capp.persistent && capp.thread != null
14594                        && capp.pid != 0
14595                        && capp.pid != MY_PID) {
14596                    capp.kill("depends on provider "
14597                            + cpr.name.flattenToShortString()
14598                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14599                }
14600            } else if (capp.thread != null && conn.provider.provider != null) {
14601                try {
14602                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14603                } catch (RemoteException e) {
14604                }
14605                // In the protocol here, we don't expect the client to correctly
14606                // clean up this connection, we'll just remove it.
14607                cpr.connections.remove(i);
14608                conn.client.conProviders.remove(conn);
14609            }
14610        }
14611
14612        if (inLaunching && always) {
14613            mLaunchingProviders.remove(cpr);
14614        }
14615        return inLaunching;
14616    }
14617
14618    /**
14619     * Main code for cleaning up a process when it has gone away.  This is
14620     * called both as a result of the process dying, or directly when stopping
14621     * a process when running in single process mode.
14622     *
14623     * @return Returns true if the given process has been restarted, so the
14624     * app that was passed in must remain on the process lists.
14625     */
14626    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14627            boolean restarting, boolean allowRestart, int index) {
14628        if (index >= 0) {
14629            removeLruProcessLocked(app);
14630            ProcessList.remove(app.pid);
14631        }
14632
14633        mProcessesToGc.remove(app);
14634        mPendingPssProcesses.remove(app);
14635
14636        // Dismiss any open dialogs.
14637        if (app.crashDialog != null && !app.forceCrashReport) {
14638            app.crashDialog.dismiss();
14639            app.crashDialog = null;
14640        }
14641        if (app.anrDialog != null) {
14642            app.anrDialog.dismiss();
14643            app.anrDialog = null;
14644        }
14645        if (app.waitDialog != null) {
14646            app.waitDialog.dismiss();
14647            app.waitDialog = null;
14648        }
14649
14650        app.crashing = false;
14651        app.notResponding = false;
14652
14653        app.resetPackageList(mProcessStats);
14654        app.unlinkDeathRecipient();
14655        app.makeInactive(mProcessStats);
14656        app.waitingToKill = null;
14657        app.forcingToForeground = null;
14658        updateProcessForegroundLocked(app, false, false);
14659        app.foregroundActivities = false;
14660        app.hasShownUi = false;
14661        app.treatLikeActivity = false;
14662        app.hasAboveClient = false;
14663        app.hasClientActivities = false;
14664
14665        mServices.killServicesLocked(app, allowRestart);
14666
14667        boolean restart = false;
14668
14669        // Remove published content providers.
14670        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14671            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14672            final boolean always = app.bad || !allowRestart;
14673            if (removeDyingProviderLocked(app, cpr, always) || always) {
14674                // We left the provider in the launching list, need to
14675                // restart it.
14676                restart = true;
14677            }
14678
14679            cpr.provider = null;
14680            cpr.proc = null;
14681        }
14682        app.pubProviders.clear();
14683
14684        // Take care of any launching providers waiting for this process.
14685        if (checkAppInLaunchingProvidersLocked(app, false)) {
14686            restart = true;
14687        }
14688
14689        // Unregister from connected content providers.
14690        if (!app.conProviders.isEmpty()) {
14691            for (int i=0; i<app.conProviders.size(); i++) {
14692                ContentProviderConnection conn = app.conProviders.get(i);
14693                conn.provider.connections.remove(conn);
14694            }
14695            app.conProviders.clear();
14696        }
14697
14698        // At this point there may be remaining entries in mLaunchingProviders
14699        // where we were the only one waiting, so they are no longer of use.
14700        // Look for these and clean up if found.
14701        // XXX Commented out for now.  Trying to figure out a way to reproduce
14702        // the actual situation to identify what is actually going on.
14703        if (false) {
14704            for (int i=0; i<mLaunchingProviders.size(); i++) {
14705                ContentProviderRecord cpr = (ContentProviderRecord)
14706                        mLaunchingProviders.get(i);
14707                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14708                    synchronized (cpr) {
14709                        cpr.launchingApp = null;
14710                        cpr.notifyAll();
14711                    }
14712                }
14713            }
14714        }
14715
14716        skipCurrentReceiverLocked(app);
14717
14718        // Unregister any receivers.
14719        for (int i=app.receivers.size()-1; i>=0; i--) {
14720            removeReceiverLocked(app.receivers.valueAt(i));
14721        }
14722        app.receivers.clear();
14723
14724        // If the app is undergoing backup, tell the backup manager about it
14725        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14726            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14727                    + mBackupTarget.appInfo + " died during backup");
14728            try {
14729                IBackupManager bm = IBackupManager.Stub.asInterface(
14730                        ServiceManager.getService(Context.BACKUP_SERVICE));
14731                bm.agentDisconnected(app.info.packageName);
14732            } catch (RemoteException e) {
14733                // can't happen; backup manager is local
14734            }
14735        }
14736
14737        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14738            ProcessChangeItem item = mPendingProcessChanges.get(i);
14739            if (item.pid == app.pid) {
14740                mPendingProcessChanges.remove(i);
14741                mAvailProcessChanges.add(item);
14742            }
14743        }
14744        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14745
14746        // If the caller is restarting this app, then leave it in its
14747        // current lists and let the caller take care of it.
14748        if (restarting) {
14749            return false;
14750        }
14751
14752        if (!app.persistent || app.isolated) {
14753            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14754                    "Removing non-persistent process during cleanup: " + app);
14755            mProcessNames.remove(app.processName, app.uid);
14756            mIsolatedProcesses.remove(app.uid);
14757            if (mHeavyWeightProcess == app) {
14758                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14759                        mHeavyWeightProcess.userId, 0));
14760                mHeavyWeightProcess = null;
14761            }
14762        } else if (!app.removed) {
14763            // This app is persistent, so we need to keep its record around.
14764            // If it is not already on the pending app list, add it there
14765            // and start a new process for it.
14766            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14767                mPersistentStartingProcesses.add(app);
14768                restart = true;
14769            }
14770        }
14771        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14772                "Clean-up removing on hold: " + app);
14773        mProcessesOnHold.remove(app);
14774
14775        if (app == mHomeProcess) {
14776            mHomeProcess = null;
14777        }
14778        if (app == mPreviousProcess) {
14779            mPreviousProcess = null;
14780        }
14781
14782        if (restart && !app.isolated) {
14783            // We have components that still need to be running in the
14784            // process, so re-launch it.
14785            if (index < 0) {
14786                ProcessList.remove(app.pid);
14787            }
14788            mProcessNames.put(app.processName, app.uid, app);
14789            startProcessLocked(app, "restart", app.processName);
14790            return true;
14791        } else if (app.pid > 0 && app.pid != MY_PID) {
14792            // Goodbye!
14793            boolean removed;
14794            synchronized (mPidsSelfLocked) {
14795                mPidsSelfLocked.remove(app.pid);
14796                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14797            }
14798            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14799            if (app.isolated) {
14800                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14801            }
14802            app.setPid(0);
14803        }
14804        return false;
14805    }
14806
14807    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14808        // Look through the content providers we are waiting to have launched,
14809        // and if any run in this process then either schedule a restart of
14810        // the process or kill the client waiting for it if this process has
14811        // gone bad.
14812        int NL = mLaunchingProviders.size();
14813        boolean restart = false;
14814        for (int i=0; i<NL; i++) {
14815            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14816            if (cpr.launchingApp == app) {
14817                if (!alwaysBad && !app.bad) {
14818                    restart = true;
14819                } else {
14820                    removeDyingProviderLocked(app, cpr, true);
14821                    // cpr should have been removed from mLaunchingProviders
14822                    NL = mLaunchingProviders.size();
14823                    i--;
14824                }
14825            }
14826        }
14827        return restart;
14828    }
14829
14830    // =========================================================
14831    // SERVICES
14832    // =========================================================
14833
14834    @Override
14835    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14836            int flags) {
14837        enforceNotIsolatedCaller("getServices");
14838        synchronized (this) {
14839            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14840        }
14841    }
14842
14843    @Override
14844    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14845        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14846        synchronized (this) {
14847            return mServices.getRunningServiceControlPanelLocked(name);
14848        }
14849    }
14850
14851    @Override
14852    public ComponentName startService(IApplicationThread caller, Intent service,
14853            String resolvedType, int userId) {
14854        enforceNotIsolatedCaller("startService");
14855        // Refuse possible leaked file descriptors
14856        if (service != null && service.hasFileDescriptors() == true) {
14857            throw new IllegalArgumentException("File descriptors passed in Intent");
14858        }
14859
14860        if (DEBUG_SERVICE)
14861            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14862        synchronized(this) {
14863            final int callingPid = Binder.getCallingPid();
14864            final int callingUid = Binder.getCallingUid();
14865            final long origId = Binder.clearCallingIdentity();
14866            ComponentName res = mServices.startServiceLocked(caller, service,
14867                    resolvedType, callingPid, callingUid, userId);
14868            Binder.restoreCallingIdentity(origId);
14869            return res;
14870        }
14871    }
14872
14873    ComponentName startServiceInPackage(int uid,
14874            Intent service, String resolvedType, int userId) {
14875        synchronized(this) {
14876            if (DEBUG_SERVICE)
14877                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14878            final long origId = Binder.clearCallingIdentity();
14879            ComponentName res = mServices.startServiceLocked(null, service,
14880                    resolvedType, -1, uid, userId);
14881            Binder.restoreCallingIdentity(origId);
14882            return res;
14883        }
14884    }
14885
14886    @Override
14887    public int stopService(IApplicationThread caller, Intent service,
14888            String resolvedType, int userId) {
14889        enforceNotIsolatedCaller("stopService");
14890        // Refuse possible leaked file descriptors
14891        if (service != null && service.hasFileDescriptors() == true) {
14892            throw new IllegalArgumentException("File descriptors passed in Intent");
14893        }
14894
14895        synchronized(this) {
14896            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14897        }
14898    }
14899
14900    @Override
14901    public IBinder peekService(Intent service, String resolvedType) {
14902        enforceNotIsolatedCaller("peekService");
14903        // Refuse possible leaked file descriptors
14904        if (service != null && service.hasFileDescriptors() == true) {
14905            throw new IllegalArgumentException("File descriptors passed in Intent");
14906        }
14907        synchronized(this) {
14908            return mServices.peekServiceLocked(service, resolvedType);
14909        }
14910    }
14911
14912    @Override
14913    public boolean stopServiceToken(ComponentName className, IBinder token,
14914            int startId) {
14915        synchronized(this) {
14916            return mServices.stopServiceTokenLocked(className, token, startId);
14917        }
14918    }
14919
14920    @Override
14921    public void setServiceForeground(ComponentName className, IBinder token,
14922            int id, Notification notification, boolean removeNotification) {
14923        synchronized(this) {
14924            mServices.setServiceForegroundLocked(className, token, id, notification,
14925                    removeNotification);
14926        }
14927    }
14928
14929    @Override
14930    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14931            boolean requireFull, String name, String callerPackage) {
14932        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14933                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14934    }
14935
14936    int unsafeConvertIncomingUser(int userId) {
14937        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14938                ? mCurrentUserId : userId;
14939    }
14940
14941    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14942            int allowMode, String name, String callerPackage) {
14943        final int callingUserId = UserHandle.getUserId(callingUid);
14944        if (callingUserId == userId) {
14945            return userId;
14946        }
14947
14948        // Note that we may be accessing mCurrentUserId outside of a lock...
14949        // shouldn't be a big deal, if this is being called outside
14950        // of a locked context there is intrinsically a race with
14951        // the value the caller will receive and someone else changing it.
14952        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14953        // we will switch to the calling user if access to the current user fails.
14954        int targetUserId = unsafeConvertIncomingUser(userId);
14955
14956        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14957            final boolean allow;
14958            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14959                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14960                // If the caller has this permission, they always pass go.  And collect $200.
14961                allow = true;
14962            } else if (allowMode == ALLOW_FULL_ONLY) {
14963                // We require full access, sucks to be you.
14964                allow = false;
14965            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14966                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14967                // If the caller does not have either permission, they are always doomed.
14968                allow = false;
14969            } else if (allowMode == ALLOW_NON_FULL) {
14970                // We are blanket allowing non-full access, you lucky caller!
14971                allow = true;
14972            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14973                // We may or may not allow this depending on whether the two users are
14974                // in the same profile.
14975                synchronized (mUserProfileGroupIdsSelfLocked) {
14976                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14977                            UserInfo.NO_PROFILE_GROUP_ID);
14978                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14979                            UserInfo.NO_PROFILE_GROUP_ID);
14980                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14981                            && callingProfile == targetProfile;
14982                }
14983            } else {
14984                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14985            }
14986            if (!allow) {
14987                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14988                    // In this case, they would like to just execute as their
14989                    // owner user instead of failing.
14990                    targetUserId = callingUserId;
14991                } else {
14992                    StringBuilder builder = new StringBuilder(128);
14993                    builder.append("Permission Denial: ");
14994                    builder.append(name);
14995                    if (callerPackage != null) {
14996                        builder.append(" from ");
14997                        builder.append(callerPackage);
14998                    }
14999                    builder.append(" asks to run as user ");
15000                    builder.append(userId);
15001                    builder.append(" but is calling from user ");
15002                    builder.append(UserHandle.getUserId(callingUid));
15003                    builder.append("; this requires ");
15004                    builder.append(INTERACT_ACROSS_USERS_FULL);
15005                    if (allowMode != ALLOW_FULL_ONLY) {
15006                        builder.append(" or ");
15007                        builder.append(INTERACT_ACROSS_USERS);
15008                    }
15009                    String msg = builder.toString();
15010                    Slog.w(TAG, msg);
15011                    throw new SecurityException(msg);
15012                }
15013            }
15014        }
15015        if (!allowAll && targetUserId < 0) {
15016            throw new IllegalArgumentException(
15017                    "Call does not support special user #" + targetUserId);
15018        }
15019        // Check shell permission
15020        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15021            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15022                    targetUserId)) {
15023                throw new SecurityException("Shell does not have permission to access user "
15024                        + targetUserId + "\n " + Debug.getCallers(3));
15025            }
15026        }
15027        return targetUserId;
15028    }
15029
15030    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15031            String className, int flags) {
15032        boolean result = false;
15033        // For apps that don't have pre-defined UIDs, check for permission
15034        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15035            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15036                if (ActivityManager.checkUidPermission(
15037                        INTERACT_ACROSS_USERS,
15038                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15039                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15040                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15041                            + " requests FLAG_SINGLE_USER, but app does not hold "
15042                            + INTERACT_ACROSS_USERS;
15043                    Slog.w(TAG, msg);
15044                    throw new SecurityException(msg);
15045                }
15046                // Permission passed
15047                result = true;
15048            }
15049        } else if ("system".equals(componentProcessName)) {
15050            result = true;
15051        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15052            // Phone app and persistent apps are allowed to export singleuser providers.
15053            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15054                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15055        }
15056        if (DEBUG_MU) {
15057            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15058                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15059        }
15060        return result;
15061    }
15062
15063    /**
15064     * Checks to see if the caller is in the same app as the singleton
15065     * component, or the component is in a special app. It allows special apps
15066     * to export singleton components but prevents exporting singleton
15067     * components for regular apps.
15068     */
15069    boolean isValidSingletonCall(int callingUid, int componentUid) {
15070        int componentAppId = UserHandle.getAppId(componentUid);
15071        return UserHandle.isSameApp(callingUid, componentUid)
15072                || componentAppId == Process.SYSTEM_UID
15073                || componentAppId == Process.PHONE_UID
15074                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15075                        == PackageManager.PERMISSION_GRANTED;
15076    }
15077
15078    public int bindService(IApplicationThread caller, IBinder token,
15079            Intent service, String resolvedType,
15080            IServiceConnection connection, int flags, int userId) {
15081        enforceNotIsolatedCaller("bindService");
15082
15083        // Refuse possible leaked file descriptors
15084        if (service != null && service.hasFileDescriptors() == true) {
15085            throw new IllegalArgumentException("File descriptors passed in Intent");
15086        }
15087
15088        synchronized(this) {
15089            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15090                    connection, flags, userId);
15091        }
15092    }
15093
15094    public boolean unbindService(IServiceConnection connection) {
15095        synchronized (this) {
15096            return mServices.unbindServiceLocked(connection);
15097        }
15098    }
15099
15100    public void publishService(IBinder token, Intent intent, IBinder service) {
15101        // Refuse possible leaked file descriptors
15102        if (intent != null && intent.hasFileDescriptors() == true) {
15103            throw new IllegalArgumentException("File descriptors passed in Intent");
15104        }
15105
15106        synchronized(this) {
15107            if (!(token instanceof ServiceRecord)) {
15108                throw new IllegalArgumentException("Invalid service token");
15109            }
15110            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15111        }
15112    }
15113
15114    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15115        // Refuse possible leaked file descriptors
15116        if (intent != null && intent.hasFileDescriptors() == true) {
15117            throw new IllegalArgumentException("File descriptors passed in Intent");
15118        }
15119
15120        synchronized(this) {
15121            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15122        }
15123    }
15124
15125    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15126        synchronized(this) {
15127            if (!(token instanceof ServiceRecord)) {
15128                throw new IllegalArgumentException("Invalid service token");
15129            }
15130            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15131        }
15132    }
15133
15134    // =========================================================
15135    // BACKUP AND RESTORE
15136    // =========================================================
15137
15138    // Cause the target app to be launched if necessary and its backup agent
15139    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15140    // activity manager to announce its creation.
15141    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15142        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15143        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15144
15145        synchronized(this) {
15146            // !!! TODO: currently no check here that we're already bound
15147            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15148            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15149            synchronized (stats) {
15150                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15151            }
15152
15153            // Backup agent is now in use, its package can't be stopped.
15154            try {
15155                AppGlobals.getPackageManager().setPackageStoppedState(
15156                        app.packageName, false, UserHandle.getUserId(app.uid));
15157            } catch (RemoteException e) {
15158            } catch (IllegalArgumentException e) {
15159                Slog.w(TAG, "Failed trying to unstop package "
15160                        + app.packageName + ": " + e);
15161            }
15162
15163            BackupRecord r = new BackupRecord(ss, app, backupMode);
15164            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15165                    ? new ComponentName(app.packageName, app.backupAgentName)
15166                    : new ComponentName("android", "FullBackupAgent");
15167            // startProcessLocked() returns existing proc's record if it's already running
15168            ProcessRecord proc = startProcessLocked(app.processName, app,
15169                    false, 0, "backup", hostingName, false, false, false);
15170            if (proc == null) {
15171                Slog.e(TAG, "Unable to start backup agent process " + r);
15172                return false;
15173            }
15174
15175            r.app = proc;
15176            mBackupTarget = r;
15177            mBackupAppName = app.packageName;
15178
15179            // Try not to kill the process during backup
15180            updateOomAdjLocked(proc);
15181
15182            // If the process is already attached, schedule the creation of the backup agent now.
15183            // If it is not yet live, this will be done when it attaches to the framework.
15184            if (proc.thread != null) {
15185                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15186                try {
15187                    proc.thread.scheduleCreateBackupAgent(app,
15188                            compatibilityInfoForPackageLocked(app), backupMode);
15189                } catch (RemoteException e) {
15190                    // Will time out on the backup manager side
15191                }
15192            } else {
15193                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15194            }
15195            // Invariants: at this point, the target app process exists and the application
15196            // is either already running or in the process of coming up.  mBackupTarget and
15197            // mBackupAppName describe the app, so that when it binds back to the AM we
15198            // know that it's scheduled for a backup-agent operation.
15199        }
15200
15201        return true;
15202    }
15203
15204    @Override
15205    public void clearPendingBackup() {
15206        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15207        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15208
15209        synchronized (this) {
15210            mBackupTarget = null;
15211            mBackupAppName = null;
15212        }
15213    }
15214
15215    // A backup agent has just come up
15216    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15217        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15218                + " = " + agent);
15219
15220        synchronized(this) {
15221            if (!agentPackageName.equals(mBackupAppName)) {
15222                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15223                return;
15224            }
15225        }
15226
15227        long oldIdent = Binder.clearCallingIdentity();
15228        try {
15229            IBackupManager bm = IBackupManager.Stub.asInterface(
15230                    ServiceManager.getService(Context.BACKUP_SERVICE));
15231            bm.agentConnected(agentPackageName, agent);
15232        } catch (RemoteException e) {
15233            // can't happen; the backup manager service is local
15234        } catch (Exception e) {
15235            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15236            e.printStackTrace();
15237        } finally {
15238            Binder.restoreCallingIdentity(oldIdent);
15239        }
15240    }
15241
15242    // done with this agent
15243    public void unbindBackupAgent(ApplicationInfo appInfo) {
15244        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15245        if (appInfo == null) {
15246            Slog.w(TAG, "unbind backup agent for null app");
15247            return;
15248        }
15249
15250        synchronized(this) {
15251            try {
15252                if (mBackupAppName == null) {
15253                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15254                    return;
15255                }
15256
15257                if (!mBackupAppName.equals(appInfo.packageName)) {
15258                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15259                    return;
15260                }
15261
15262                // Not backing this app up any more; reset its OOM adjustment
15263                final ProcessRecord proc = mBackupTarget.app;
15264                updateOomAdjLocked(proc);
15265
15266                // If the app crashed during backup, 'thread' will be null here
15267                if (proc.thread != null) {
15268                    try {
15269                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15270                                compatibilityInfoForPackageLocked(appInfo));
15271                    } catch (Exception e) {
15272                        Slog.e(TAG, "Exception when unbinding backup agent:");
15273                        e.printStackTrace();
15274                    }
15275                }
15276            } finally {
15277                mBackupTarget = null;
15278                mBackupAppName = null;
15279            }
15280        }
15281    }
15282    // =========================================================
15283    // BROADCASTS
15284    // =========================================================
15285
15286    private final List getStickiesLocked(String action, IntentFilter filter,
15287            List cur, int userId) {
15288        final ContentResolver resolver = mContext.getContentResolver();
15289        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15290        if (stickies == null) {
15291            return cur;
15292        }
15293        final ArrayList<Intent> list = stickies.get(action);
15294        if (list == null) {
15295            return cur;
15296        }
15297        int N = list.size();
15298        for (int i=0; i<N; i++) {
15299            Intent intent = list.get(i);
15300            if (filter.match(resolver, intent, true, TAG) >= 0) {
15301                if (cur == null) {
15302                    cur = new ArrayList<Intent>();
15303                }
15304                cur.add(intent);
15305            }
15306        }
15307        return cur;
15308    }
15309
15310    boolean isPendingBroadcastProcessLocked(int pid) {
15311        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15312                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15313    }
15314
15315    void skipPendingBroadcastLocked(int pid) {
15316            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15317            for (BroadcastQueue queue : mBroadcastQueues) {
15318                queue.skipPendingBroadcastLocked(pid);
15319            }
15320    }
15321
15322    // The app just attached; send any pending broadcasts that it should receive
15323    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15324        boolean didSomething = false;
15325        for (BroadcastQueue queue : mBroadcastQueues) {
15326            didSomething |= queue.sendPendingBroadcastsLocked(app);
15327        }
15328        return didSomething;
15329    }
15330
15331    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15332            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15333        enforceNotIsolatedCaller("registerReceiver");
15334        int callingUid;
15335        int callingPid;
15336        synchronized(this) {
15337            ProcessRecord callerApp = null;
15338            if (caller != null) {
15339                callerApp = getRecordForAppLocked(caller);
15340                if (callerApp == null) {
15341                    throw new SecurityException(
15342                            "Unable to find app for caller " + caller
15343                            + " (pid=" + Binder.getCallingPid()
15344                            + ") when registering receiver " + receiver);
15345                }
15346                if (callerApp.info.uid != Process.SYSTEM_UID &&
15347                        !callerApp.pkgList.containsKey(callerPackage) &&
15348                        !"android".equals(callerPackage)) {
15349                    throw new SecurityException("Given caller package " + callerPackage
15350                            + " is not running in process " + callerApp);
15351                }
15352                callingUid = callerApp.info.uid;
15353                callingPid = callerApp.pid;
15354            } else {
15355                callerPackage = null;
15356                callingUid = Binder.getCallingUid();
15357                callingPid = Binder.getCallingPid();
15358            }
15359
15360            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15361                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15362
15363            List allSticky = null;
15364
15365            // Look for any matching sticky broadcasts...
15366            Iterator actions = filter.actionsIterator();
15367            if (actions != null) {
15368                while (actions.hasNext()) {
15369                    String action = (String)actions.next();
15370                    allSticky = getStickiesLocked(action, filter, allSticky,
15371                            UserHandle.USER_ALL);
15372                    allSticky = getStickiesLocked(action, filter, allSticky,
15373                            UserHandle.getUserId(callingUid));
15374                }
15375            } else {
15376                allSticky = getStickiesLocked(null, filter, allSticky,
15377                        UserHandle.USER_ALL);
15378                allSticky = getStickiesLocked(null, filter, allSticky,
15379                        UserHandle.getUserId(callingUid));
15380            }
15381
15382            // The first sticky in the list is returned directly back to
15383            // the client.
15384            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15385
15386            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15387                    + ": " + sticky);
15388
15389            if (receiver == null) {
15390                return sticky;
15391            }
15392
15393            ReceiverList rl
15394                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15395            if (rl == null) {
15396                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15397                        userId, receiver);
15398                if (rl.app != null) {
15399                    rl.app.receivers.add(rl);
15400                } else {
15401                    try {
15402                        receiver.asBinder().linkToDeath(rl, 0);
15403                    } catch (RemoteException e) {
15404                        return sticky;
15405                    }
15406                    rl.linkedToDeath = true;
15407                }
15408                mRegisteredReceivers.put(receiver.asBinder(), rl);
15409            } else if (rl.uid != callingUid) {
15410                throw new IllegalArgumentException(
15411                        "Receiver requested to register for uid " + callingUid
15412                        + " was previously registered for uid " + rl.uid);
15413            } else if (rl.pid != callingPid) {
15414                throw new IllegalArgumentException(
15415                        "Receiver requested to register for pid " + callingPid
15416                        + " was previously registered for pid " + rl.pid);
15417            } else if (rl.userId != userId) {
15418                throw new IllegalArgumentException(
15419                        "Receiver requested to register for user " + userId
15420                        + " was previously registered for user " + rl.userId);
15421            }
15422            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15423                    permission, callingUid, userId);
15424            rl.add(bf);
15425            if (!bf.debugCheck()) {
15426                Slog.w(TAG, "==> For Dynamic broadast");
15427            }
15428            mReceiverResolver.addFilter(bf);
15429
15430            // Enqueue broadcasts for all existing stickies that match
15431            // this filter.
15432            if (allSticky != null) {
15433                ArrayList receivers = new ArrayList();
15434                receivers.add(bf);
15435
15436                int N = allSticky.size();
15437                for (int i=0; i<N; i++) {
15438                    Intent intent = (Intent)allSticky.get(i);
15439                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15440                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15441                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15442                            null, null, false, true, true, -1);
15443                    queue.enqueueParallelBroadcastLocked(r);
15444                    queue.scheduleBroadcastsLocked();
15445                }
15446            }
15447
15448            return sticky;
15449        }
15450    }
15451
15452    public void unregisterReceiver(IIntentReceiver receiver) {
15453        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15454
15455        final long origId = Binder.clearCallingIdentity();
15456        try {
15457            boolean doTrim = false;
15458
15459            synchronized(this) {
15460                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15461                if (rl != null) {
15462                    if (rl.curBroadcast != null) {
15463                        BroadcastRecord r = rl.curBroadcast;
15464                        final boolean doNext = finishReceiverLocked(
15465                                receiver.asBinder(), r.resultCode, r.resultData,
15466                                r.resultExtras, r.resultAbort);
15467                        if (doNext) {
15468                            doTrim = true;
15469                            r.queue.processNextBroadcast(false);
15470                        }
15471                    }
15472
15473                    if (rl.app != null) {
15474                        rl.app.receivers.remove(rl);
15475                    }
15476                    removeReceiverLocked(rl);
15477                    if (rl.linkedToDeath) {
15478                        rl.linkedToDeath = false;
15479                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15480                    }
15481                }
15482            }
15483
15484            // If we actually concluded any broadcasts, we might now be able
15485            // to trim the recipients' apps from our working set
15486            if (doTrim) {
15487                trimApplications();
15488                return;
15489            }
15490
15491        } finally {
15492            Binder.restoreCallingIdentity(origId);
15493        }
15494    }
15495
15496    void removeReceiverLocked(ReceiverList rl) {
15497        mRegisteredReceivers.remove(rl.receiver.asBinder());
15498        int N = rl.size();
15499        for (int i=0; i<N; i++) {
15500            mReceiverResolver.removeFilter(rl.get(i));
15501        }
15502    }
15503
15504    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15505        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15506            ProcessRecord r = mLruProcesses.get(i);
15507            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15508                try {
15509                    r.thread.dispatchPackageBroadcast(cmd, packages);
15510                } catch (RemoteException ex) {
15511                }
15512            }
15513        }
15514    }
15515
15516    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15517            int callingUid, int[] users) {
15518        List<ResolveInfo> receivers = null;
15519        try {
15520            HashSet<ComponentName> singleUserReceivers = null;
15521            boolean scannedFirstReceivers = false;
15522            for (int user : users) {
15523                // Skip users that have Shell restrictions
15524                if (callingUid == Process.SHELL_UID
15525                        && getUserManagerLocked().hasUserRestriction(
15526                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15527                    continue;
15528                }
15529                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15530                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15531                if (user != 0 && newReceivers != null) {
15532                    // If this is not the primary user, we need to check for
15533                    // any receivers that should be filtered out.
15534                    for (int i=0; i<newReceivers.size(); i++) {
15535                        ResolveInfo ri = newReceivers.get(i);
15536                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15537                            newReceivers.remove(i);
15538                            i--;
15539                        }
15540                    }
15541                }
15542                if (newReceivers != null && newReceivers.size() == 0) {
15543                    newReceivers = null;
15544                }
15545                if (receivers == null) {
15546                    receivers = newReceivers;
15547                } else if (newReceivers != null) {
15548                    // We need to concatenate the additional receivers
15549                    // found with what we have do far.  This would be easy,
15550                    // but we also need to de-dup any receivers that are
15551                    // singleUser.
15552                    if (!scannedFirstReceivers) {
15553                        // Collect any single user receivers we had already retrieved.
15554                        scannedFirstReceivers = true;
15555                        for (int i=0; i<receivers.size(); i++) {
15556                            ResolveInfo ri = receivers.get(i);
15557                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15558                                ComponentName cn = new ComponentName(
15559                                        ri.activityInfo.packageName, ri.activityInfo.name);
15560                                if (singleUserReceivers == null) {
15561                                    singleUserReceivers = new HashSet<ComponentName>();
15562                                }
15563                                singleUserReceivers.add(cn);
15564                            }
15565                        }
15566                    }
15567                    // Add the new results to the existing results, tracking
15568                    // and de-dupping single user receivers.
15569                    for (int i=0; i<newReceivers.size(); i++) {
15570                        ResolveInfo ri = newReceivers.get(i);
15571                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15572                            ComponentName cn = new ComponentName(
15573                                    ri.activityInfo.packageName, ri.activityInfo.name);
15574                            if (singleUserReceivers == null) {
15575                                singleUserReceivers = new HashSet<ComponentName>();
15576                            }
15577                            if (!singleUserReceivers.contains(cn)) {
15578                                singleUserReceivers.add(cn);
15579                                receivers.add(ri);
15580                            }
15581                        } else {
15582                            receivers.add(ri);
15583                        }
15584                    }
15585                }
15586            }
15587        } catch (RemoteException ex) {
15588            // pm is in same process, this will never happen.
15589        }
15590        return receivers;
15591    }
15592
15593    private final int broadcastIntentLocked(ProcessRecord callerApp,
15594            String callerPackage, Intent intent, String resolvedType,
15595            IIntentReceiver resultTo, int resultCode, String resultData,
15596            Bundle map, String requiredPermission, int appOp,
15597            boolean ordered, boolean sticky, int callingPid, int callingUid,
15598            int userId) {
15599        intent = new Intent(intent);
15600
15601        // By default broadcasts do not go to stopped apps.
15602        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15603
15604        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15605            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15606            + " ordered=" + ordered + " userid=" + userId);
15607        if ((resultTo != null) && !ordered) {
15608            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15609        }
15610
15611        userId = handleIncomingUser(callingPid, callingUid, userId,
15612                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15613
15614        // Make sure that the user who is receiving this broadcast is started.
15615        // If not, we will just skip it.
15616
15617        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15618            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15619                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15620                Slog.w(TAG, "Skipping broadcast of " + intent
15621                        + ": user " + userId + " is stopped");
15622                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15623            }
15624        }
15625
15626        /*
15627         * Prevent non-system code (defined here to be non-persistent
15628         * processes) from sending protected broadcasts.
15629         */
15630        int callingAppId = UserHandle.getAppId(callingUid);
15631        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15632            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15633            || callingAppId == Process.NFC_UID || callingUid == 0) {
15634            // Always okay.
15635        } else if (callerApp == null || !callerApp.persistent) {
15636            try {
15637                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15638                        intent.getAction())) {
15639                    String msg = "Permission Denial: not allowed to send broadcast "
15640                            + intent.getAction() + " from pid="
15641                            + callingPid + ", uid=" + callingUid;
15642                    Slog.w(TAG, msg);
15643                    throw new SecurityException(msg);
15644                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15645                    // Special case for compatibility: we don't want apps to send this,
15646                    // but historically it has not been protected and apps may be using it
15647                    // to poke their own app widget.  So, instead of making it protected,
15648                    // just limit it to the caller.
15649                    if (callerApp == null) {
15650                        String msg = "Permission Denial: not allowed to send broadcast "
15651                                + intent.getAction() + " from unknown caller.";
15652                        Slog.w(TAG, msg);
15653                        throw new SecurityException(msg);
15654                    } else if (intent.getComponent() != null) {
15655                        // They are good enough to send to an explicit component...  verify
15656                        // it is being sent to the calling app.
15657                        if (!intent.getComponent().getPackageName().equals(
15658                                callerApp.info.packageName)) {
15659                            String msg = "Permission Denial: not allowed to send broadcast "
15660                                    + intent.getAction() + " to "
15661                                    + intent.getComponent().getPackageName() + " from "
15662                                    + callerApp.info.packageName;
15663                            Slog.w(TAG, msg);
15664                            throw new SecurityException(msg);
15665                        }
15666                    } else {
15667                        // Limit broadcast to their own package.
15668                        intent.setPackage(callerApp.info.packageName);
15669                    }
15670                }
15671            } catch (RemoteException e) {
15672                Slog.w(TAG, "Remote exception", e);
15673                return ActivityManager.BROADCAST_SUCCESS;
15674            }
15675        }
15676
15677        // Handle special intents: if this broadcast is from the package
15678        // manager about a package being removed, we need to remove all of
15679        // its activities from the history stack.
15680        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15681                intent.getAction());
15682        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15683                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15684                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15685                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15686                || uidRemoved) {
15687            if (checkComponentPermission(
15688                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15689                    callingPid, callingUid, -1, true)
15690                    == PackageManager.PERMISSION_GRANTED) {
15691                if (uidRemoved) {
15692                    final Bundle intentExtras = intent.getExtras();
15693                    final int uid = intentExtras != null
15694                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15695                    if (uid >= 0) {
15696                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15697                        synchronized (bs) {
15698                            bs.removeUidStatsLocked(uid);
15699                        }
15700                        mAppOpsService.uidRemoved(uid);
15701                    }
15702                } else {
15703                    // If resources are unavailable just force stop all
15704                    // those packages and flush the attribute cache as well.
15705                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15706                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15707                        if (list != null && (list.length > 0)) {
15708                            for (String pkg : list) {
15709                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15710                                        "storage unmount");
15711                            }
15712                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15713                            sendPackageBroadcastLocked(
15714                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15715                        }
15716                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15717                            intent.getAction())) {
15718                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15719                    } else {
15720                        Uri data = intent.getData();
15721                        String ssp;
15722                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15723                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15724                                    intent.getAction());
15725                            boolean fullUninstall = removed &&
15726                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15727                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15728                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15729                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15730                                        false, fullUninstall, userId,
15731                                        removed ? "pkg removed" : "pkg changed");
15732                            }
15733                            if (removed) {
15734                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15735                                        new String[] {ssp}, userId);
15736                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15737                                    mAppOpsService.packageRemoved(
15738                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15739
15740                                    // Remove all permissions granted from/to this package
15741                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15742                                }
15743                            }
15744                        }
15745                    }
15746                }
15747            } else {
15748                String msg = "Permission Denial: " + intent.getAction()
15749                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15750                        + ", uid=" + callingUid + ")"
15751                        + " requires "
15752                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15753                Slog.w(TAG, msg);
15754                throw new SecurityException(msg);
15755            }
15756
15757        // Special case for adding a package: by default turn on compatibility
15758        // mode.
15759        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15760            Uri data = intent.getData();
15761            String ssp;
15762            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15763                mCompatModePackages.handlePackageAddedLocked(ssp,
15764                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15765            }
15766        }
15767
15768        /*
15769         * If this is the time zone changed action, queue up a message that will reset the timezone
15770         * of all currently running processes. This message will get queued up before the broadcast
15771         * happens.
15772         */
15773        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15774            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15775        }
15776
15777        /*
15778         * If the user set the time, let all running processes know.
15779         */
15780        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15781            final int is24Hour = intent.getBooleanExtra(
15782                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15783            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15784            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15785            synchronized (stats) {
15786                stats.noteCurrentTimeChangedLocked();
15787            }
15788        }
15789
15790        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15791            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15792        }
15793
15794        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15795            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15796            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15797        }
15798
15799        // Add to the sticky list if requested.
15800        if (sticky) {
15801            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15802                    callingPid, callingUid)
15803                    != PackageManager.PERMISSION_GRANTED) {
15804                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15805                        + callingPid + ", uid=" + callingUid
15806                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15807                Slog.w(TAG, msg);
15808                throw new SecurityException(msg);
15809            }
15810            if (requiredPermission != null) {
15811                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15812                        + " and enforce permission " + requiredPermission);
15813                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15814            }
15815            if (intent.getComponent() != null) {
15816                throw new SecurityException(
15817                        "Sticky broadcasts can't target a specific component");
15818            }
15819            // We use userId directly here, since the "all" target is maintained
15820            // as a separate set of sticky broadcasts.
15821            if (userId != UserHandle.USER_ALL) {
15822                // But first, if this is not a broadcast to all users, then
15823                // make sure it doesn't conflict with an existing broadcast to
15824                // all users.
15825                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15826                        UserHandle.USER_ALL);
15827                if (stickies != null) {
15828                    ArrayList<Intent> list = stickies.get(intent.getAction());
15829                    if (list != null) {
15830                        int N = list.size();
15831                        int i;
15832                        for (i=0; i<N; i++) {
15833                            if (intent.filterEquals(list.get(i))) {
15834                                throw new IllegalArgumentException(
15835                                        "Sticky broadcast " + intent + " for user "
15836                                        + userId + " conflicts with existing global broadcast");
15837                            }
15838                        }
15839                    }
15840                }
15841            }
15842            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15843            if (stickies == null) {
15844                stickies = new ArrayMap<String, ArrayList<Intent>>();
15845                mStickyBroadcasts.put(userId, stickies);
15846            }
15847            ArrayList<Intent> list = stickies.get(intent.getAction());
15848            if (list == null) {
15849                list = new ArrayList<Intent>();
15850                stickies.put(intent.getAction(), list);
15851            }
15852            int N = list.size();
15853            int i;
15854            for (i=0; i<N; i++) {
15855                if (intent.filterEquals(list.get(i))) {
15856                    // This sticky already exists, replace it.
15857                    list.set(i, new Intent(intent));
15858                    break;
15859                }
15860            }
15861            if (i >= N) {
15862                list.add(new Intent(intent));
15863            }
15864        }
15865
15866        int[] users;
15867        if (userId == UserHandle.USER_ALL) {
15868            // Caller wants broadcast to go to all started users.
15869            users = mStartedUserArray;
15870        } else {
15871            // Caller wants broadcast to go to one specific user.
15872            users = new int[] {userId};
15873        }
15874
15875        // Figure out who all will receive this broadcast.
15876        List receivers = null;
15877        List<BroadcastFilter> registeredReceivers = null;
15878        // Need to resolve the intent to interested receivers...
15879        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15880                 == 0) {
15881            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15882        }
15883        if (intent.getComponent() == null) {
15884            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15885                // Query one target user at a time, excluding shell-restricted users
15886                UserManagerService ums = getUserManagerLocked();
15887                for (int i = 0; i < users.length; i++) {
15888                    if (ums.hasUserRestriction(
15889                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15890                        continue;
15891                    }
15892                    List<BroadcastFilter> registeredReceiversForUser =
15893                            mReceiverResolver.queryIntent(intent,
15894                                    resolvedType, false, users[i]);
15895                    if (registeredReceivers == null) {
15896                        registeredReceivers = registeredReceiversForUser;
15897                    } else if (registeredReceiversForUser != null) {
15898                        registeredReceivers.addAll(registeredReceiversForUser);
15899                    }
15900                }
15901            } else {
15902                registeredReceivers = mReceiverResolver.queryIntent(intent,
15903                        resolvedType, false, userId);
15904            }
15905        }
15906
15907        final boolean replacePending =
15908                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15909
15910        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15911                + " replacePending=" + replacePending);
15912
15913        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15914        if (!ordered && NR > 0) {
15915            // If we are not serializing this broadcast, then send the
15916            // registered receivers separately so they don't wait for the
15917            // components to be launched.
15918            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15919            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15920                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15921                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15922                    ordered, sticky, false, userId);
15923            if (DEBUG_BROADCAST) Slog.v(
15924                    TAG, "Enqueueing parallel broadcast " + r);
15925            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15926            if (!replaced) {
15927                queue.enqueueParallelBroadcastLocked(r);
15928                queue.scheduleBroadcastsLocked();
15929            }
15930            registeredReceivers = null;
15931            NR = 0;
15932        }
15933
15934        // Merge into one list.
15935        int ir = 0;
15936        if (receivers != null) {
15937            // A special case for PACKAGE_ADDED: do not allow the package
15938            // being added to see this broadcast.  This prevents them from
15939            // using this as a back door to get run as soon as they are
15940            // installed.  Maybe in the future we want to have a special install
15941            // broadcast or such for apps, but we'd like to deliberately make
15942            // this decision.
15943            String skipPackages[] = null;
15944            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15945                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15946                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15947                Uri data = intent.getData();
15948                if (data != null) {
15949                    String pkgName = data.getSchemeSpecificPart();
15950                    if (pkgName != null) {
15951                        skipPackages = new String[] { pkgName };
15952                    }
15953                }
15954            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15955                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15956            }
15957            if (skipPackages != null && (skipPackages.length > 0)) {
15958                for (String skipPackage : skipPackages) {
15959                    if (skipPackage != null) {
15960                        int NT = receivers.size();
15961                        for (int it=0; it<NT; it++) {
15962                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15963                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15964                                receivers.remove(it);
15965                                it--;
15966                                NT--;
15967                            }
15968                        }
15969                    }
15970                }
15971            }
15972
15973            int NT = receivers != null ? receivers.size() : 0;
15974            int it = 0;
15975            ResolveInfo curt = null;
15976            BroadcastFilter curr = null;
15977            while (it < NT && ir < NR) {
15978                if (curt == null) {
15979                    curt = (ResolveInfo)receivers.get(it);
15980                }
15981                if (curr == null) {
15982                    curr = registeredReceivers.get(ir);
15983                }
15984                if (curr.getPriority() >= curt.priority) {
15985                    // Insert this broadcast record into the final list.
15986                    receivers.add(it, curr);
15987                    ir++;
15988                    curr = null;
15989                    it++;
15990                    NT++;
15991                } else {
15992                    // Skip to the next ResolveInfo in the final list.
15993                    it++;
15994                    curt = null;
15995                }
15996            }
15997        }
15998        while (ir < NR) {
15999            if (receivers == null) {
16000                receivers = new ArrayList();
16001            }
16002            receivers.add(registeredReceivers.get(ir));
16003            ir++;
16004        }
16005
16006        if ((receivers != null && receivers.size() > 0)
16007                || resultTo != null) {
16008            BroadcastQueue queue = broadcastQueueForIntent(intent);
16009            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16010                    callerPackage, callingPid, callingUid, resolvedType,
16011                    requiredPermission, appOp, receivers, resultTo, resultCode,
16012                    resultData, map, ordered, sticky, false, userId);
16013            if (DEBUG_BROADCAST) Slog.v(
16014                    TAG, "Enqueueing ordered broadcast " + r
16015                    + ": prev had " + queue.mOrderedBroadcasts.size());
16016            if (DEBUG_BROADCAST) {
16017                int seq = r.intent.getIntExtra("seq", -1);
16018                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16019            }
16020            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16021            if (!replaced) {
16022                queue.enqueueOrderedBroadcastLocked(r);
16023                queue.scheduleBroadcastsLocked();
16024            }
16025        }
16026
16027        return ActivityManager.BROADCAST_SUCCESS;
16028    }
16029
16030    final Intent verifyBroadcastLocked(Intent intent) {
16031        // Refuse possible leaked file descriptors
16032        if (intent != null && intent.hasFileDescriptors() == true) {
16033            throw new IllegalArgumentException("File descriptors passed in Intent");
16034        }
16035
16036        int flags = intent.getFlags();
16037
16038        if (!mProcessesReady) {
16039            // if the caller really truly claims to know what they're doing, go
16040            // ahead and allow the broadcast without launching any receivers
16041            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16042                intent = new Intent(intent);
16043                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16044            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16045                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16046                        + " before boot completion");
16047                throw new IllegalStateException("Cannot broadcast before boot completed");
16048            }
16049        }
16050
16051        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16052            throw new IllegalArgumentException(
16053                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16054        }
16055
16056        return intent;
16057    }
16058
16059    public final int broadcastIntent(IApplicationThread caller,
16060            Intent intent, String resolvedType, IIntentReceiver resultTo,
16061            int resultCode, String resultData, Bundle map,
16062            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16063        enforceNotIsolatedCaller("broadcastIntent");
16064        synchronized(this) {
16065            intent = verifyBroadcastLocked(intent);
16066
16067            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16068            final int callingPid = Binder.getCallingPid();
16069            final int callingUid = Binder.getCallingUid();
16070            final long origId = Binder.clearCallingIdentity();
16071            int res = broadcastIntentLocked(callerApp,
16072                    callerApp != null ? callerApp.info.packageName : null,
16073                    intent, resolvedType, resultTo,
16074                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16075                    callingPid, callingUid, userId);
16076            Binder.restoreCallingIdentity(origId);
16077            return res;
16078        }
16079    }
16080
16081    int broadcastIntentInPackage(String packageName, int uid,
16082            Intent intent, String resolvedType, IIntentReceiver resultTo,
16083            int resultCode, String resultData, Bundle map,
16084            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16085        synchronized(this) {
16086            intent = verifyBroadcastLocked(intent);
16087
16088            final long origId = Binder.clearCallingIdentity();
16089            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16090                    resultTo, resultCode, resultData, map, requiredPermission,
16091                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16092            Binder.restoreCallingIdentity(origId);
16093            return res;
16094        }
16095    }
16096
16097    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16098        // Refuse possible leaked file descriptors
16099        if (intent != null && intent.hasFileDescriptors() == true) {
16100            throw new IllegalArgumentException("File descriptors passed in Intent");
16101        }
16102
16103        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16104                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16105
16106        synchronized(this) {
16107            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16108                    != PackageManager.PERMISSION_GRANTED) {
16109                String msg = "Permission Denial: unbroadcastIntent() from pid="
16110                        + Binder.getCallingPid()
16111                        + ", uid=" + Binder.getCallingUid()
16112                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16113                Slog.w(TAG, msg);
16114                throw new SecurityException(msg);
16115            }
16116            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16117            if (stickies != null) {
16118                ArrayList<Intent> list = stickies.get(intent.getAction());
16119                if (list != null) {
16120                    int N = list.size();
16121                    int i;
16122                    for (i=0; i<N; i++) {
16123                        if (intent.filterEquals(list.get(i))) {
16124                            list.remove(i);
16125                            break;
16126                        }
16127                    }
16128                    if (list.size() <= 0) {
16129                        stickies.remove(intent.getAction());
16130                    }
16131                }
16132                if (stickies.size() <= 0) {
16133                    mStickyBroadcasts.remove(userId);
16134                }
16135            }
16136        }
16137    }
16138
16139    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16140            String resultData, Bundle resultExtras, boolean resultAbort) {
16141        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16142        if (r == null) {
16143            Slog.w(TAG, "finishReceiver called but not found on queue");
16144            return false;
16145        }
16146
16147        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16148    }
16149
16150    void backgroundServicesFinishedLocked(int userId) {
16151        for (BroadcastQueue queue : mBroadcastQueues) {
16152            queue.backgroundServicesFinishedLocked(userId);
16153        }
16154    }
16155
16156    public void finishReceiver(IBinder who, int resultCode, String resultData,
16157            Bundle resultExtras, boolean resultAbort) {
16158        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16159
16160        // Refuse possible leaked file descriptors
16161        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16162            throw new IllegalArgumentException("File descriptors passed in Bundle");
16163        }
16164
16165        final long origId = Binder.clearCallingIdentity();
16166        try {
16167            boolean doNext = false;
16168            BroadcastRecord r;
16169
16170            synchronized(this) {
16171                r = broadcastRecordForReceiverLocked(who);
16172                if (r != null) {
16173                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16174                        resultData, resultExtras, resultAbort, true);
16175                }
16176            }
16177
16178            if (doNext) {
16179                r.queue.processNextBroadcast(false);
16180            }
16181            trimApplications();
16182        } finally {
16183            Binder.restoreCallingIdentity(origId);
16184        }
16185    }
16186
16187    // =========================================================
16188    // INSTRUMENTATION
16189    // =========================================================
16190
16191    public boolean startInstrumentation(ComponentName className,
16192            String profileFile, int flags, Bundle arguments,
16193            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16194            int userId, String abiOverride) {
16195        enforceNotIsolatedCaller("startInstrumentation");
16196        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16197                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16198        // Refuse possible leaked file descriptors
16199        if (arguments != null && arguments.hasFileDescriptors()) {
16200            throw new IllegalArgumentException("File descriptors passed in Bundle");
16201        }
16202
16203        synchronized(this) {
16204            InstrumentationInfo ii = null;
16205            ApplicationInfo ai = null;
16206            try {
16207                ii = mContext.getPackageManager().getInstrumentationInfo(
16208                    className, STOCK_PM_FLAGS);
16209                ai = AppGlobals.getPackageManager().getApplicationInfo(
16210                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16211            } catch (PackageManager.NameNotFoundException e) {
16212            } catch (RemoteException e) {
16213            }
16214            if (ii == null) {
16215                reportStartInstrumentationFailure(watcher, className,
16216                        "Unable to find instrumentation info for: " + className);
16217                return false;
16218            }
16219            if (ai == null) {
16220                reportStartInstrumentationFailure(watcher, className,
16221                        "Unable to find instrumentation target package: " + ii.targetPackage);
16222                return false;
16223            }
16224
16225            int match = mContext.getPackageManager().checkSignatures(
16226                    ii.targetPackage, ii.packageName);
16227            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16228                String msg = "Permission Denial: starting instrumentation "
16229                        + className + " from pid="
16230                        + Binder.getCallingPid()
16231                        + ", uid=" + Binder.getCallingPid()
16232                        + " not allowed because package " + ii.packageName
16233                        + " does not have a signature matching the target "
16234                        + ii.targetPackage;
16235                reportStartInstrumentationFailure(watcher, className, msg);
16236                throw new SecurityException(msg);
16237            }
16238
16239            final long origId = Binder.clearCallingIdentity();
16240            // Instrumentation can kill and relaunch even persistent processes
16241            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16242                    "start instr");
16243            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16244            app.instrumentationClass = className;
16245            app.instrumentationInfo = ai;
16246            app.instrumentationProfileFile = profileFile;
16247            app.instrumentationArguments = arguments;
16248            app.instrumentationWatcher = watcher;
16249            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16250            app.instrumentationResultClass = className;
16251            Binder.restoreCallingIdentity(origId);
16252        }
16253
16254        return true;
16255    }
16256
16257    /**
16258     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16259     * error to the logs, but if somebody is watching, send the report there too.  This enables
16260     * the "am" command to report errors with more information.
16261     *
16262     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16263     * @param cn The component name of the instrumentation.
16264     * @param report The error report.
16265     */
16266    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16267            ComponentName cn, String report) {
16268        Slog.w(TAG, report);
16269        try {
16270            if (watcher != null) {
16271                Bundle results = new Bundle();
16272                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16273                results.putString("Error", report);
16274                watcher.instrumentationStatus(cn, -1, results);
16275            }
16276        } catch (RemoteException e) {
16277            Slog.w(TAG, e);
16278        }
16279    }
16280
16281    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16282        if (app.instrumentationWatcher != null) {
16283            try {
16284                // NOTE:  IInstrumentationWatcher *must* be oneway here
16285                app.instrumentationWatcher.instrumentationFinished(
16286                    app.instrumentationClass,
16287                    resultCode,
16288                    results);
16289            } catch (RemoteException e) {
16290            }
16291        }
16292        if (app.instrumentationUiAutomationConnection != null) {
16293            try {
16294                app.instrumentationUiAutomationConnection.shutdown();
16295            } catch (RemoteException re) {
16296                /* ignore */
16297            }
16298            // Only a UiAutomation can set this flag and now that
16299            // it is finished we make sure it is reset to its default.
16300            mUserIsMonkey = false;
16301        }
16302        app.instrumentationWatcher = null;
16303        app.instrumentationUiAutomationConnection = null;
16304        app.instrumentationClass = null;
16305        app.instrumentationInfo = null;
16306        app.instrumentationProfileFile = null;
16307        app.instrumentationArguments = null;
16308
16309        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16310                "finished inst");
16311    }
16312
16313    public void finishInstrumentation(IApplicationThread target,
16314            int resultCode, Bundle results) {
16315        int userId = UserHandle.getCallingUserId();
16316        // Refuse possible leaked file descriptors
16317        if (results != null && results.hasFileDescriptors()) {
16318            throw new IllegalArgumentException("File descriptors passed in Intent");
16319        }
16320
16321        synchronized(this) {
16322            ProcessRecord app = getRecordForAppLocked(target);
16323            if (app == null) {
16324                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16325                return;
16326            }
16327            final long origId = Binder.clearCallingIdentity();
16328            finishInstrumentationLocked(app, resultCode, results);
16329            Binder.restoreCallingIdentity(origId);
16330        }
16331    }
16332
16333    // =========================================================
16334    // CONFIGURATION
16335    // =========================================================
16336
16337    public ConfigurationInfo getDeviceConfigurationInfo() {
16338        ConfigurationInfo config = new ConfigurationInfo();
16339        synchronized (this) {
16340            config.reqTouchScreen = mConfiguration.touchscreen;
16341            config.reqKeyboardType = mConfiguration.keyboard;
16342            config.reqNavigation = mConfiguration.navigation;
16343            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16344                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16345                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16346            }
16347            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16348                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16349                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16350            }
16351            config.reqGlEsVersion = GL_ES_VERSION;
16352        }
16353        return config;
16354    }
16355
16356    ActivityStack getFocusedStack() {
16357        return mStackSupervisor.getFocusedStack();
16358    }
16359
16360    public Configuration getConfiguration() {
16361        Configuration ci;
16362        synchronized(this) {
16363            ci = new Configuration(mConfiguration);
16364        }
16365        return ci;
16366    }
16367
16368    public void updatePersistentConfiguration(Configuration values) {
16369        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16370                "updateConfiguration()");
16371        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16372                "updateConfiguration()");
16373        if (values == null) {
16374            throw new NullPointerException("Configuration must not be null");
16375        }
16376
16377        synchronized(this) {
16378            final long origId = Binder.clearCallingIdentity();
16379            updateConfigurationLocked(values, null, true, false);
16380            Binder.restoreCallingIdentity(origId);
16381        }
16382    }
16383
16384    public void updateConfiguration(Configuration values) {
16385        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16386                "updateConfiguration()");
16387
16388        synchronized(this) {
16389            if (values == null && mWindowManager != null) {
16390                // sentinel: fetch the current configuration from the window manager
16391                values = mWindowManager.computeNewConfiguration();
16392            }
16393
16394            if (mWindowManager != null) {
16395                mProcessList.applyDisplaySize(mWindowManager);
16396            }
16397
16398            final long origId = Binder.clearCallingIdentity();
16399            if (values != null) {
16400                Settings.System.clearConfiguration(values);
16401            }
16402            updateConfigurationLocked(values, null, false, false);
16403            Binder.restoreCallingIdentity(origId);
16404        }
16405    }
16406
16407    /**
16408     * Do either or both things: (1) change the current configuration, and (2)
16409     * make sure the given activity is running with the (now) current
16410     * configuration.  Returns true if the activity has been left running, or
16411     * false if <var>starting</var> is being destroyed to match the new
16412     * configuration.
16413     * @param persistent TODO
16414     */
16415    boolean updateConfigurationLocked(Configuration values,
16416            ActivityRecord starting, boolean persistent, boolean initLocale) {
16417        int changes = 0;
16418
16419        if (values != null) {
16420            Configuration newConfig = new Configuration(mConfiguration);
16421            changes = newConfig.updateFrom(values);
16422            if (changes != 0) {
16423                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16424                    Slog.i(TAG, "Updating configuration to: " + values);
16425                }
16426
16427                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16428
16429                if (values.locale != null && !initLocale) {
16430                    saveLocaleLocked(values.locale,
16431                                     !values.locale.equals(mConfiguration.locale),
16432                                     values.userSetLocale);
16433                }
16434
16435                mConfigurationSeq++;
16436                if (mConfigurationSeq <= 0) {
16437                    mConfigurationSeq = 1;
16438                }
16439                newConfig.seq = mConfigurationSeq;
16440                mConfiguration = newConfig;
16441                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16442                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16443                //mUsageStatsService.noteStartConfig(newConfig);
16444
16445                final Configuration configCopy = new Configuration(mConfiguration);
16446
16447                // TODO: If our config changes, should we auto dismiss any currently
16448                // showing dialogs?
16449                mShowDialogs = shouldShowDialogs(newConfig);
16450
16451                AttributeCache ac = AttributeCache.instance();
16452                if (ac != null) {
16453                    ac.updateConfiguration(configCopy);
16454                }
16455
16456                // Make sure all resources in our process are updated
16457                // right now, so that anyone who is going to retrieve
16458                // resource values after we return will be sure to get
16459                // the new ones.  This is especially important during
16460                // boot, where the first config change needs to guarantee
16461                // all resources have that config before following boot
16462                // code is executed.
16463                mSystemThread.applyConfigurationToResources(configCopy);
16464
16465                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16466                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16467                    msg.obj = new Configuration(configCopy);
16468                    mHandler.sendMessage(msg);
16469                }
16470
16471                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16472                    ProcessRecord app = mLruProcesses.get(i);
16473                    try {
16474                        if (app.thread != null) {
16475                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16476                                    + app.processName + " new config " + mConfiguration);
16477                            app.thread.scheduleConfigurationChanged(configCopy);
16478                        }
16479                    } catch (Exception e) {
16480                    }
16481                }
16482                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16483                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16484                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16485                        | Intent.FLAG_RECEIVER_FOREGROUND);
16486                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16487                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16488                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16489                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16490                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16491                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16492                    broadcastIntentLocked(null, null, intent,
16493                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16494                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16495                }
16496            }
16497        }
16498
16499        boolean kept = true;
16500        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16501        // mainStack is null during startup.
16502        if (mainStack != null) {
16503            if (changes != 0 && starting == null) {
16504                // If the configuration changed, and the caller is not already
16505                // in the process of starting an activity, then find the top
16506                // activity to check if its configuration needs to change.
16507                starting = mainStack.topRunningActivityLocked(null);
16508            }
16509
16510            if (starting != null) {
16511                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16512                // And we need to make sure at this point that all other activities
16513                // are made visible with the correct configuration.
16514                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16515            }
16516        }
16517
16518        if (values != null && mWindowManager != null) {
16519            mWindowManager.setNewConfiguration(mConfiguration);
16520        }
16521
16522        return kept;
16523    }
16524
16525    /**
16526     * Decide based on the configuration whether we should shouw the ANR,
16527     * crash, etc dialogs.  The idea is that if there is no affordnace to
16528     * press the on-screen buttons, we shouldn't show the dialog.
16529     *
16530     * A thought: SystemUI might also want to get told about this, the Power
16531     * dialog / global actions also might want different behaviors.
16532     */
16533    private static final boolean shouldShowDialogs(Configuration config) {
16534        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16535                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16536    }
16537
16538    /**
16539     * Save the locale.  You must be inside a synchronized (this) block.
16540     */
16541    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16542        if(isDiff) {
16543            SystemProperties.set("user.language", l.getLanguage());
16544            SystemProperties.set("user.region", l.getCountry());
16545        }
16546
16547        if(isPersist) {
16548            SystemProperties.set("persist.sys.language", l.getLanguage());
16549            SystemProperties.set("persist.sys.country", l.getCountry());
16550            SystemProperties.set("persist.sys.localevar", l.getVariant());
16551
16552            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16553        }
16554    }
16555
16556    @Override
16557    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16558        synchronized (this) {
16559            ActivityRecord srec = ActivityRecord.forToken(token);
16560            if (srec.task != null && srec.task.stack != null) {
16561                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16562            }
16563        }
16564        return false;
16565    }
16566
16567    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16568            Intent resultData) {
16569
16570        synchronized (this) {
16571            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16572            if (stack != null) {
16573                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16574            }
16575            return false;
16576        }
16577    }
16578
16579    public int getLaunchedFromUid(IBinder activityToken) {
16580        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16581        if (srec == null) {
16582            return -1;
16583        }
16584        return srec.launchedFromUid;
16585    }
16586
16587    public String getLaunchedFromPackage(IBinder activityToken) {
16588        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16589        if (srec == null) {
16590            return null;
16591        }
16592        return srec.launchedFromPackage;
16593    }
16594
16595    // =========================================================
16596    // LIFETIME MANAGEMENT
16597    // =========================================================
16598
16599    // Returns which broadcast queue the app is the current [or imminent] receiver
16600    // on, or 'null' if the app is not an active broadcast recipient.
16601    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16602        BroadcastRecord r = app.curReceiver;
16603        if (r != null) {
16604            return r.queue;
16605        }
16606
16607        // It's not the current receiver, but it might be starting up to become one
16608        synchronized (this) {
16609            for (BroadcastQueue queue : mBroadcastQueues) {
16610                r = queue.mPendingBroadcast;
16611                if (r != null && r.curApp == app) {
16612                    // found it; report which queue it's in
16613                    return queue;
16614                }
16615            }
16616        }
16617
16618        return null;
16619    }
16620
16621    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16622            boolean doingAll, long now) {
16623        if (mAdjSeq == app.adjSeq) {
16624            // This adjustment has already been computed.
16625            return app.curRawAdj;
16626        }
16627
16628        if (app.thread == null) {
16629            app.adjSeq = mAdjSeq;
16630            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16631            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16632            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16633        }
16634
16635        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16636        app.adjSource = null;
16637        app.adjTarget = null;
16638        app.empty = false;
16639        app.cached = false;
16640
16641        final int activitiesSize = app.activities.size();
16642
16643        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16644            // The max adjustment doesn't allow this app to be anything
16645            // below foreground, so it is not worth doing work for it.
16646            app.adjType = "fixed";
16647            app.adjSeq = mAdjSeq;
16648            app.curRawAdj = app.maxAdj;
16649            app.foregroundActivities = false;
16650            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16651            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16652            // System processes can do UI, and when they do we want to have
16653            // them trim their memory after the user leaves the UI.  To
16654            // facilitate this, here we need to determine whether or not it
16655            // is currently showing UI.
16656            app.systemNoUi = true;
16657            if (app == TOP_APP) {
16658                app.systemNoUi = false;
16659            } else if (activitiesSize > 0) {
16660                for (int j = 0; j < activitiesSize; j++) {
16661                    final ActivityRecord r = app.activities.get(j);
16662                    if (r.visible) {
16663                        app.systemNoUi = false;
16664                    }
16665                }
16666            }
16667            if (!app.systemNoUi) {
16668                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16669            }
16670            return (app.curAdj=app.maxAdj);
16671        }
16672
16673        app.systemNoUi = false;
16674
16675        // Determine the importance of the process, starting with most
16676        // important to least, and assign an appropriate OOM adjustment.
16677        int adj;
16678        int schedGroup;
16679        int procState;
16680        boolean foregroundActivities = false;
16681        BroadcastQueue queue;
16682        if (app == TOP_APP) {
16683            // The last app on the list is the foreground app.
16684            adj = ProcessList.FOREGROUND_APP_ADJ;
16685            schedGroup = Process.THREAD_GROUP_DEFAULT;
16686            app.adjType = "top-activity";
16687            foregroundActivities = true;
16688            procState = ActivityManager.PROCESS_STATE_TOP;
16689        } else if (app.instrumentationClass != null) {
16690            // Don't want to kill running instrumentation.
16691            adj = ProcessList.FOREGROUND_APP_ADJ;
16692            schedGroup = Process.THREAD_GROUP_DEFAULT;
16693            app.adjType = "instrumentation";
16694            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16695        } else if ((queue = isReceivingBroadcast(app)) != null) {
16696            // An app that is currently receiving a broadcast also
16697            // counts as being in the foreground for OOM killer purposes.
16698            // It's placed in a sched group based on the nature of the
16699            // broadcast as reflected by which queue it's active in.
16700            adj = ProcessList.FOREGROUND_APP_ADJ;
16701            schedGroup = (queue == mFgBroadcastQueue)
16702                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16703            app.adjType = "broadcast";
16704            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16705        } else if (app.executingServices.size() > 0) {
16706            // An app that is currently executing a service callback also
16707            // counts as being in the foreground.
16708            adj = ProcessList.FOREGROUND_APP_ADJ;
16709            schedGroup = app.execServicesFg ?
16710                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16711            app.adjType = "exec-service";
16712            procState = ActivityManager.PROCESS_STATE_SERVICE;
16713            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16714        } else {
16715            // As far as we know the process is empty.  We may change our mind later.
16716            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16717            // At this point we don't actually know the adjustment.  Use the cached adj
16718            // value that the caller wants us to.
16719            adj = cachedAdj;
16720            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16721            app.cached = true;
16722            app.empty = true;
16723            app.adjType = "cch-empty";
16724        }
16725
16726        // Examine all activities if not already foreground.
16727        if (!foregroundActivities && activitiesSize > 0) {
16728            for (int j = 0; j < activitiesSize; j++) {
16729                final ActivityRecord r = app.activities.get(j);
16730                if (r.app != app) {
16731                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16732                            + app + "?!?");
16733                    continue;
16734                }
16735                if (r.visible) {
16736                    // App has a visible activity; only upgrade adjustment.
16737                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16738                        adj = ProcessList.VISIBLE_APP_ADJ;
16739                        app.adjType = "visible";
16740                    }
16741                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16742                        procState = ActivityManager.PROCESS_STATE_TOP;
16743                    }
16744                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16745                    app.cached = false;
16746                    app.empty = false;
16747                    foregroundActivities = true;
16748                    break;
16749                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16750                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16751                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16752                        app.adjType = "pausing";
16753                    }
16754                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16755                        procState = ActivityManager.PROCESS_STATE_TOP;
16756                    }
16757                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16758                    app.cached = false;
16759                    app.empty = false;
16760                    foregroundActivities = true;
16761                } else if (r.state == ActivityState.STOPPING) {
16762                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16763                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16764                        app.adjType = "stopping";
16765                    }
16766                    // For the process state, we will at this point consider the
16767                    // process to be cached.  It will be cached either as an activity
16768                    // or empty depending on whether the activity is finishing.  We do
16769                    // this so that we can treat the process as cached for purposes of
16770                    // memory trimming (determing current memory level, trim command to
16771                    // send to process) since there can be an arbitrary number of stopping
16772                    // processes and they should soon all go into the cached state.
16773                    if (!r.finishing) {
16774                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16775                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16776                        }
16777                    }
16778                    app.cached = false;
16779                    app.empty = false;
16780                    foregroundActivities = true;
16781                } else {
16782                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16783                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16784                        app.adjType = "cch-act";
16785                    }
16786                }
16787            }
16788        }
16789
16790        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16791            if (app.foregroundServices) {
16792                // The user is aware of this app, so make it visible.
16793                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16794                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16795                app.cached = false;
16796                app.adjType = "fg-service";
16797                schedGroup = Process.THREAD_GROUP_DEFAULT;
16798            } else if (app.forcingToForeground != null) {
16799                // The user is aware of this app, so make it visible.
16800                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16801                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16802                app.cached = false;
16803                app.adjType = "force-fg";
16804                app.adjSource = app.forcingToForeground;
16805                schedGroup = Process.THREAD_GROUP_DEFAULT;
16806            }
16807        }
16808
16809        if (app == mHeavyWeightProcess) {
16810            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16811                // We don't want to kill the current heavy-weight process.
16812                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16813                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16814                app.cached = false;
16815                app.adjType = "heavy";
16816            }
16817            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16818                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16819            }
16820        }
16821
16822        if (app == mHomeProcess) {
16823            if (adj > ProcessList.HOME_APP_ADJ) {
16824                // This process is hosting what we currently consider to be the
16825                // home app, so we don't want to let it go into the background.
16826                adj = ProcessList.HOME_APP_ADJ;
16827                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16828                app.cached = false;
16829                app.adjType = "home";
16830            }
16831            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16832                procState = ActivityManager.PROCESS_STATE_HOME;
16833            }
16834        }
16835
16836        if (app == mPreviousProcess && app.activities.size() > 0) {
16837            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16838                // This was the previous process that showed UI to the user.
16839                // We want to try to keep it around more aggressively, to give
16840                // a good experience around switching between two apps.
16841                adj = ProcessList.PREVIOUS_APP_ADJ;
16842                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16843                app.cached = false;
16844                app.adjType = "previous";
16845            }
16846            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16847                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16848            }
16849        }
16850
16851        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16852                + " reason=" + app.adjType);
16853
16854        // By default, we use the computed adjustment.  It may be changed if
16855        // there are applications dependent on our services or providers, but
16856        // this gives us a baseline and makes sure we don't get into an
16857        // infinite recursion.
16858        app.adjSeq = mAdjSeq;
16859        app.curRawAdj = adj;
16860        app.hasStartedServices = false;
16861
16862        if (mBackupTarget != null && app == mBackupTarget.app) {
16863            // If possible we want to avoid killing apps while they're being backed up
16864            if (adj > ProcessList.BACKUP_APP_ADJ) {
16865                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16866                adj = ProcessList.BACKUP_APP_ADJ;
16867                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16868                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16869                }
16870                app.adjType = "backup";
16871                app.cached = false;
16872            }
16873            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16874                procState = ActivityManager.PROCESS_STATE_BACKUP;
16875            }
16876        }
16877
16878        boolean mayBeTop = false;
16879
16880        for (int is = app.services.size()-1;
16881                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16882                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16883                        || procState > ActivityManager.PROCESS_STATE_TOP);
16884                is--) {
16885            ServiceRecord s = app.services.valueAt(is);
16886            if (s.startRequested) {
16887                app.hasStartedServices = true;
16888                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16889                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16890                }
16891                if (app.hasShownUi && app != mHomeProcess) {
16892                    // If this process has shown some UI, let it immediately
16893                    // go to the LRU list because it may be pretty heavy with
16894                    // UI stuff.  We'll tag it with a label just to help
16895                    // debug and understand what is going on.
16896                    if (adj > ProcessList.SERVICE_ADJ) {
16897                        app.adjType = "cch-started-ui-services";
16898                    }
16899                } else {
16900                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16901                        // This service has seen some activity within
16902                        // recent memory, so we will keep its process ahead
16903                        // of the background processes.
16904                        if (adj > ProcessList.SERVICE_ADJ) {
16905                            adj = ProcessList.SERVICE_ADJ;
16906                            app.adjType = "started-services";
16907                            app.cached = false;
16908                        }
16909                    }
16910                    // If we have let the service slide into the background
16911                    // state, still have some text describing what it is doing
16912                    // even though the service no longer has an impact.
16913                    if (adj > ProcessList.SERVICE_ADJ) {
16914                        app.adjType = "cch-started-services";
16915                    }
16916                }
16917            }
16918            for (int conni = s.connections.size()-1;
16919                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16920                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16921                            || procState > ActivityManager.PROCESS_STATE_TOP);
16922                    conni--) {
16923                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16924                for (int i = 0;
16925                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16926                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16927                                || procState > ActivityManager.PROCESS_STATE_TOP);
16928                        i++) {
16929                    // XXX should compute this based on the max of
16930                    // all connected clients.
16931                    ConnectionRecord cr = clist.get(i);
16932                    if (cr.binding.client == app) {
16933                        // Binding to ourself is not interesting.
16934                        continue;
16935                    }
16936                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16937                        ProcessRecord client = cr.binding.client;
16938                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16939                                TOP_APP, doingAll, now);
16940                        int clientProcState = client.curProcState;
16941                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16942                            // If the other app is cached for any reason, for purposes here
16943                            // we are going to consider it empty.  The specific cached state
16944                            // doesn't propagate except under certain conditions.
16945                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16946                        }
16947                        String adjType = null;
16948                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16949                            // Not doing bind OOM management, so treat
16950                            // this guy more like a started service.
16951                            if (app.hasShownUi && app != mHomeProcess) {
16952                                // If this process has shown some UI, let it immediately
16953                                // go to the LRU list because it may be pretty heavy with
16954                                // UI stuff.  We'll tag it with a label just to help
16955                                // debug and understand what is going on.
16956                                if (adj > clientAdj) {
16957                                    adjType = "cch-bound-ui-services";
16958                                }
16959                                app.cached = false;
16960                                clientAdj = adj;
16961                                clientProcState = procState;
16962                            } else {
16963                                if (now >= (s.lastActivity
16964                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16965                                    // This service has not seen activity within
16966                                    // recent memory, so allow it to drop to the
16967                                    // LRU list if there is no other reason to keep
16968                                    // it around.  We'll also tag it with a label just
16969                                    // to help debug and undertand what is going on.
16970                                    if (adj > clientAdj) {
16971                                        adjType = "cch-bound-services";
16972                                    }
16973                                    clientAdj = adj;
16974                                }
16975                            }
16976                        }
16977                        if (adj > clientAdj) {
16978                            // If this process has recently shown UI, and
16979                            // the process that is binding to it is less
16980                            // important than being visible, then we don't
16981                            // care about the binding as much as we care
16982                            // about letting this process get into the LRU
16983                            // list to be killed and restarted if needed for
16984                            // memory.
16985                            if (app.hasShownUi && app != mHomeProcess
16986                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16987                                adjType = "cch-bound-ui-services";
16988                            } else {
16989                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16990                                        |Context.BIND_IMPORTANT)) != 0) {
16991                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16992                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16993                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16994                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16995                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16996                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16997                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16998                                    adj = clientAdj;
16999                                } else {
17000                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17001                                        adj = ProcessList.VISIBLE_APP_ADJ;
17002                                    }
17003                                }
17004                                if (!client.cached) {
17005                                    app.cached = false;
17006                                }
17007                                adjType = "service";
17008                            }
17009                        }
17010                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17011                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17012                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17013                            }
17014                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17015                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17016                                    // Special handling of clients who are in the top state.
17017                                    // We *may* want to consider this process to be in the
17018                                    // top state as well, but only if there is not another
17019                                    // reason for it to be running.  Being on the top is a
17020                                    // special state, meaning you are specifically running
17021                                    // for the current top app.  If the process is already
17022                                    // running in the background for some other reason, it
17023                                    // is more important to continue considering it to be
17024                                    // in the background state.
17025                                    mayBeTop = true;
17026                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17027                                } else {
17028                                    // Special handling for above-top states (persistent
17029                                    // processes).  These should not bring the current process
17030                                    // into the top state, since they are not on top.  Instead
17031                                    // give them the best state after that.
17032                                    clientProcState =
17033                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17034                                }
17035                            }
17036                        } else {
17037                            if (clientProcState <
17038                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17039                                clientProcState =
17040                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17041                            }
17042                        }
17043                        if (procState > clientProcState) {
17044                            procState = clientProcState;
17045                        }
17046                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17047                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17048                            app.pendingUiClean = true;
17049                        }
17050                        if (adjType != null) {
17051                            app.adjType = adjType;
17052                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17053                                    .REASON_SERVICE_IN_USE;
17054                            app.adjSource = cr.binding.client;
17055                            app.adjSourceProcState = clientProcState;
17056                            app.adjTarget = s.name;
17057                        }
17058                    }
17059                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17060                        app.treatLikeActivity = true;
17061                    }
17062                    final ActivityRecord a = cr.activity;
17063                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17064                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17065                                (a.visible || a.state == ActivityState.RESUMED
17066                                 || a.state == ActivityState.PAUSING)) {
17067                            adj = ProcessList.FOREGROUND_APP_ADJ;
17068                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17069                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17070                            }
17071                            app.cached = false;
17072                            app.adjType = "service";
17073                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17074                                    .REASON_SERVICE_IN_USE;
17075                            app.adjSource = a;
17076                            app.adjSourceProcState = procState;
17077                            app.adjTarget = s.name;
17078                        }
17079                    }
17080                }
17081            }
17082        }
17083
17084        for (int provi = app.pubProviders.size()-1;
17085                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17086                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17087                        || procState > ActivityManager.PROCESS_STATE_TOP);
17088                provi--) {
17089            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17090            for (int i = cpr.connections.size()-1;
17091                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17092                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17093                            || procState > ActivityManager.PROCESS_STATE_TOP);
17094                    i--) {
17095                ContentProviderConnection conn = cpr.connections.get(i);
17096                ProcessRecord client = conn.client;
17097                if (client == app) {
17098                    // Being our own client is not interesting.
17099                    continue;
17100                }
17101                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17102                int clientProcState = client.curProcState;
17103                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17104                    // If the other app is cached for any reason, for purposes here
17105                    // we are going to consider it empty.
17106                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17107                }
17108                if (adj > clientAdj) {
17109                    if (app.hasShownUi && app != mHomeProcess
17110                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17111                        app.adjType = "cch-ui-provider";
17112                    } else {
17113                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17114                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17115                        app.adjType = "provider";
17116                    }
17117                    app.cached &= client.cached;
17118                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17119                            .REASON_PROVIDER_IN_USE;
17120                    app.adjSource = client;
17121                    app.adjSourceProcState = clientProcState;
17122                    app.adjTarget = cpr.name;
17123                }
17124                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17125                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17126                        // Special handling of clients who are in the top state.
17127                        // We *may* want to consider this process to be in the
17128                        // top state as well, but only if there is not another
17129                        // reason for it to be running.  Being on the top is a
17130                        // special state, meaning you are specifically running
17131                        // for the current top app.  If the process is already
17132                        // running in the background for some other reason, it
17133                        // is more important to continue considering it to be
17134                        // in the background state.
17135                        mayBeTop = true;
17136                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17137                    } else {
17138                        // Special handling for above-top states (persistent
17139                        // processes).  These should not bring the current process
17140                        // into the top state, since they are not on top.  Instead
17141                        // give them the best state after that.
17142                        clientProcState =
17143                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17144                    }
17145                }
17146                if (procState > clientProcState) {
17147                    procState = clientProcState;
17148                }
17149                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17150                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17151                }
17152            }
17153            // If the provider has external (non-framework) process
17154            // dependencies, ensure that its adjustment is at least
17155            // FOREGROUND_APP_ADJ.
17156            if (cpr.hasExternalProcessHandles()) {
17157                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17158                    adj = ProcessList.FOREGROUND_APP_ADJ;
17159                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17160                    app.cached = false;
17161                    app.adjType = "provider";
17162                    app.adjTarget = cpr.name;
17163                }
17164                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17165                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17166                }
17167            }
17168        }
17169
17170        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17171            // A client of one of our services or providers is in the top state.  We
17172            // *may* want to be in the top state, but not if we are already running in
17173            // the background for some other reason.  For the decision here, we are going
17174            // to pick out a few specific states that we want to remain in when a client
17175            // is top (states that tend to be longer-term) and otherwise allow it to go
17176            // to the top state.
17177            switch (procState) {
17178                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17179                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17180                case ActivityManager.PROCESS_STATE_SERVICE:
17181                    // These all are longer-term states, so pull them up to the top
17182                    // of the background states, but not all the way to the top state.
17183                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17184                    break;
17185                default:
17186                    // Otherwise, top is a better choice, so take it.
17187                    procState = ActivityManager.PROCESS_STATE_TOP;
17188                    break;
17189            }
17190        }
17191
17192        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17193            if (app.hasClientActivities) {
17194                // This is a cached process, but with client activities.  Mark it so.
17195                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17196                app.adjType = "cch-client-act";
17197            } else if (app.treatLikeActivity) {
17198                // This is a cached process, but somebody wants us to treat it like it has
17199                // an activity, okay!
17200                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17201                app.adjType = "cch-as-act";
17202            }
17203        }
17204
17205        if (adj == ProcessList.SERVICE_ADJ) {
17206            if (doingAll) {
17207                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17208                mNewNumServiceProcs++;
17209                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17210                if (!app.serviceb) {
17211                    // This service isn't far enough down on the LRU list to
17212                    // normally be a B service, but if we are low on RAM and it
17213                    // is large we want to force it down since we would prefer to
17214                    // keep launcher over it.
17215                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17216                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17217                        app.serviceHighRam = true;
17218                        app.serviceb = true;
17219                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17220                    } else {
17221                        mNewNumAServiceProcs++;
17222                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17223                    }
17224                } else {
17225                    app.serviceHighRam = false;
17226                }
17227            }
17228            if (app.serviceb) {
17229                adj = ProcessList.SERVICE_B_ADJ;
17230            }
17231        }
17232
17233        app.curRawAdj = adj;
17234
17235        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17236        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17237        if (adj > app.maxAdj) {
17238            adj = app.maxAdj;
17239            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17240                schedGroup = Process.THREAD_GROUP_DEFAULT;
17241            }
17242        }
17243
17244        // Do final modification to adj.  Everything we do between here and applying
17245        // the final setAdj must be done in this function, because we will also use
17246        // it when computing the final cached adj later.  Note that we don't need to
17247        // worry about this for max adj above, since max adj will always be used to
17248        // keep it out of the cached vaues.
17249        app.curAdj = app.modifyRawOomAdj(adj);
17250        app.curSchedGroup = schedGroup;
17251        app.curProcState = procState;
17252        app.foregroundActivities = foregroundActivities;
17253
17254        return app.curRawAdj;
17255    }
17256
17257    /**
17258     * Schedule PSS collection of a process.
17259     */
17260    void requestPssLocked(ProcessRecord proc, int procState) {
17261        if (mPendingPssProcesses.contains(proc)) {
17262            return;
17263        }
17264        if (mPendingPssProcesses.size() == 0) {
17265            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17266        }
17267        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17268        proc.pssProcState = procState;
17269        mPendingPssProcesses.add(proc);
17270    }
17271
17272    /**
17273     * Schedule PSS collection of all processes.
17274     */
17275    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17276        if (!always) {
17277            if (now < (mLastFullPssTime +
17278                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17279                return;
17280            }
17281        }
17282        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17283        mLastFullPssTime = now;
17284        mFullPssPending = true;
17285        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17286        mPendingPssProcesses.clear();
17287        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17288            ProcessRecord app = mLruProcesses.get(i);
17289            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17290                app.pssProcState = app.setProcState;
17291                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17292                        isSleeping(), now);
17293                mPendingPssProcesses.add(app);
17294            }
17295        }
17296        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17297    }
17298
17299    /**
17300     * Ask a given process to GC right now.
17301     */
17302    final void performAppGcLocked(ProcessRecord app) {
17303        try {
17304            app.lastRequestedGc = SystemClock.uptimeMillis();
17305            if (app.thread != null) {
17306                if (app.reportLowMemory) {
17307                    app.reportLowMemory = false;
17308                    app.thread.scheduleLowMemory();
17309                } else {
17310                    app.thread.processInBackground();
17311                }
17312            }
17313        } catch (Exception e) {
17314            // whatever.
17315        }
17316    }
17317
17318    /**
17319     * Returns true if things are idle enough to perform GCs.
17320     */
17321    private final boolean canGcNowLocked() {
17322        boolean processingBroadcasts = false;
17323        for (BroadcastQueue q : mBroadcastQueues) {
17324            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17325                processingBroadcasts = true;
17326            }
17327        }
17328        return !processingBroadcasts
17329                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17330    }
17331
17332    /**
17333     * Perform GCs on all processes that are waiting for it, but only
17334     * if things are idle.
17335     */
17336    final void performAppGcsLocked() {
17337        final int N = mProcessesToGc.size();
17338        if (N <= 0) {
17339            return;
17340        }
17341        if (canGcNowLocked()) {
17342            while (mProcessesToGc.size() > 0) {
17343                ProcessRecord proc = mProcessesToGc.remove(0);
17344                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17345                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17346                            <= SystemClock.uptimeMillis()) {
17347                        // To avoid spamming the system, we will GC processes one
17348                        // at a time, waiting a few seconds between each.
17349                        performAppGcLocked(proc);
17350                        scheduleAppGcsLocked();
17351                        return;
17352                    } else {
17353                        // It hasn't been long enough since we last GCed this
17354                        // process...  put it in the list to wait for its time.
17355                        addProcessToGcListLocked(proc);
17356                        break;
17357                    }
17358                }
17359            }
17360
17361            scheduleAppGcsLocked();
17362        }
17363    }
17364
17365    /**
17366     * If all looks good, perform GCs on all processes waiting for them.
17367     */
17368    final void performAppGcsIfAppropriateLocked() {
17369        if (canGcNowLocked()) {
17370            performAppGcsLocked();
17371            return;
17372        }
17373        // Still not idle, wait some more.
17374        scheduleAppGcsLocked();
17375    }
17376
17377    /**
17378     * Schedule the execution of all pending app GCs.
17379     */
17380    final void scheduleAppGcsLocked() {
17381        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17382
17383        if (mProcessesToGc.size() > 0) {
17384            // Schedule a GC for the time to the next process.
17385            ProcessRecord proc = mProcessesToGc.get(0);
17386            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17387
17388            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17389            long now = SystemClock.uptimeMillis();
17390            if (when < (now+GC_TIMEOUT)) {
17391                when = now + GC_TIMEOUT;
17392            }
17393            mHandler.sendMessageAtTime(msg, when);
17394        }
17395    }
17396
17397    /**
17398     * Add a process to the array of processes waiting to be GCed.  Keeps the
17399     * list in sorted order by the last GC time.  The process can't already be
17400     * on the list.
17401     */
17402    final void addProcessToGcListLocked(ProcessRecord proc) {
17403        boolean added = false;
17404        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17405            if (mProcessesToGc.get(i).lastRequestedGc <
17406                    proc.lastRequestedGc) {
17407                added = true;
17408                mProcessesToGc.add(i+1, proc);
17409                break;
17410            }
17411        }
17412        if (!added) {
17413            mProcessesToGc.add(0, proc);
17414        }
17415    }
17416
17417    /**
17418     * Set up to ask a process to GC itself.  This will either do it
17419     * immediately, or put it on the list of processes to gc the next
17420     * time things are idle.
17421     */
17422    final void scheduleAppGcLocked(ProcessRecord app) {
17423        long now = SystemClock.uptimeMillis();
17424        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17425            return;
17426        }
17427        if (!mProcessesToGc.contains(app)) {
17428            addProcessToGcListLocked(app);
17429            scheduleAppGcsLocked();
17430        }
17431    }
17432
17433    final void checkExcessivePowerUsageLocked(boolean doKills) {
17434        updateCpuStatsNow();
17435
17436        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17437        boolean doWakeKills = doKills;
17438        boolean doCpuKills = doKills;
17439        if (mLastPowerCheckRealtime == 0) {
17440            doWakeKills = false;
17441        }
17442        if (mLastPowerCheckUptime == 0) {
17443            doCpuKills = false;
17444        }
17445        if (stats.isScreenOn()) {
17446            doWakeKills = false;
17447        }
17448        final long curRealtime = SystemClock.elapsedRealtime();
17449        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17450        final long curUptime = SystemClock.uptimeMillis();
17451        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17452        mLastPowerCheckRealtime = curRealtime;
17453        mLastPowerCheckUptime = curUptime;
17454        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17455            doWakeKills = false;
17456        }
17457        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17458            doCpuKills = false;
17459        }
17460        int i = mLruProcesses.size();
17461        while (i > 0) {
17462            i--;
17463            ProcessRecord app = mLruProcesses.get(i);
17464            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17465                long wtime;
17466                synchronized (stats) {
17467                    wtime = stats.getProcessWakeTime(app.info.uid,
17468                            app.pid, curRealtime);
17469                }
17470                long wtimeUsed = wtime - app.lastWakeTime;
17471                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17472                if (DEBUG_POWER) {
17473                    StringBuilder sb = new StringBuilder(128);
17474                    sb.append("Wake for ");
17475                    app.toShortString(sb);
17476                    sb.append(": over ");
17477                    TimeUtils.formatDuration(realtimeSince, sb);
17478                    sb.append(" used ");
17479                    TimeUtils.formatDuration(wtimeUsed, sb);
17480                    sb.append(" (");
17481                    sb.append((wtimeUsed*100)/realtimeSince);
17482                    sb.append("%)");
17483                    Slog.i(TAG, sb.toString());
17484                    sb.setLength(0);
17485                    sb.append("CPU for ");
17486                    app.toShortString(sb);
17487                    sb.append(": over ");
17488                    TimeUtils.formatDuration(uptimeSince, sb);
17489                    sb.append(" used ");
17490                    TimeUtils.formatDuration(cputimeUsed, sb);
17491                    sb.append(" (");
17492                    sb.append((cputimeUsed*100)/uptimeSince);
17493                    sb.append("%)");
17494                    Slog.i(TAG, sb.toString());
17495                }
17496                // If a process has held a wake lock for more
17497                // than 50% of the time during this period,
17498                // that sounds bad.  Kill!
17499                if (doWakeKills && realtimeSince > 0
17500                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17501                    synchronized (stats) {
17502                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17503                                realtimeSince, wtimeUsed);
17504                    }
17505                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17506                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17507                } else if (doCpuKills && uptimeSince > 0
17508                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17509                    synchronized (stats) {
17510                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17511                                uptimeSince, cputimeUsed);
17512                    }
17513                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17514                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17515                } else {
17516                    app.lastWakeTime = wtime;
17517                    app.lastCpuTime = app.curCpuTime;
17518                }
17519            }
17520        }
17521    }
17522
17523    private final boolean applyOomAdjLocked(ProcessRecord app,
17524            ProcessRecord TOP_APP, boolean doingAll, long now) {
17525        boolean success = true;
17526
17527        if (app.curRawAdj != app.setRawAdj) {
17528            app.setRawAdj = app.curRawAdj;
17529        }
17530
17531        int changes = 0;
17532
17533        if (app.curAdj != app.setAdj) {
17534            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17535            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17536                TAG, "Set " + app.pid + " " + app.processName +
17537                " adj " + app.curAdj + ": " + app.adjType);
17538            app.setAdj = app.curAdj;
17539        }
17540
17541        if (app.setSchedGroup != app.curSchedGroup) {
17542            app.setSchedGroup = app.curSchedGroup;
17543            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17544                    "Setting process group of " + app.processName
17545                    + " to " + app.curSchedGroup);
17546            if (app.waitingToKill != null &&
17547                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17548                app.kill(app.waitingToKill, true);
17549                success = false;
17550            } else {
17551                if (true) {
17552                    long oldId = Binder.clearCallingIdentity();
17553                    try {
17554                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17555                    } catch (Exception e) {
17556                        Slog.w(TAG, "Failed setting process group of " + app.pid
17557                                + " to " + app.curSchedGroup);
17558                        e.printStackTrace();
17559                    } finally {
17560                        Binder.restoreCallingIdentity(oldId);
17561                    }
17562                } else {
17563                    if (app.thread != null) {
17564                        try {
17565                            app.thread.setSchedulingGroup(app.curSchedGroup);
17566                        } catch (RemoteException e) {
17567                        }
17568                    }
17569                }
17570                Process.setSwappiness(app.pid,
17571                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17572            }
17573        }
17574        if (app.repForegroundActivities != app.foregroundActivities) {
17575            app.repForegroundActivities = app.foregroundActivities;
17576            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17577        }
17578        if (app.repProcState != app.curProcState) {
17579            app.repProcState = app.curProcState;
17580            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17581            if (app.thread != null) {
17582                try {
17583                    if (false) {
17584                        //RuntimeException h = new RuntimeException("here");
17585                        Slog.i(TAG, "Sending new process state " + app.repProcState
17586                                + " to " + app /*, h*/);
17587                    }
17588                    app.thread.setProcessState(app.repProcState);
17589                } catch (RemoteException e) {
17590                }
17591            }
17592        }
17593        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17594                app.setProcState)) {
17595            app.lastStateTime = now;
17596            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17597                    isSleeping(), now);
17598            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17599                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17600                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17601                    + (app.nextPssTime-now) + ": " + app);
17602        } else {
17603            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17604                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17605                requestPssLocked(app, app.setProcState);
17606                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17607                        isSleeping(), now);
17608            } else if (false && DEBUG_PSS) {
17609                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17610            }
17611        }
17612        if (app.setProcState != app.curProcState) {
17613            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17614                    "Proc state change of " + app.processName
17615                    + " to " + app.curProcState);
17616            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17617            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17618            if (setImportant && !curImportant) {
17619                // This app is no longer something we consider important enough to allow to
17620                // use arbitrary amounts of battery power.  Note
17621                // its current wake lock time to later know to kill it if
17622                // it is not behaving well.
17623                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17624                synchronized (stats) {
17625                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17626                            app.pid, SystemClock.elapsedRealtime());
17627                }
17628                app.lastCpuTime = app.curCpuTime;
17629
17630            }
17631            app.setProcState = app.curProcState;
17632            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17633                app.notCachedSinceIdle = false;
17634            }
17635            if (!doingAll) {
17636                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17637            } else {
17638                app.procStateChanged = true;
17639            }
17640        }
17641
17642        if (changes != 0) {
17643            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17644            int i = mPendingProcessChanges.size()-1;
17645            ProcessChangeItem item = null;
17646            while (i >= 0) {
17647                item = mPendingProcessChanges.get(i);
17648                if (item.pid == app.pid) {
17649                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17650                    break;
17651                }
17652                i--;
17653            }
17654            if (i < 0) {
17655                // No existing item in pending changes; need a new one.
17656                final int NA = mAvailProcessChanges.size();
17657                if (NA > 0) {
17658                    item = mAvailProcessChanges.remove(NA-1);
17659                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17660                } else {
17661                    item = new ProcessChangeItem();
17662                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17663                }
17664                item.changes = 0;
17665                item.pid = app.pid;
17666                item.uid = app.info.uid;
17667                if (mPendingProcessChanges.size() == 0) {
17668                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17669                            "*** Enqueueing dispatch processes changed!");
17670                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17671                }
17672                mPendingProcessChanges.add(item);
17673            }
17674            item.changes |= changes;
17675            item.processState = app.repProcState;
17676            item.foregroundActivities = app.repForegroundActivities;
17677            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17678                    + Integer.toHexString(System.identityHashCode(item))
17679                    + " " + app.toShortString() + ": changes=" + item.changes
17680                    + " procState=" + item.processState
17681                    + " foreground=" + item.foregroundActivities
17682                    + " type=" + app.adjType + " source=" + app.adjSource
17683                    + " target=" + app.adjTarget);
17684        }
17685
17686        return success;
17687    }
17688
17689    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17690        if (proc.thread != null) {
17691            if (proc.baseProcessTracker != null) {
17692                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17693            }
17694            if (proc.repProcState >= 0) {
17695                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17696                        proc.repProcState);
17697            }
17698        }
17699    }
17700
17701    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17702            ProcessRecord TOP_APP, boolean doingAll, long now) {
17703        if (app.thread == null) {
17704            return false;
17705        }
17706
17707        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17708
17709        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17710    }
17711
17712    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17713            boolean oomAdj) {
17714        if (isForeground != proc.foregroundServices) {
17715            proc.foregroundServices = isForeground;
17716            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17717                    proc.info.uid);
17718            if (isForeground) {
17719                if (curProcs == null) {
17720                    curProcs = new ArrayList<ProcessRecord>();
17721                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17722                }
17723                if (!curProcs.contains(proc)) {
17724                    curProcs.add(proc);
17725                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17726                            proc.info.packageName, proc.info.uid);
17727                }
17728            } else {
17729                if (curProcs != null) {
17730                    if (curProcs.remove(proc)) {
17731                        mBatteryStatsService.noteEvent(
17732                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17733                                proc.info.packageName, proc.info.uid);
17734                        if (curProcs.size() <= 0) {
17735                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17736                        }
17737                    }
17738                }
17739            }
17740            if (oomAdj) {
17741                updateOomAdjLocked();
17742            }
17743        }
17744    }
17745
17746    private final ActivityRecord resumedAppLocked() {
17747        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17748        String pkg;
17749        int uid;
17750        if (act != null) {
17751            pkg = act.packageName;
17752            uid = act.info.applicationInfo.uid;
17753        } else {
17754            pkg = null;
17755            uid = -1;
17756        }
17757        // Has the UID or resumed package name changed?
17758        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17759                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17760            if (mCurResumedPackage != null) {
17761                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17762                        mCurResumedPackage, mCurResumedUid);
17763            }
17764            mCurResumedPackage = pkg;
17765            mCurResumedUid = uid;
17766            if (mCurResumedPackage != null) {
17767                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17768                        mCurResumedPackage, mCurResumedUid);
17769            }
17770        }
17771        return act;
17772    }
17773
17774    final boolean updateOomAdjLocked(ProcessRecord app) {
17775        final ActivityRecord TOP_ACT = resumedAppLocked();
17776        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17777        final boolean wasCached = app.cached;
17778
17779        mAdjSeq++;
17780
17781        // This is the desired cached adjusment we want to tell it to use.
17782        // If our app is currently cached, we know it, and that is it.  Otherwise,
17783        // we don't know it yet, and it needs to now be cached we will then
17784        // need to do a complete oom adj.
17785        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17786                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17787        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17788                SystemClock.uptimeMillis());
17789        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17790            // Changed to/from cached state, so apps after it in the LRU
17791            // list may also be changed.
17792            updateOomAdjLocked();
17793        }
17794        return success;
17795    }
17796
17797    final void updateOomAdjLocked() {
17798        final ActivityRecord TOP_ACT = resumedAppLocked();
17799        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17800        final long now = SystemClock.uptimeMillis();
17801        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17802        final int N = mLruProcesses.size();
17803
17804        if (false) {
17805            RuntimeException e = new RuntimeException();
17806            e.fillInStackTrace();
17807            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17808        }
17809
17810        mAdjSeq++;
17811        mNewNumServiceProcs = 0;
17812        mNewNumAServiceProcs = 0;
17813
17814        final int emptyProcessLimit;
17815        final int cachedProcessLimit;
17816        if (mProcessLimit <= 0) {
17817            emptyProcessLimit = cachedProcessLimit = 0;
17818        } else if (mProcessLimit == 1) {
17819            emptyProcessLimit = 1;
17820            cachedProcessLimit = 0;
17821        } else {
17822            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17823            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17824        }
17825
17826        // Let's determine how many processes we have running vs.
17827        // how many slots we have for background processes; we may want
17828        // to put multiple processes in a slot of there are enough of
17829        // them.
17830        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17831                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17832        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17833        if (numEmptyProcs > cachedProcessLimit) {
17834            // If there are more empty processes than our limit on cached
17835            // processes, then use the cached process limit for the factor.
17836            // This ensures that the really old empty processes get pushed
17837            // down to the bottom, so if we are running low on memory we will
17838            // have a better chance at keeping around more cached processes
17839            // instead of a gazillion empty processes.
17840            numEmptyProcs = cachedProcessLimit;
17841        }
17842        int emptyFactor = numEmptyProcs/numSlots;
17843        if (emptyFactor < 1) emptyFactor = 1;
17844        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17845        if (cachedFactor < 1) cachedFactor = 1;
17846        int stepCached = 0;
17847        int stepEmpty = 0;
17848        int numCached = 0;
17849        int numEmpty = 0;
17850        int numTrimming = 0;
17851
17852        mNumNonCachedProcs = 0;
17853        mNumCachedHiddenProcs = 0;
17854
17855        // First update the OOM adjustment for each of the
17856        // application processes based on their current state.
17857        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17858        int nextCachedAdj = curCachedAdj+1;
17859        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17860        int nextEmptyAdj = curEmptyAdj+2;
17861        for (int i=N-1; i>=0; i--) {
17862            ProcessRecord app = mLruProcesses.get(i);
17863            if (!app.killedByAm && app.thread != null) {
17864                app.procStateChanged = false;
17865                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17866
17867                // If we haven't yet assigned the final cached adj
17868                // to the process, do that now.
17869                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17870                    switch (app.curProcState) {
17871                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17872                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17873                            // This process is a cached process holding activities...
17874                            // assign it the next cached value for that type, and then
17875                            // step that cached level.
17876                            app.curRawAdj = curCachedAdj;
17877                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17878                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17879                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17880                                    + ")");
17881                            if (curCachedAdj != nextCachedAdj) {
17882                                stepCached++;
17883                                if (stepCached >= cachedFactor) {
17884                                    stepCached = 0;
17885                                    curCachedAdj = nextCachedAdj;
17886                                    nextCachedAdj += 2;
17887                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17888                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17889                                    }
17890                                }
17891                            }
17892                            break;
17893                        default:
17894                            // For everything else, assign next empty cached process
17895                            // level and bump that up.  Note that this means that
17896                            // long-running services that have dropped down to the
17897                            // cached level will be treated as empty (since their process
17898                            // state is still as a service), which is what we want.
17899                            app.curRawAdj = curEmptyAdj;
17900                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17901                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17902                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17903                                    + ")");
17904                            if (curEmptyAdj != nextEmptyAdj) {
17905                                stepEmpty++;
17906                                if (stepEmpty >= emptyFactor) {
17907                                    stepEmpty = 0;
17908                                    curEmptyAdj = nextEmptyAdj;
17909                                    nextEmptyAdj += 2;
17910                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17911                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17912                                    }
17913                                }
17914                            }
17915                            break;
17916                    }
17917                }
17918
17919                applyOomAdjLocked(app, TOP_APP, true, now);
17920
17921                // Count the number of process types.
17922                switch (app.curProcState) {
17923                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17924                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17925                        mNumCachedHiddenProcs++;
17926                        numCached++;
17927                        if (numCached > cachedProcessLimit) {
17928                            app.kill("cached #" + numCached, true);
17929                        }
17930                        break;
17931                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17932                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17933                                && app.lastActivityTime < oldTime) {
17934                            app.kill("empty for "
17935                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17936                                    / 1000) + "s", true);
17937                        } else {
17938                            numEmpty++;
17939                            if (numEmpty > emptyProcessLimit) {
17940                                app.kill("empty #" + numEmpty, true);
17941                            }
17942                        }
17943                        break;
17944                    default:
17945                        mNumNonCachedProcs++;
17946                        break;
17947                }
17948
17949                if (app.isolated && app.services.size() <= 0) {
17950                    // If this is an isolated process, and there are no
17951                    // services running in it, then the process is no longer
17952                    // needed.  We agressively kill these because we can by
17953                    // definition not re-use the same process again, and it is
17954                    // good to avoid having whatever code was running in them
17955                    // left sitting around after no longer needed.
17956                    app.kill("isolated not needed", true);
17957                }
17958
17959                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17960                        && !app.killedByAm) {
17961                    numTrimming++;
17962                }
17963            }
17964        }
17965
17966        mNumServiceProcs = mNewNumServiceProcs;
17967
17968        // Now determine the memory trimming level of background processes.
17969        // Unfortunately we need to start at the back of the list to do this
17970        // properly.  We only do this if the number of background apps we
17971        // are managing to keep around is less than half the maximum we desire;
17972        // if we are keeping a good number around, we'll let them use whatever
17973        // memory they want.
17974        final int numCachedAndEmpty = numCached + numEmpty;
17975        int memFactor;
17976        if (numCached <= ProcessList.TRIM_CACHED_APPS
17977                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17978            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17979                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17980            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17981                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17982            } else {
17983                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17984            }
17985        } else {
17986            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17987        }
17988        // We always allow the memory level to go up (better).  We only allow it to go
17989        // down if we are in a state where that is allowed, *and* the total number of processes
17990        // has gone down since last time.
17991        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17992                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17993                + " last=" + mLastNumProcesses);
17994        if (memFactor > mLastMemoryLevel) {
17995            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17996                memFactor = mLastMemoryLevel;
17997                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17998            }
17999        }
18000        mLastMemoryLevel = memFactor;
18001        mLastNumProcesses = mLruProcesses.size();
18002        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18003        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18004        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18005            if (mLowRamStartTime == 0) {
18006                mLowRamStartTime = now;
18007            }
18008            int step = 0;
18009            int fgTrimLevel;
18010            switch (memFactor) {
18011                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18012                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18013                    break;
18014                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18015                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18016                    break;
18017                default:
18018                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18019                    break;
18020            }
18021            int factor = numTrimming/3;
18022            int minFactor = 2;
18023            if (mHomeProcess != null) minFactor++;
18024            if (mPreviousProcess != null) minFactor++;
18025            if (factor < minFactor) factor = minFactor;
18026            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18027            for (int i=N-1; i>=0; i--) {
18028                ProcessRecord app = mLruProcesses.get(i);
18029                if (allChanged || app.procStateChanged) {
18030                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18031                    app.procStateChanged = false;
18032                }
18033                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18034                        && !app.killedByAm) {
18035                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18036                        try {
18037                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18038                                    "Trimming memory of " + app.processName
18039                                    + " to " + curLevel);
18040                            app.thread.scheduleTrimMemory(curLevel);
18041                        } catch (RemoteException e) {
18042                        }
18043                        if (false) {
18044                            // For now we won't do this; our memory trimming seems
18045                            // to be good enough at this point that destroying
18046                            // activities causes more harm than good.
18047                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18048                                    && app != mHomeProcess && app != mPreviousProcess) {
18049                                // Need to do this on its own message because the stack may not
18050                                // be in a consistent state at this point.
18051                                // For these apps we will also finish their activities
18052                                // to help them free memory.
18053                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18054                            }
18055                        }
18056                    }
18057                    app.trimMemoryLevel = curLevel;
18058                    step++;
18059                    if (step >= factor) {
18060                        step = 0;
18061                        switch (curLevel) {
18062                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18063                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18064                                break;
18065                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18066                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18067                                break;
18068                        }
18069                    }
18070                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18071                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18072                            && app.thread != null) {
18073                        try {
18074                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18075                                    "Trimming memory of heavy-weight " + app.processName
18076                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18077                            app.thread.scheduleTrimMemory(
18078                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18079                        } catch (RemoteException e) {
18080                        }
18081                    }
18082                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18083                } else {
18084                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18085                            || app.systemNoUi) && app.pendingUiClean) {
18086                        // If this application is now in the background and it
18087                        // had done UI, then give it the special trim level to
18088                        // have it free UI resources.
18089                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18090                        if (app.trimMemoryLevel < level && app.thread != null) {
18091                            try {
18092                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18093                                        "Trimming memory of bg-ui " + app.processName
18094                                        + " to " + level);
18095                                app.thread.scheduleTrimMemory(level);
18096                            } catch (RemoteException e) {
18097                            }
18098                        }
18099                        app.pendingUiClean = false;
18100                    }
18101                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18102                        try {
18103                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18104                                    "Trimming memory of fg " + app.processName
18105                                    + " to " + fgTrimLevel);
18106                            app.thread.scheduleTrimMemory(fgTrimLevel);
18107                        } catch (RemoteException e) {
18108                        }
18109                    }
18110                    app.trimMemoryLevel = fgTrimLevel;
18111                }
18112            }
18113        } else {
18114            if (mLowRamStartTime != 0) {
18115                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18116                mLowRamStartTime = 0;
18117            }
18118            for (int i=N-1; i>=0; i--) {
18119                ProcessRecord app = mLruProcesses.get(i);
18120                if (allChanged || app.procStateChanged) {
18121                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18122                    app.procStateChanged = false;
18123                }
18124                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18125                        || app.systemNoUi) && app.pendingUiClean) {
18126                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18127                            && app.thread != null) {
18128                        try {
18129                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18130                                    "Trimming memory of ui hidden " + app.processName
18131                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18132                            app.thread.scheduleTrimMemory(
18133                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18134                        } catch (RemoteException e) {
18135                        }
18136                    }
18137                    app.pendingUiClean = false;
18138                }
18139                app.trimMemoryLevel = 0;
18140            }
18141        }
18142
18143        if (mAlwaysFinishActivities) {
18144            // Need to do this on its own message because the stack may not
18145            // be in a consistent state at this point.
18146            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18147        }
18148
18149        if (allChanged) {
18150            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18151        }
18152
18153        if (mProcessStats.shouldWriteNowLocked(now)) {
18154            mHandler.post(new Runnable() {
18155                @Override public void run() {
18156                    synchronized (ActivityManagerService.this) {
18157                        mProcessStats.writeStateAsyncLocked();
18158                    }
18159                }
18160            });
18161        }
18162
18163        if (DEBUG_OOM_ADJ) {
18164            if (false) {
18165                RuntimeException here = new RuntimeException("here");
18166                here.fillInStackTrace();
18167                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18168            } else {
18169                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18170            }
18171        }
18172    }
18173
18174    final void trimApplications() {
18175        synchronized (this) {
18176            int i;
18177
18178            // First remove any unused application processes whose package
18179            // has been removed.
18180            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18181                final ProcessRecord app = mRemovedProcesses.get(i);
18182                if (app.activities.size() == 0
18183                        && app.curReceiver == null && app.services.size() == 0) {
18184                    Slog.i(
18185                        TAG, "Exiting empty application process "
18186                        + app.processName + " ("
18187                        + (app.thread != null ? app.thread.asBinder() : null)
18188                        + ")\n");
18189                    if (app.pid > 0 && app.pid != MY_PID) {
18190                        app.kill("empty", false);
18191                    } else {
18192                        try {
18193                            app.thread.scheduleExit();
18194                        } catch (Exception e) {
18195                            // Ignore exceptions.
18196                        }
18197                    }
18198                    cleanUpApplicationRecordLocked(app, false, true, -1);
18199                    mRemovedProcesses.remove(i);
18200
18201                    if (app.persistent) {
18202                        addAppLocked(app.info, false, null /* ABI override */);
18203                    }
18204                }
18205            }
18206
18207            // Now update the oom adj for all processes.
18208            updateOomAdjLocked();
18209        }
18210    }
18211
18212    /** This method sends the specified signal to each of the persistent apps */
18213    public void signalPersistentProcesses(int sig) throws RemoteException {
18214        if (sig != Process.SIGNAL_USR1) {
18215            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18216        }
18217
18218        synchronized (this) {
18219            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18220                    != PackageManager.PERMISSION_GRANTED) {
18221                throw new SecurityException("Requires permission "
18222                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18223            }
18224
18225            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18226                ProcessRecord r = mLruProcesses.get(i);
18227                if (r.thread != null && r.persistent) {
18228                    Process.sendSignal(r.pid, sig);
18229                }
18230            }
18231        }
18232    }
18233
18234    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18235        if (proc == null || proc == mProfileProc) {
18236            proc = mProfileProc;
18237            profileType = mProfileType;
18238            clearProfilerLocked();
18239        }
18240        if (proc == null) {
18241            return;
18242        }
18243        try {
18244            proc.thread.profilerControl(false, null, profileType);
18245        } catch (RemoteException e) {
18246            throw new IllegalStateException("Process disappeared");
18247        }
18248    }
18249
18250    private void clearProfilerLocked() {
18251        if (mProfileFd != null) {
18252            try {
18253                mProfileFd.close();
18254            } catch (IOException e) {
18255            }
18256        }
18257        mProfileApp = null;
18258        mProfileProc = null;
18259        mProfileFile = null;
18260        mProfileType = 0;
18261        mAutoStopProfiler = false;
18262        mSamplingInterval = 0;
18263    }
18264
18265    public boolean profileControl(String process, int userId, boolean start,
18266            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18267
18268        try {
18269            synchronized (this) {
18270                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18271                // its own permission.
18272                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18273                        != PackageManager.PERMISSION_GRANTED) {
18274                    throw new SecurityException("Requires permission "
18275                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18276                }
18277
18278                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18279                    throw new IllegalArgumentException("null profile info or fd");
18280                }
18281
18282                ProcessRecord proc = null;
18283                if (process != null) {
18284                    proc = findProcessLocked(process, userId, "profileControl");
18285                }
18286
18287                if (start && (proc == null || proc.thread == null)) {
18288                    throw new IllegalArgumentException("Unknown process: " + process);
18289                }
18290
18291                if (start) {
18292                    stopProfilerLocked(null, 0);
18293                    setProfileApp(proc.info, proc.processName, profilerInfo);
18294                    mProfileProc = proc;
18295                    mProfileType = profileType;
18296                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18297                    try {
18298                        fd = fd.dup();
18299                    } catch (IOException e) {
18300                        fd = null;
18301                    }
18302                    profilerInfo.profileFd = fd;
18303                    proc.thread.profilerControl(start, profilerInfo, profileType);
18304                    fd = null;
18305                    mProfileFd = null;
18306                } else {
18307                    stopProfilerLocked(proc, profileType);
18308                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18309                        try {
18310                            profilerInfo.profileFd.close();
18311                        } catch (IOException e) {
18312                        }
18313                    }
18314                }
18315
18316                return true;
18317            }
18318        } catch (RemoteException e) {
18319            throw new IllegalStateException("Process disappeared");
18320        } finally {
18321            if (profilerInfo != null && profilerInfo.profileFd != null) {
18322                try {
18323                    profilerInfo.profileFd.close();
18324                } catch (IOException e) {
18325                }
18326            }
18327        }
18328    }
18329
18330    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18331        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18332                userId, true, ALLOW_FULL_ONLY, callName, null);
18333        ProcessRecord proc = null;
18334        try {
18335            int pid = Integer.parseInt(process);
18336            synchronized (mPidsSelfLocked) {
18337                proc = mPidsSelfLocked.get(pid);
18338            }
18339        } catch (NumberFormatException e) {
18340        }
18341
18342        if (proc == null) {
18343            ArrayMap<String, SparseArray<ProcessRecord>> all
18344                    = mProcessNames.getMap();
18345            SparseArray<ProcessRecord> procs = all.get(process);
18346            if (procs != null && procs.size() > 0) {
18347                proc = procs.valueAt(0);
18348                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18349                    for (int i=1; i<procs.size(); i++) {
18350                        ProcessRecord thisProc = procs.valueAt(i);
18351                        if (thisProc.userId == userId) {
18352                            proc = thisProc;
18353                            break;
18354                        }
18355                    }
18356                }
18357            }
18358        }
18359
18360        return proc;
18361    }
18362
18363    public boolean dumpHeap(String process, int userId, boolean managed,
18364            String path, ParcelFileDescriptor fd) throws RemoteException {
18365
18366        try {
18367            synchronized (this) {
18368                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18369                // its own permission (same as profileControl).
18370                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18371                        != PackageManager.PERMISSION_GRANTED) {
18372                    throw new SecurityException("Requires permission "
18373                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18374                }
18375
18376                if (fd == null) {
18377                    throw new IllegalArgumentException("null fd");
18378                }
18379
18380                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18381                if (proc == null || proc.thread == null) {
18382                    throw new IllegalArgumentException("Unknown process: " + process);
18383                }
18384
18385                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18386                if (!isDebuggable) {
18387                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18388                        throw new SecurityException("Process not debuggable: " + proc);
18389                    }
18390                }
18391
18392                proc.thread.dumpHeap(managed, path, fd);
18393                fd = null;
18394                return true;
18395            }
18396        } catch (RemoteException e) {
18397            throw new IllegalStateException("Process disappeared");
18398        } finally {
18399            if (fd != null) {
18400                try {
18401                    fd.close();
18402                } catch (IOException e) {
18403                }
18404            }
18405        }
18406    }
18407
18408    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18409    public void monitor() {
18410        synchronized (this) { }
18411    }
18412
18413    void onCoreSettingsChange(Bundle settings) {
18414        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18415            ProcessRecord processRecord = mLruProcesses.get(i);
18416            try {
18417                if (processRecord.thread != null) {
18418                    processRecord.thread.setCoreSettings(settings);
18419                }
18420            } catch (RemoteException re) {
18421                /* ignore */
18422            }
18423        }
18424    }
18425
18426    // Multi-user methods
18427
18428    /**
18429     * Start user, if its not already running, but don't bring it to foreground.
18430     */
18431    @Override
18432    public boolean startUserInBackground(final int userId) {
18433        return startUser(userId, /* foreground */ false);
18434    }
18435
18436    /**
18437     * Start user, if its not already running, and bring it to foreground.
18438     */
18439    boolean startUserInForeground(final int userId, Dialog dlg) {
18440        boolean result = startUser(userId, /* foreground */ true);
18441        dlg.dismiss();
18442        return result;
18443    }
18444
18445    /**
18446     * Refreshes the list of users related to the current user when either a
18447     * user switch happens or when a new related user is started in the
18448     * background.
18449     */
18450    private void updateCurrentProfileIdsLocked() {
18451        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18452                mCurrentUserId, false /* enabledOnly */);
18453        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18454        for (int i = 0; i < currentProfileIds.length; i++) {
18455            currentProfileIds[i] = profiles.get(i).id;
18456        }
18457        mCurrentProfileIds = currentProfileIds;
18458
18459        synchronized (mUserProfileGroupIdsSelfLocked) {
18460            mUserProfileGroupIdsSelfLocked.clear();
18461            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18462            for (int i = 0; i < users.size(); i++) {
18463                UserInfo user = users.get(i);
18464                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18465                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18466                }
18467            }
18468        }
18469    }
18470
18471    private Set getProfileIdsLocked(int userId) {
18472        Set userIds = new HashSet<Integer>();
18473        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18474                userId, false /* enabledOnly */);
18475        for (UserInfo user : profiles) {
18476            userIds.add(Integer.valueOf(user.id));
18477        }
18478        return userIds;
18479    }
18480
18481    @Override
18482    public boolean switchUser(final int userId) {
18483        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18484        String userName;
18485        synchronized (this) {
18486            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18487            if (userInfo == null) {
18488                Slog.w(TAG, "No user info for user #" + userId);
18489                return false;
18490            }
18491            if (userInfo.isManagedProfile()) {
18492                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18493                return false;
18494            }
18495            userName = userInfo.name;
18496            mTargetUserId = userId;
18497        }
18498        mHandler.removeMessages(START_USER_SWITCH_MSG);
18499        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18500        return true;
18501    }
18502
18503    private void showUserSwitchDialog(int userId, String userName) {
18504        // The dialog will show and then initiate the user switch by calling startUserInForeground
18505        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18506                true /* above system */);
18507        d.show();
18508    }
18509
18510    private boolean startUser(final int userId, final boolean foreground) {
18511        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18512                != PackageManager.PERMISSION_GRANTED) {
18513            String msg = "Permission Denial: switchUser() from pid="
18514                    + Binder.getCallingPid()
18515                    + ", uid=" + Binder.getCallingUid()
18516                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18517            Slog.w(TAG, msg);
18518            throw new SecurityException(msg);
18519        }
18520
18521        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18522
18523        final long ident = Binder.clearCallingIdentity();
18524        try {
18525            synchronized (this) {
18526                final int oldUserId = mCurrentUserId;
18527                if (oldUserId == userId) {
18528                    return true;
18529                }
18530
18531                mStackSupervisor.setLockTaskModeLocked(null, false);
18532
18533                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18534                if (userInfo == null) {
18535                    Slog.w(TAG, "No user info for user #" + userId);
18536                    return false;
18537                }
18538                if (foreground && userInfo.isManagedProfile()) {
18539                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18540                    return false;
18541                }
18542
18543                if (foreground) {
18544                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18545                            R.anim.screen_user_enter);
18546                }
18547
18548                boolean needStart = false;
18549
18550                // If the user we are switching to is not currently started, then
18551                // we need to start it now.
18552                if (mStartedUsers.get(userId) == null) {
18553                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18554                    updateStartedUserArrayLocked();
18555                    needStart = true;
18556                }
18557
18558                final Integer userIdInt = Integer.valueOf(userId);
18559                mUserLru.remove(userIdInt);
18560                mUserLru.add(userIdInt);
18561
18562                if (foreground) {
18563                    mCurrentUserId = userId;
18564                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18565                    updateCurrentProfileIdsLocked();
18566                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18567                    // Once the internal notion of the active user has switched, we lock the device
18568                    // with the option to show the user switcher on the keyguard.
18569                    mWindowManager.lockNow(null);
18570                } else {
18571                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18572                    updateCurrentProfileIdsLocked();
18573                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18574                    mUserLru.remove(currentUserIdInt);
18575                    mUserLru.add(currentUserIdInt);
18576                }
18577
18578                final UserStartedState uss = mStartedUsers.get(userId);
18579
18580                // Make sure user is in the started state.  If it is currently
18581                // stopping, we need to knock that off.
18582                if (uss.mState == UserStartedState.STATE_STOPPING) {
18583                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18584                    // so we can just fairly silently bring the user back from
18585                    // the almost-dead.
18586                    uss.mState = UserStartedState.STATE_RUNNING;
18587                    updateStartedUserArrayLocked();
18588                    needStart = true;
18589                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18590                    // This means ACTION_SHUTDOWN has been sent, so we will
18591                    // need to treat this as a new boot of the user.
18592                    uss.mState = UserStartedState.STATE_BOOTING;
18593                    updateStartedUserArrayLocked();
18594                    needStart = true;
18595                }
18596
18597                if (uss.mState == UserStartedState.STATE_BOOTING) {
18598                    // Booting up a new user, need to tell system services about it.
18599                    // Note that this is on the same handler as scheduling of broadcasts,
18600                    // which is important because it needs to go first.
18601                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18602                }
18603
18604                if (foreground) {
18605                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18606                            oldUserId));
18607                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18608                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18609                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18610                            oldUserId, userId, uss));
18611                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18612                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18613                }
18614
18615                if (needStart) {
18616                    // Send USER_STARTED broadcast
18617                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18618                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18619                            | Intent.FLAG_RECEIVER_FOREGROUND);
18620                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18621                    broadcastIntentLocked(null, null, intent,
18622                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18623                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18624                }
18625
18626                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18627                    if (userId != UserHandle.USER_OWNER) {
18628                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18629                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18630                        broadcastIntentLocked(null, null, intent, null,
18631                                new IIntentReceiver.Stub() {
18632                                    public void performReceive(Intent intent, int resultCode,
18633                                            String data, Bundle extras, boolean ordered,
18634                                            boolean sticky, int sendingUser) {
18635                                        onUserInitialized(uss, foreground, oldUserId, userId);
18636                                    }
18637                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18638                                true, false, MY_PID, Process.SYSTEM_UID,
18639                                userId);
18640                        uss.initializing = true;
18641                    } else {
18642                        getUserManagerLocked().makeInitialized(userInfo.id);
18643                    }
18644                }
18645
18646                if (foreground) {
18647                    if (!uss.initializing) {
18648                        moveUserToForeground(uss, oldUserId, userId);
18649                    }
18650                } else {
18651                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18652                }
18653
18654                if (needStart) {
18655                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18656                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18657                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18658                    broadcastIntentLocked(null, null, intent,
18659                            null, new IIntentReceiver.Stub() {
18660                                @Override
18661                                public void performReceive(Intent intent, int resultCode, String data,
18662                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18663                                        throws RemoteException {
18664                                }
18665                            }, 0, null, null,
18666                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18667                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18668                }
18669            }
18670        } finally {
18671            Binder.restoreCallingIdentity(ident);
18672        }
18673
18674        return true;
18675    }
18676
18677    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18678        long ident = Binder.clearCallingIdentity();
18679        try {
18680            Intent intent;
18681            if (oldUserId >= 0) {
18682                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18683                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18684                int count = profiles.size();
18685                for (int i = 0; i < count; i++) {
18686                    int profileUserId = profiles.get(i).id;
18687                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18688                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18689                            | Intent.FLAG_RECEIVER_FOREGROUND);
18690                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18691                    broadcastIntentLocked(null, null, intent,
18692                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18693                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18694                }
18695            }
18696            if (newUserId >= 0) {
18697                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18698                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18699                int count = profiles.size();
18700                for (int i = 0; i < count; i++) {
18701                    int profileUserId = profiles.get(i).id;
18702                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18703                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18704                            | Intent.FLAG_RECEIVER_FOREGROUND);
18705                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18706                    broadcastIntentLocked(null, null, intent,
18707                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18708                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18709                }
18710                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18711                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18712                        | Intent.FLAG_RECEIVER_FOREGROUND);
18713                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18714                broadcastIntentLocked(null, null, intent,
18715                        null, null, 0, null, null,
18716                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18717                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18718            }
18719        } finally {
18720            Binder.restoreCallingIdentity(ident);
18721        }
18722    }
18723
18724    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18725            final int newUserId) {
18726        final int N = mUserSwitchObservers.beginBroadcast();
18727        if (N > 0) {
18728            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18729                int mCount = 0;
18730                @Override
18731                public void sendResult(Bundle data) throws RemoteException {
18732                    synchronized (ActivityManagerService.this) {
18733                        if (mCurUserSwitchCallback == this) {
18734                            mCount++;
18735                            if (mCount == N) {
18736                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18737                            }
18738                        }
18739                    }
18740                }
18741            };
18742            synchronized (this) {
18743                uss.switching = true;
18744                mCurUserSwitchCallback = callback;
18745            }
18746            for (int i=0; i<N; i++) {
18747                try {
18748                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18749                            newUserId, callback);
18750                } catch (RemoteException e) {
18751                }
18752            }
18753        } else {
18754            synchronized (this) {
18755                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18756            }
18757        }
18758        mUserSwitchObservers.finishBroadcast();
18759    }
18760
18761    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18762        synchronized (this) {
18763            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18764            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18765        }
18766    }
18767
18768    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18769        mCurUserSwitchCallback = null;
18770        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18771        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18772                oldUserId, newUserId, uss));
18773    }
18774
18775    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18776        synchronized (this) {
18777            if (foreground) {
18778                moveUserToForeground(uss, oldUserId, newUserId);
18779            }
18780        }
18781
18782        completeSwitchAndInitalize(uss, newUserId, true, false);
18783    }
18784
18785    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18786        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18787        if (homeInFront) {
18788            startHomeActivityLocked(newUserId);
18789        } else {
18790            mStackSupervisor.resumeTopActivitiesLocked();
18791        }
18792        EventLogTags.writeAmSwitchUser(newUserId);
18793        getUserManagerLocked().userForeground(newUserId);
18794        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18795    }
18796
18797    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18798        completeSwitchAndInitalize(uss, newUserId, false, true);
18799    }
18800
18801    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18802            boolean clearInitializing, boolean clearSwitching) {
18803        boolean unfrozen = false;
18804        synchronized (this) {
18805            if (clearInitializing) {
18806                uss.initializing = false;
18807                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18808            }
18809            if (clearSwitching) {
18810                uss.switching = false;
18811            }
18812            if (!uss.switching && !uss.initializing) {
18813                mWindowManager.stopFreezingScreen();
18814                unfrozen = true;
18815            }
18816        }
18817        if (unfrozen) {
18818            final int N = mUserSwitchObservers.beginBroadcast();
18819            for (int i=0; i<N; i++) {
18820                try {
18821                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18822                } catch (RemoteException e) {
18823                }
18824            }
18825            mUserSwitchObservers.finishBroadcast();
18826        }
18827    }
18828
18829    void scheduleStartProfilesLocked() {
18830        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18831            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18832                    DateUtils.SECOND_IN_MILLIS);
18833        }
18834    }
18835
18836    void startProfilesLocked() {
18837        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18838        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18839                mCurrentUserId, false /* enabledOnly */);
18840        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18841        for (UserInfo user : profiles) {
18842            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18843                    && user.id != mCurrentUserId) {
18844                toStart.add(user);
18845            }
18846        }
18847        final int n = toStart.size();
18848        int i = 0;
18849        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18850            startUserInBackground(toStart.get(i).id);
18851        }
18852        if (i < n) {
18853            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18854        }
18855    }
18856
18857    void finishUserBoot(UserStartedState uss) {
18858        synchronized (this) {
18859            if (uss.mState == UserStartedState.STATE_BOOTING
18860                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18861                uss.mState = UserStartedState.STATE_RUNNING;
18862                final int userId = uss.mHandle.getIdentifier();
18863                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18864                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18865                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18866                broadcastIntentLocked(null, null, intent,
18867                        null, null, 0, null, null,
18868                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18869                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18870            }
18871        }
18872    }
18873
18874    void finishUserSwitch(UserStartedState uss) {
18875        synchronized (this) {
18876            finishUserBoot(uss);
18877
18878            startProfilesLocked();
18879
18880            int num = mUserLru.size();
18881            int i = 0;
18882            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18883                Integer oldUserId = mUserLru.get(i);
18884                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18885                if (oldUss == null) {
18886                    // Shouldn't happen, but be sane if it does.
18887                    mUserLru.remove(i);
18888                    num--;
18889                    continue;
18890                }
18891                if (oldUss.mState == UserStartedState.STATE_STOPPING
18892                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18893                    // This user is already stopping, doesn't count.
18894                    num--;
18895                    i++;
18896                    continue;
18897                }
18898                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18899                    // Owner and current can't be stopped, but count as running.
18900                    i++;
18901                    continue;
18902                }
18903                // This is a user to be stopped.
18904                stopUserLocked(oldUserId, null);
18905                num--;
18906                i++;
18907            }
18908        }
18909    }
18910
18911    @Override
18912    public int stopUser(final int userId, final IStopUserCallback callback) {
18913        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18914                != PackageManager.PERMISSION_GRANTED) {
18915            String msg = "Permission Denial: switchUser() from pid="
18916                    + Binder.getCallingPid()
18917                    + ", uid=" + Binder.getCallingUid()
18918                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18919            Slog.w(TAG, msg);
18920            throw new SecurityException(msg);
18921        }
18922        if (userId <= 0) {
18923            throw new IllegalArgumentException("Can't stop primary user " + userId);
18924        }
18925        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18926        synchronized (this) {
18927            return stopUserLocked(userId, callback);
18928        }
18929    }
18930
18931    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18932        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18933        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18934            return ActivityManager.USER_OP_IS_CURRENT;
18935        }
18936
18937        final UserStartedState uss = mStartedUsers.get(userId);
18938        if (uss == null) {
18939            // User is not started, nothing to do...  but we do need to
18940            // callback if requested.
18941            if (callback != null) {
18942                mHandler.post(new Runnable() {
18943                    @Override
18944                    public void run() {
18945                        try {
18946                            callback.userStopped(userId);
18947                        } catch (RemoteException e) {
18948                        }
18949                    }
18950                });
18951            }
18952            return ActivityManager.USER_OP_SUCCESS;
18953        }
18954
18955        if (callback != null) {
18956            uss.mStopCallbacks.add(callback);
18957        }
18958
18959        if (uss.mState != UserStartedState.STATE_STOPPING
18960                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18961            uss.mState = UserStartedState.STATE_STOPPING;
18962            updateStartedUserArrayLocked();
18963
18964            long ident = Binder.clearCallingIdentity();
18965            try {
18966                // We are going to broadcast ACTION_USER_STOPPING and then
18967                // once that is done send a final ACTION_SHUTDOWN and then
18968                // stop the user.
18969                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18970                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18971                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18972                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18973                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18974                // This is the result receiver for the final shutdown broadcast.
18975                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18976                    @Override
18977                    public void performReceive(Intent intent, int resultCode, String data,
18978                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18979                        finishUserStop(uss);
18980                    }
18981                };
18982                // This is the result receiver for the initial stopping broadcast.
18983                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18984                    @Override
18985                    public void performReceive(Intent intent, int resultCode, String data,
18986                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18987                        // On to the next.
18988                        synchronized (ActivityManagerService.this) {
18989                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18990                                // Whoops, we are being started back up.  Abort, abort!
18991                                return;
18992                            }
18993                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18994                        }
18995                        mBatteryStatsService.noteEvent(
18996                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18997                                Integer.toString(userId), userId);
18998                        mSystemServiceManager.stopUser(userId);
18999                        broadcastIntentLocked(null, null, shutdownIntent,
19000                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19001                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19002                    }
19003                };
19004                // Kick things off.
19005                broadcastIntentLocked(null, null, stoppingIntent,
19006                        null, stoppingReceiver, 0, null, null,
19007                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19008                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19009            } finally {
19010                Binder.restoreCallingIdentity(ident);
19011            }
19012        }
19013
19014        return ActivityManager.USER_OP_SUCCESS;
19015    }
19016
19017    void finishUserStop(UserStartedState uss) {
19018        final int userId = uss.mHandle.getIdentifier();
19019        boolean stopped;
19020        ArrayList<IStopUserCallback> callbacks;
19021        synchronized (this) {
19022            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19023            if (mStartedUsers.get(userId) != uss) {
19024                stopped = false;
19025            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19026                stopped = false;
19027            } else {
19028                stopped = true;
19029                // User can no longer run.
19030                mStartedUsers.remove(userId);
19031                mUserLru.remove(Integer.valueOf(userId));
19032                updateStartedUserArrayLocked();
19033
19034                // Clean up all state and processes associated with the user.
19035                // Kill all the processes for the user.
19036                forceStopUserLocked(userId, "finish user");
19037            }
19038
19039            // Explicitly remove the old information in mRecentTasks.
19040            removeRecentTasksForUserLocked(userId);
19041        }
19042
19043        for (int i=0; i<callbacks.size(); i++) {
19044            try {
19045                if (stopped) callbacks.get(i).userStopped(userId);
19046                else callbacks.get(i).userStopAborted(userId);
19047            } catch (RemoteException e) {
19048            }
19049        }
19050
19051        if (stopped) {
19052            mSystemServiceManager.cleanupUser(userId);
19053            synchronized (this) {
19054                mStackSupervisor.removeUserLocked(userId);
19055            }
19056        }
19057    }
19058
19059    @Override
19060    public UserInfo getCurrentUser() {
19061        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19062                != PackageManager.PERMISSION_GRANTED) && (
19063                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19064                != PackageManager.PERMISSION_GRANTED)) {
19065            String msg = "Permission Denial: getCurrentUser() from pid="
19066                    + Binder.getCallingPid()
19067                    + ", uid=" + Binder.getCallingUid()
19068                    + " requires " + INTERACT_ACROSS_USERS;
19069            Slog.w(TAG, msg);
19070            throw new SecurityException(msg);
19071        }
19072        synchronized (this) {
19073            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19074            return getUserManagerLocked().getUserInfo(userId);
19075        }
19076    }
19077
19078    int getCurrentUserIdLocked() {
19079        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19080    }
19081
19082    @Override
19083    public boolean isUserRunning(int userId, boolean orStopped) {
19084        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19085                != PackageManager.PERMISSION_GRANTED) {
19086            String msg = "Permission Denial: isUserRunning() from pid="
19087                    + Binder.getCallingPid()
19088                    + ", uid=" + Binder.getCallingUid()
19089                    + " requires " + INTERACT_ACROSS_USERS;
19090            Slog.w(TAG, msg);
19091            throw new SecurityException(msg);
19092        }
19093        synchronized (this) {
19094            return isUserRunningLocked(userId, orStopped);
19095        }
19096    }
19097
19098    boolean isUserRunningLocked(int userId, boolean orStopped) {
19099        UserStartedState state = mStartedUsers.get(userId);
19100        if (state == null) {
19101            return false;
19102        }
19103        if (orStopped) {
19104            return true;
19105        }
19106        return state.mState != UserStartedState.STATE_STOPPING
19107                && state.mState != UserStartedState.STATE_SHUTDOWN;
19108    }
19109
19110    @Override
19111    public int[] getRunningUserIds() {
19112        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19113                != PackageManager.PERMISSION_GRANTED) {
19114            String msg = "Permission Denial: isUserRunning() from pid="
19115                    + Binder.getCallingPid()
19116                    + ", uid=" + Binder.getCallingUid()
19117                    + " requires " + INTERACT_ACROSS_USERS;
19118            Slog.w(TAG, msg);
19119            throw new SecurityException(msg);
19120        }
19121        synchronized (this) {
19122            return mStartedUserArray;
19123        }
19124    }
19125
19126    private void updateStartedUserArrayLocked() {
19127        int num = 0;
19128        for (int i=0; i<mStartedUsers.size();  i++) {
19129            UserStartedState uss = mStartedUsers.valueAt(i);
19130            // This list does not include stopping users.
19131            if (uss.mState != UserStartedState.STATE_STOPPING
19132                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19133                num++;
19134            }
19135        }
19136        mStartedUserArray = new int[num];
19137        num = 0;
19138        for (int i=0; i<mStartedUsers.size();  i++) {
19139            UserStartedState uss = mStartedUsers.valueAt(i);
19140            if (uss.mState != UserStartedState.STATE_STOPPING
19141                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19142                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19143                num++;
19144            }
19145        }
19146    }
19147
19148    @Override
19149    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19150        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19151                != PackageManager.PERMISSION_GRANTED) {
19152            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19153                    + Binder.getCallingPid()
19154                    + ", uid=" + Binder.getCallingUid()
19155                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19156            Slog.w(TAG, msg);
19157            throw new SecurityException(msg);
19158        }
19159
19160        mUserSwitchObservers.register(observer);
19161    }
19162
19163    @Override
19164    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19165        mUserSwitchObservers.unregister(observer);
19166    }
19167
19168    private boolean userExists(int userId) {
19169        if (userId == 0) {
19170            return true;
19171        }
19172        UserManagerService ums = getUserManagerLocked();
19173        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19174    }
19175
19176    int[] getUsersLocked() {
19177        UserManagerService ums = getUserManagerLocked();
19178        return ums != null ? ums.getUserIds() : new int[] { 0 };
19179    }
19180
19181    UserManagerService getUserManagerLocked() {
19182        if (mUserManager == null) {
19183            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19184            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19185        }
19186        return mUserManager;
19187    }
19188
19189    private int applyUserId(int uid, int userId) {
19190        return UserHandle.getUid(userId, uid);
19191    }
19192
19193    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19194        if (info == null) return null;
19195        ApplicationInfo newInfo = new ApplicationInfo(info);
19196        newInfo.uid = applyUserId(info.uid, userId);
19197        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19198                + info.packageName;
19199        return newInfo;
19200    }
19201
19202    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19203        if (aInfo == null
19204                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19205            return aInfo;
19206        }
19207
19208        ActivityInfo info = new ActivityInfo(aInfo);
19209        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19210        return info;
19211    }
19212
19213    private final class LocalService extends ActivityManagerInternal {
19214        @Override
19215        public void goingToSleep() {
19216            ActivityManagerService.this.goingToSleep();
19217        }
19218
19219        @Override
19220        public void wakingUp() {
19221            ActivityManagerService.this.wakingUp();
19222        }
19223
19224        @Override
19225        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19226                String processName, String abiOverride, int uid, Runnable crashHandler) {
19227            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19228                    processName, abiOverride, uid, crashHandler);
19229        }
19230    }
19231
19232    /**
19233     * An implementation of IAppTask, that allows an app to manage its own tasks via
19234     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19235     * only the process that calls getAppTasks() can call the AppTask methods.
19236     */
19237    class AppTaskImpl extends IAppTask.Stub {
19238        private int mTaskId;
19239        private int mCallingUid;
19240
19241        public AppTaskImpl(int taskId, int callingUid) {
19242            mTaskId = taskId;
19243            mCallingUid = callingUid;
19244        }
19245
19246        private void checkCaller() {
19247            if (mCallingUid != Binder.getCallingUid()) {
19248                throw new SecurityException("Caller " + mCallingUid
19249                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19250            }
19251        }
19252
19253        @Override
19254        public void finishAndRemoveTask() {
19255            checkCaller();
19256
19257            synchronized (ActivityManagerService.this) {
19258                long origId = Binder.clearCallingIdentity();
19259                try {
19260                    if (!removeTaskByIdLocked(mTaskId, false)) {
19261                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19262                    }
19263                } finally {
19264                    Binder.restoreCallingIdentity(origId);
19265                }
19266            }
19267        }
19268
19269        @Override
19270        public ActivityManager.RecentTaskInfo getTaskInfo() {
19271            checkCaller();
19272
19273            synchronized (ActivityManagerService.this) {
19274                long origId = Binder.clearCallingIdentity();
19275                try {
19276                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19277                    if (tr == null) {
19278                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19279                    }
19280                    return createRecentTaskInfoFromTaskRecord(tr);
19281                } finally {
19282                    Binder.restoreCallingIdentity(origId);
19283                }
19284            }
19285        }
19286
19287        @Override
19288        public void moveToFront() {
19289            checkCaller();
19290
19291            final TaskRecord tr;
19292            synchronized (ActivityManagerService.this) {
19293                tr = recentTaskForIdLocked(mTaskId);
19294                if (tr == null) {
19295                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19296                }
19297                if (tr.getRootActivity() != null) {
19298                    moveTaskToFrontLocked(tr.taskId, 0, null);
19299                    return;
19300                }
19301            }
19302
19303            startActivityFromRecentsInner(tr.taskId, null);
19304        }
19305
19306        @Override
19307        public int startActivity(IBinder whoThread, String callingPackage,
19308                Intent intent, String resolvedType, Bundle options) {
19309            checkCaller();
19310
19311            int callingUser = UserHandle.getCallingUserId();
19312            TaskRecord tr;
19313            IApplicationThread appThread;
19314            synchronized (ActivityManagerService.this) {
19315                tr = recentTaskForIdLocked(mTaskId);
19316                if (tr == null) {
19317                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19318                }
19319                appThread = ApplicationThreadNative.asInterface(whoThread);
19320                if (appThread == null) {
19321                    throw new IllegalArgumentException("Bad app thread " + appThread);
19322                }
19323            }
19324            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19325                    resolvedType, null, null, null, null, 0, 0, null, null,
19326                    null, options, callingUser, null, tr);
19327        }
19328
19329        @Override
19330        public void setExcludeFromRecents(boolean exclude) {
19331            checkCaller();
19332
19333            synchronized (ActivityManagerService.this) {
19334                long origId = Binder.clearCallingIdentity();
19335                try {
19336                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19337                    if (tr == null) {
19338                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19339                    }
19340                    Intent intent = tr.getBaseIntent();
19341                    if (exclude) {
19342                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19343                    } else {
19344                        intent.setFlags(intent.getFlags()
19345                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19346                    }
19347                } finally {
19348                    Binder.restoreCallingIdentity(origId);
19349                }
19350            }
19351        }
19352    }
19353}
19354