ActivityManagerService.java revision 3597b55d12f77d2fb3019b2bbc3496673c78be7d
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            int hashCode = 1;
800            hashCode = 31 * hashCode + sourceUserId;
801            hashCode = 31 * hashCode + uri.hashCode();
802            hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
803            return hashCode;
804        }
805
806        @Override
807        public boolean equals(Object o) {
808            if (o instanceof GrantUri) {
809                GrantUri other = (GrantUri) o;
810                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
811                        && prefix == other.prefix;
812            }
813            return false;
814        }
815
816        @Override
817        public String toString() {
818            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
819            if (prefix) result += " [prefix]";
820            return result;
821        }
822
823        public String toSafeString() {
824            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
825            if (prefix) result += " [prefix]";
826            return result;
827        }
828
829        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
830            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
831                    ContentProvider.getUriWithoutUserId(uri), false);
832        }
833    }
834
835    CoreSettingsObserver mCoreSettingsObserver;
836
837    /**
838     * Thread-local storage used to carry caller permissions over through
839     * indirect content-provider access.
840     */
841    private class Identity {
842        public int pid;
843        public int uid;
844
845        Identity(int _pid, int _uid) {
846            pid = _pid;
847            uid = _uid;
848        }
849    }
850
851    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
852
853    /**
854     * All information we have collected about the runtime performance of
855     * any user id that can impact battery performance.
856     */
857    final BatteryStatsService mBatteryStatsService;
858
859    /**
860     * Information about component usage
861     */
862    UsageStatsManagerInternal mUsageStatsService;
863
864    /**
865     * Information about and control over application operations
866     */
867    final AppOpsService mAppOpsService;
868
869    /**
870     * Save recent tasks information across reboots.
871     */
872    final TaskPersister mTaskPersister;
873
874    /**
875     * Current configuration information.  HistoryRecord objects are given
876     * a reference to this object to indicate which configuration they are
877     * currently running in, so this object must be kept immutable.
878     */
879    Configuration mConfiguration = new Configuration();
880
881    /**
882     * Current sequencing integer of the configuration, for skipping old
883     * configurations.
884     */
885    int mConfigurationSeq = 0;
886
887    /**
888     * Hardware-reported OpenGLES version.
889     */
890    final int GL_ES_VERSION;
891
892    /**
893     * List of initialization arguments to pass to all processes when binding applications to them.
894     * For example, references to the commonly used services.
895     */
896    HashMap<String, IBinder> mAppBindArgs;
897
898    /**
899     * Temporary to avoid allocations.  Protected by main lock.
900     */
901    final StringBuilder mStringBuilder = new StringBuilder(256);
902
903    /**
904     * Used to control how we initialize the service.
905     */
906    ComponentName mTopComponent;
907    String mTopAction = Intent.ACTION_MAIN;
908    String mTopData;
909    boolean mProcessesReady = false;
910    boolean mSystemReady = false;
911    boolean mBooting = false;
912    boolean mCallFinishBooting = false;
913    boolean mBootAnimationComplete = false;
914    boolean mWaitingUpdate = false;
915    boolean mDidUpdate = false;
916    boolean mOnBattery = false;
917    boolean mLaunchWarningShown = false;
918
919    Context mContext;
920
921    int mFactoryTest;
922
923    boolean mCheckedForSetup;
924
925    /**
926     * The time at which we will allow normal application switches again,
927     * after a call to {@link #stopAppSwitches()}.
928     */
929    long mAppSwitchesAllowedTime;
930
931    /**
932     * This is set to true after the first switch after mAppSwitchesAllowedTime
933     * is set; any switches after that will clear the time.
934     */
935    boolean mDidAppSwitch;
936
937    /**
938     * Last time (in realtime) at which we checked for power usage.
939     */
940    long mLastPowerCheckRealtime;
941
942    /**
943     * Last time (in uptime) at which we checked for power usage.
944     */
945    long mLastPowerCheckUptime;
946
947    /**
948     * Set while we are wanting to sleep, to prevent any
949     * activities from being started/resumed.
950     */
951    private boolean mSleeping = false;
952
953    /**
954     * Set while we are running a voice interaction.  This overrides
955     * sleeping while it is active.
956     */
957    private boolean mRunningVoice = false;
958
959    /**
960     * State of external calls telling us if the device is asleep.
961     */
962    private boolean mWentToSleep = false;
963
964    static final int LOCK_SCREEN_HIDDEN = 0;
965    static final int LOCK_SCREEN_LEAVING = 1;
966    static final int LOCK_SCREEN_SHOWN = 2;
967    /**
968     * State of external call telling us if the lock screen is shown.
969     */
970    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
971
972    /**
973     * Set if we are shutting down the system, similar to sleeping.
974     */
975    boolean mShuttingDown = false;
976
977    /**
978     * Current sequence id for oom_adj computation traversal.
979     */
980    int mAdjSeq = 0;
981
982    /**
983     * Current sequence id for process LRU updating.
984     */
985    int mLruSeq = 0;
986
987    /**
988     * Keep track of the non-cached/empty process we last found, to help
989     * determine how to distribute cached/empty processes next time.
990     */
991    int mNumNonCachedProcs = 0;
992
993    /**
994     * Keep track of the number of cached hidden procs, to balance oom adj
995     * distribution between those and empty procs.
996     */
997    int mNumCachedHiddenProcs = 0;
998
999    /**
1000     * Keep track of the number of service processes we last found, to
1001     * determine on the next iteration which should be B services.
1002     */
1003    int mNumServiceProcs = 0;
1004    int mNewNumAServiceProcs = 0;
1005    int mNewNumServiceProcs = 0;
1006
1007    /**
1008     * Allow the current computed overall memory level of the system to go down?
1009     * This is set to false when we are killing processes for reasons other than
1010     * memory management, so that the now smaller process list will not be taken as
1011     * an indication that memory is tighter.
1012     */
1013    boolean mAllowLowerMemLevel = false;
1014
1015    /**
1016     * The last computed memory level, for holding when we are in a state that
1017     * processes are going away for other reasons.
1018     */
1019    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1020
1021    /**
1022     * The last total number of process we have, to determine if changes actually look
1023     * like a shrinking number of process due to lower RAM.
1024     */
1025    int mLastNumProcesses;
1026
1027    /**
1028     * The uptime of the last time we performed idle maintenance.
1029     */
1030    long mLastIdleTime = SystemClock.uptimeMillis();
1031
1032    /**
1033     * Total time spent with RAM that has been added in the past since the last idle time.
1034     */
1035    long mLowRamTimeSinceLastIdle = 0;
1036
1037    /**
1038     * If RAM is currently low, when that horrible situation started.
1039     */
1040    long mLowRamStartTime = 0;
1041
1042    /**
1043     * For reporting to battery stats the current top application.
1044     */
1045    private String mCurResumedPackage = null;
1046    private int mCurResumedUid = -1;
1047
1048    /**
1049     * For reporting to battery stats the apps currently running foreground
1050     * service.  The ProcessMap is package/uid tuples; each of these contain
1051     * an array of the currently foreground processes.
1052     */
1053    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1054            = new ProcessMap<ArrayList<ProcessRecord>>();
1055
1056    /**
1057     * This is set if we had to do a delayed dexopt of an app before launching
1058     * it, to increase the ANR timeouts in that case.
1059     */
1060    boolean mDidDexOpt;
1061
1062    /**
1063     * Set if the systemServer made a call to enterSafeMode.
1064     */
1065    boolean mSafeMode;
1066
1067    String mDebugApp = null;
1068    boolean mWaitForDebugger = false;
1069    boolean mDebugTransient = false;
1070    String mOrigDebugApp = null;
1071    boolean mOrigWaitForDebugger = false;
1072    boolean mAlwaysFinishActivities = false;
1073    IActivityController mController = null;
1074    String mProfileApp = null;
1075    ProcessRecord mProfileProc = null;
1076    String mProfileFile;
1077    ParcelFileDescriptor mProfileFd;
1078    int mSamplingInterval = 0;
1079    boolean mAutoStopProfiler = false;
1080    int mProfileType = 0;
1081    String mOpenGlTraceApp = null;
1082
1083    static class ProcessChangeItem {
1084        static final int CHANGE_ACTIVITIES = 1<<0;
1085        static final int CHANGE_PROCESS_STATE = 1<<1;
1086        int changes;
1087        int uid;
1088        int pid;
1089        int processState;
1090        boolean foregroundActivities;
1091    }
1092
1093    final RemoteCallbackList<IProcessObserver> mProcessObservers
1094            = new RemoteCallbackList<IProcessObserver>();
1095    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1096
1097    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1098            = new ArrayList<ProcessChangeItem>();
1099    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1100            = new ArrayList<ProcessChangeItem>();
1101
1102    /**
1103     * Runtime CPU use collection thread.  This object's lock is used to
1104     * perform synchronization with the thread (notifying it to run).
1105     */
1106    final Thread mProcessCpuThread;
1107
1108    /**
1109     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1110     * Must acquire this object's lock when accessing it.
1111     * NOTE: this lock will be held while doing long operations (trawling
1112     * through all processes in /proc), so it should never be acquired by
1113     * any critical paths such as when holding the main activity manager lock.
1114     */
1115    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1116            MONITOR_THREAD_CPU_USAGE);
1117    final AtomicLong mLastCpuTime = new AtomicLong(0);
1118    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1119
1120    long mLastWriteTime = 0;
1121
1122    /**
1123     * Used to retain an update lock when the foreground activity is in
1124     * immersive mode.
1125     */
1126    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1127
1128    /**
1129     * Set to true after the system has finished booting.
1130     */
1131    boolean mBooted = false;
1132
1133    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1134    int mProcessLimitOverride = -1;
1135
1136    WindowManagerService mWindowManager;
1137
1138    final ActivityThread mSystemThread;
1139
1140    // Holds the current foreground user's id
1141    int mCurrentUserId = 0;
1142    // Holds the target user's id during a user switch
1143    int mTargetUserId = UserHandle.USER_NULL;
1144    // If there are multiple profiles for the current user, their ids are here
1145    // Currently only the primary user can have managed profiles
1146    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1147
1148    /**
1149     * Mapping from each known user ID to the profile group ID it is associated with.
1150     */
1151    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1152
1153    private UserManagerService mUserManager;
1154
1155    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1156        final ProcessRecord mApp;
1157        final int mPid;
1158        final IApplicationThread mAppThread;
1159
1160        AppDeathRecipient(ProcessRecord app, int pid,
1161                IApplicationThread thread) {
1162            if (localLOGV) Slog.v(
1163                TAG, "New death recipient " + this
1164                + " for thread " + thread.asBinder());
1165            mApp = app;
1166            mPid = pid;
1167            mAppThread = thread;
1168        }
1169
1170        @Override
1171        public void binderDied() {
1172            if (localLOGV) Slog.v(
1173                TAG, "Death received in " + this
1174                + " for thread " + mAppThread.asBinder());
1175            synchronized(ActivityManagerService.this) {
1176                appDiedLocked(mApp, mPid, mAppThread);
1177            }
1178        }
1179    }
1180
1181    static final int SHOW_ERROR_MSG = 1;
1182    static final int SHOW_NOT_RESPONDING_MSG = 2;
1183    static final int SHOW_FACTORY_ERROR_MSG = 3;
1184    static final int UPDATE_CONFIGURATION_MSG = 4;
1185    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1186    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1187    static final int SERVICE_TIMEOUT_MSG = 12;
1188    static final int UPDATE_TIME_ZONE = 13;
1189    static final int SHOW_UID_ERROR_MSG = 14;
1190    static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1191    static final int PROC_START_TIMEOUT_MSG = 20;
1192    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1193    static final int KILL_APPLICATION_MSG = 22;
1194    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1195    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1196    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1197    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1198    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1199    static final int CLEAR_DNS_CACHE_MSG = 28;
1200    static final int UPDATE_HTTP_PROXY_MSG = 29;
1201    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1202    static final int DISPATCH_PROCESSES_CHANGED = 31;
1203    static final int DISPATCH_PROCESS_DIED = 32;
1204    static final int REPORT_MEM_USAGE_MSG = 33;
1205    static final int REPORT_USER_SWITCH_MSG = 34;
1206    static final int CONTINUE_USER_SWITCH_MSG = 35;
1207    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1208    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1209    static final int PERSIST_URI_GRANTS_MSG = 38;
1210    static final int REQUEST_ALL_PSS_MSG = 39;
1211    static final int START_PROFILES_MSG = 40;
1212    static final int UPDATE_TIME = 41;
1213    static final int SYSTEM_USER_START_MSG = 42;
1214    static final int SYSTEM_USER_CURRENT_MSG = 43;
1215    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1216    static final int FINISH_BOOTING_MSG = 45;
1217    static final int START_USER_SWITCH_MSG = 46;
1218    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1219    static final int DISMISS_DIALOG_MSG = 48;
1220
1221    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1222    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1223    static final int FIRST_COMPAT_MODE_MSG = 300;
1224    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1225
1226    CompatModeDialog mCompatModeDialog;
1227    long mLastMemUsageReportTime = 0;
1228
1229    /**
1230     * Flag whether the current user is a "monkey", i.e. whether
1231     * the UI is driven by a UI automation tool.
1232     */
1233    private boolean mUserIsMonkey;
1234
1235    /** Flag whether the device has a Recents UI */
1236    boolean mHasRecents;
1237
1238    /** The dimensions of the thumbnails in the Recents UI. */
1239    int mThumbnailWidth;
1240    int mThumbnailHeight;
1241
1242    final ServiceThread mHandlerThread;
1243    final MainHandler mHandler;
1244
1245    final class MainHandler extends Handler {
1246        public MainHandler(Looper looper) {
1247            super(looper, null, true);
1248        }
1249
1250        @Override
1251        public void handleMessage(Message msg) {
1252            switch (msg.what) {
1253            case SHOW_ERROR_MSG: {
1254                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1255                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1256                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1257                synchronized (ActivityManagerService.this) {
1258                    ProcessRecord proc = (ProcessRecord)data.get("app");
1259                    AppErrorResult res = (AppErrorResult) data.get("result");
1260                    if (proc != null && proc.crashDialog != null) {
1261                        Slog.e(TAG, "App already has crash dialog: " + proc);
1262                        if (res != null) {
1263                            res.set(0);
1264                        }
1265                        return;
1266                    }
1267                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1268                            >= Process.FIRST_APPLICATION_UID
1269                            && proc.pid != MY_PID);
1270                    for (int userId : mCurrentProfileIds) {
1271                        isBackground &= (proc.userId != userId);
1272                    }
1273                    if (isBackground && !showBackground) {
1274                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1275                        if (res != null) {
1276                            res.set(0);
1277                        }
1278                        return;
1279                    }
1280                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1281                        Dialog d = new AppErrorDialog(mContext,
1282                                ActivityManagerService.this, res, proc);
1283                        d.show();
1284                        proc.crashDialog = d;
1285                    } else {
1286                        // The device is asleep, so just pretend that the user
1287                        // saw a crash dialog and hit "force quit".
1288                        if (res != null) {
1289                            res.set(0);
1290                        }
1291                    }
1292                }
1293
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_NOT_RESPONDING_MSG: {
1297                synchronized (ActivityManagerService.this) {
1298                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1299                    ProcessRecord proc = (ProcessRecord)data.get("app");
1300                    if (proc != null && proc.anrDialog != null) {
1301                        Slog.e(TAG, "App already has anr dialog: " + proc);
1302                        return;
1303                    }
1304
1305                    Intent intent = new Intent("android.intent.action.ANR");
1306                    if (!mProcessesReady) {
1307                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1308                                | Intent.FLAG_RECEIVER_FOREGROUND);
1309                    }
1310                    broadcastIntentLocked(null, null, intent,
1311                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1312                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1313
1314                    if (mShowDialogs) {
1315                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1316                                mContext, proc, (ActivityRecord)data.get("activity"),
1317                                msg.arg1 != 0);
1318                        d.show();
1319                        proc.anrDialog = d;
1320                    } else {
1321                        // Just kill the app if there is no dialog to be shown.
1322                        killAppAtUsersRequest(proc, null);
1323                    }
1324                }
1325
1326                ensureBootCompleted();
1327            } break;
1328            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1329                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1330                synchronized (ActivityManagerService.this) {
1331                    ProcessRecord proc = (ProcessRecord) data.get("app");
1332                    if (proc == null) {
1333                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1334                        break;
1335                    }
1336                    if (proc.crashDialog != null) {
1337                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1338                        return;
1339                    }
1340                    AppErrorResult res = (AppErrorResult) data.get("result");
1341                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1342                        Dialog d = new StrictModeViolationDialog(mContext,
1343                                ActivityManagerService.this, res, proc);
1344                        d.show();
1345                        proc.crashDialog = d;
1346                    } else {
1347                        // The device is asleep, so just pretend that the user
1348                        // saw a crash dialog and hit "force quit".
1349                        res.set(0);
1350                    }
1351                }
1352                ensureBootCompleted();
1353            } break;
1354            case SHOW_FACTORY_ERROR_MSG: {
1355                Dialog d = new FactoryErrorDialog(
1356                    mContext, msg.getData().getCharSequence("msg"));
1357                d.show();
1358                ensureBootCompleted();
1359            } break;
1360            case UPDATE_CONFIGURATION_MSG: {
1361                final ContentResolver resolver = mContext.getContentResolver();
1362                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1363            } break;
1364            case GC_BACKGROUND_PROCESSES_MSG: {
1365                synchronized (ActivityManagerService.this) {
1366                    performAppGcsIfAppropriateLocked();
1367                }
1368            } break;
1369            case WAIT_FOR_DEBUGGER_MSG: {
1370                synchronized (ActivityManagerService.this) {
1371                    ProcessRecord app = (ProcessRecord)msg.obj;
1372                    if (msg.arg1 != 0) {
1373                        if (!app.waitedForDebugger) {
1374                            Dialog d = new AppWaitingForDebuggerDialog(
1375                                    ActivityManagerService.this,
1376                                    mContext, app);
1377                            app.waitDialog = d;
1378                            app.waitedForDebugger = true;
1379                            d.show();
1380                        }
1381                    } else {
1382                        if (app.waitDialog != null) {
1383                            app.waitDialog.dismiss();
1384                            app.waitDialog = null;
1385                        }
1386                    }
1387                }
1388            } break;
1389            case SERVICE_TIMEOUT_MSG: {
1390                if (mDidDexOpt) {
1391                    mDidDexOpt = false;
1392                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1393                    nmsg.obj = msg.obj;
1394                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1395                    return;
1396                }
1397                mServices.serviceTimeout((ProcessRecord)msg.obj);
1398            } break;
1399            case UPDATE_TIME_ZONE: {
1400                synchronized (ActivityManagerService.this) {
1401                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1402                        ProcessRecord r = mLruProcesses.get(i);
1403                        if (r.thread != null) {
1404                            try {
1405                                r.thread.updateTimeZone();
1406                            } catch (RemoteException ex) {
1407                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1408                            }
1409                        }
1410                    }
1411                }
1412            } break;
1413            case CLEAR_DNS_CACHE_MSG: {
1414                synchronized (ActivityManagerService.this) {
1415                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1416                        ProcessRecord r = mLruProcesses.get(i);
1417                        if (r.thread != null) {
1418                            try {
1419                                r.thread.clearDnsCache();
1420                            } catch (RemoteException ex) {
1421                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1422                            }
1423                        }
1424                    }
1425                }
1426            } break;
1427            case UPDATE_HTTP_PROXY_MSG: {
1428                ProxyInfo proxy = (ProxyInfo)msg.obj;
1429                String host = "";
1430                String port = "";
1431                String exclList = "";
1432                Uri pacFileUrl = Uri.EMPTY;
1433                if (proxy != null) {
1434                    host = proxy.getHost();
1435                    port = Integer.toString(proxy.getPort());
1436                    exclList = proxy.getExclusionListAsString();
1437                    pacFileUrl = proxy.getPacFileUrl();
1438                }
1439                synchronized (ActivityManagerService.this) {
1440                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1441                        ProcessRecord r = mLruProcesses.get(i);
1442                        if (r.thread != null) {
1443                            try {
1444                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1445                            } catch (RemoteException ex) {
1446                                Slog.w(TAG, "Failed to update http proxy for: " +
1447                                        r.info.processName);
1448                            }
1449                        }
1450                    }
1451                }
1452            } break;
1453            case SHOW_UID_ERROR_MSG: {
1454                if (mShowDialogs) {
1455                    AlertDialog d = new BaseErrorDialog(mContext);
1456                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1457                    d.setCancelable(false);
1458                    d.setTitle(mContext.getText(R.string.android_system_label));
1459                    d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1460                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1461                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1462                    d.show();
1463                }
1464            } break;
1465            case SHOW_FINGERPRINT_ERROR_MSG: {
1466                if (mShowDialogs) {
1467                    AlertDialog d = new BaseErrorDialog(mContext);
1468                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1469                    d.setCancelable(false);
1470                    d.setTitle(mContext.getText(R.string.android_system_label));
1471                    d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1472                    d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1473                            mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1474                    d.show();
1475                }
1476            } break;
1477            case PROC_START_TIMEOUT_MSG: {
1478                if (mDidDexOpt) {
1479                    mDidDexOpt = false;
1480                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1481                    nmsg.obj = msg.obj;
1482                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1483                    return;
1484                }
1485                ProcessRecord app = (ProcessRecord)msg.obj;
1486                synchronized (ActivityManagerService.this) {
1487                    processStartTimedOutLocked(app);
1488                }
1489            } break;
1490            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1491                synchronized (ActivityManagerService.this) {
1492                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1493                }
1494            } break;
1495            case KILL_APPLICATION_MSG: {
1496                synchronized (ActivityManagerService.this) {
1497                    int appid = msg.arg1;
1498                    boolean restart = (msg.arg2 == 1);
1499                    Bundle bundle = (Bundle)msg.obj;
1500                    String pkg = bundle.getString("pkg");
1501                    String reason = bundle.getString("reason");
1502                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1503                            false, UserHandle.USER_ALL, reason);
1504                }
1505            } break;
1506            case FINALIZE_PENDING_INTENT_MSG: {
1507                ((PendingIntentRecord)msg.obj).completeFinalize();
1508            } break;
1509            case POST_HEAVY_NOTIFICATION_MSG: {
1510                INotificationManager inm = NotificationManager.getService();
1511                if (inm == null) {
1512                    return;
1513                }
1514
1515                ActivityRecord root = (ActivityRecord)msg.obj;
1516                ProcessRecord process = root.app;
1517                if (process == null) {
1518                    return;
1519                }
1520
1521                try {
1522                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1523                    String text = mContext.getString(R.string.heavy_weight_notification,
1524                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1525                    Notification notification = new Notification();
1526                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1527                    notification.when = 0;
1528                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1529                    notification.tickerText = text;
1530                    notification.defaults = 0; // please be quiet
1531                    notification.sound = null;
1532                    notification.vibrate = null;
1533                    notification.color = mContext.getResources().getColor(
1534                            com.android.internal.R.color.system_notification_accent_color);
1535                    notification.setLatestEventInfo(context, text,
1536                            mContext.getText(R.string.heavy_weight_notification_detail),
1537                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1538                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1539                                    new UserHandle(root.userId)));
1540
1541                    try {
1542                        int[] outId = new int[1];
1543                        inm.enqueueNotificationWithTag("android", "android", null,
1544                                R.string.heavy_weight_notification,
1545                                notification, outId, root.userId);
1546                    } catch (RuntimeException e) {
1547                        Slog.w(ActivityManagerService.TAG,
1548                                "Error showing notification for heavy-weight app", e);
1549                    } catch (RemoteException e) {
1550                    }
1551                } catch (NameNotFoundException e) {
1552                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1553                }
1554            } break;
1555            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1556                INotificationManager inm = NotificationManager.getService();
1557                if (inm == null) {
1558                    return;
1559                }
1560                try {
1561                    inm.cancelNotificationWithTag("android", null,
1562                            R.string.heavy_weight_notification,  msg.arg1);
1563                } catch (RuntimeException e) {
1564                    Slog.w(ActivityManagerService.TAG,
1565                            "Error canceling notification for service", e);
1566                } catch (RemoteException e) {
1567                }
1568            } break;
1569            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1570                synchronized (ActivityManagerService.this) {
1571                    checkExcessivePowerUsageLocked(true);
1572                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1573                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1574                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1575                }
1576            } break;
1577            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1578                synchronized (ActivityManagerService.this) {
1579                    ActivityRecord ar = (ActivityRecord)msg.obj;
1580                    if (mCompatModeDialog != null) {
1581                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1582                                ar.info.applicationInfo.packageName)) {
1583                            return;
1584                        }
1585                        mCompatModeDialog.dismiss();
1586                        mCompatModeDialog = null;
1587                    }
1588                    if (ar != null && false) {
1589                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1590                                ar.packageName)) {
1591                            int mode = mCompatModePackages.computeCompatModeLocked(
1592                                    ar.info.applicationInfo);
1593                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1594                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1595                                mCompatModeDialog = new CompatModeDialog(
1596                                        ActivityManagerService.this, mContext,
1597                                        ar.info.applicationInfo);
1598                                mCompatModeDialog.show();
1599                            }
1600                        }
1601                    }
1602                }
1603                break;
1604            }
1605            case DISPATCH_PROCESSES_CHANGED: {
1606                dispatchProcessesChanged();
1607                break;
1608            }
1609            case DISPATCH_PROCESS_DIED: {
1610                final int pid = msg.arg1;
1611                final int uid = msg.arg2;
1612                dispatchProcessDied(pid, uid);
1613                break;
1614            }
1615            case REPORT_MEM_USAGE_MSG: {
1616                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1617                Thread thread = new Thread() {
1618                    @Override public void run() {
1619                        reportMemUsage(memInfos);
1620                    }
1621                };
1622                thread.start();
1623                break;
1624            }
1625            case START_USER_SWITCH_MSG: {
1626                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1627                break;
1628            }
1629            case REPORT_USER_SWITCH_MSG: {
1630                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1631                break;
1632            }
1633            case CONTINUE_USER_SWITCH_MSG: {
1634                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1635                break;
1636            }
1637            case USER_SWITCH_TIMEOUT_MSG: {
1638                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1639                break;
1640            }
1641            case IMMERSIVE_MODE_LOCK_MSG: {
1642                final boolean nextState = (msg.arg1 != 0);
1643                if (mUpdateLock.isHeld() != nextState) {
1644                    if (DEBUG_IMMERSIVE) {
1645                        final ActivityRecord r = (ActivityRecord) msg.obj;
1646                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1647                    }
1648                    if (nextState) {
1649                        mUpdateLock.acquire();
1650                    } else {
1651                        mUpdateLock.release();
1652                    }
1653                }
1654                break;
1655            }
1656            case PERSIST_URI_GRANTS_MSG: {
1657                writeGrantedUriPermissions();
1658                break;
1659            }
1660            case REQUEST_ALL_PSS_MSG: {
1661                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1662                break;
1663            }
1664            case START_PROFILES_MSG: {
1665                synchronized (ActivityManagerService.this) {
1666                    startProfilesLocked();
1667                }
1668                break;
1669            }
1670            case UPDATE_TIME: {
1671                synchronized (ActivityManagerService.this) {
1672                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1673                        ProcessRecord r = mLruProcesses.get(i);
1674                        if (r.thread != null) {
1675                            try {
1676                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1677                            } catch (RemoteException ex) {
1678                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1679                            }
1680                        }
1681                    }
1682                }
1683                break;
1684            }
1685            case SYSTEM_USER_START_MSG: {
1686                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1687                        Integer.toString(msg.arg1), msg.arg1);
1688                mSystemServiceManager.startUser(msg.arg1);
1689                break;
1690            }
1691            case SYSTEM_USER_CURRENT_MSG: {
1692                mBatteryStatsService.noteEvent(
1693                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1694                        Integer.toString(msg.arg2), msg.arg2);
1695                mBatteryStatsService.noteEvent(
1696                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1697                        Integer.toString(msg.arg1), msg.arg1);
1698                mSystemServiceManager.switchUser(msg.arg1);
1699                break;
1700            }
1701            case ENTER_ANIMATION_COMPLETE_MSG: {
1702                synchronized (ActivityManagerService.this) {
1703                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1704                    if (r != null && r.app != null && r.app.thread != null) {
1705                        try {
1706                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1707                        } catch (RemoteException e) {
1708                        }
1709                    }
1710                }
1711                break;
1712            }
1713            case FINISH_BOOTING_MSG: {
1714                if (msg.arg1 != 0) {
1715                    finishBooting();
1716                }
1717                if (msg.arg2 != 0) {
1718                    enableScreenAfterBoot();
1719                }
1720                break;
1721            }
1722            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1723                try {
1724                    Locale l = (Locale) msg.obj;
1725                    IBinder service = ServiceManager.getService("mount");
1726                    IMountService mountService = IMountService.Stub.asInterface(service);
1727                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1728                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1729                } catch (RemoteException e) {
1730                    Log.e(TAG, "Error storing locale for decryption UI", e);
1731                }
1732                break;
1733            }
1734            case DISMISS_DIALOG_MSG: {
1735                final Dialog d = (Dialog) msg.obj;
1736                d.dismiss();
1737                break;
1738            }
1739            }
1740        }
1741    };
1742
1743    static final int COLLECT_PSS_BG_MSG = 1;
1744
1745    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1746        @Override
1747        public void handleMessage(Message msg) {
1748            switch (msg.what) {
1749            case COLLECT_PSS_BG_MSG: {
1750                long start = SystemClock.uptimeMillis();
1751                MemInfoReader memInfo = null;
1752                synchronized (ActivityManagerService.this) {
1753                    if (mFullPssPending) {
1754                        mFullPssPending = false;
1755                        memInfo = new MemInfoReader();
1756                    }
1757                }
1758                if (memInfo != null) {
1759                    updateCpuStatsNow();
1760                    long nativeTotalPss = 0;
1761                    synchronized (mProcessCpuTracker) {
1762                        final int N = mProcessCpuTracker.countStats();
1763                        for (int j=0; j<N; j++) {
1764                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1765                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1766                                // This is definitely an application process; skip it.
1767                                continue;
1768                            }
1769                            synchronized (mPidsSelfLocked) {
1770                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1771                                    // This is one of our own processes; skip it.
1772                                    continue;
1773                                }
1774                            }
1775                            nativeTotalPss += Debug.getPss(st.pid, null);
1776                        }
1777                    }
1778                    memInfo.readMemInfo();
1779                    synchronized (ActivityManagerService.this) {
1780                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1781                                + (SystemClock.uptimeMillis()-start) + "ms");
1782                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1783                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1784                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1785                    }
1786                }
1787
1788                int i = 0;
1789                int num = 0;
1790                long[] tmp = new long[1];
1791                do {
1792                    ProcessRecord proc;
1793                    int procState;
1794                    int pid;
1795                    synchronized (ActivityManagerService.this) {
1796                        if (i >= mPendingPssProcesses.size()) {
1797                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1798                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1799                            mPendingPssProcesses.clear();
1800                            return;
1801                        }
1802                        proc = mPendingPssProcesses.get(i);
1803                        procState = proc.pssProcState;
1804                        if (proc.thread != null && procState == proc.setProcState) {
1805                            pid = proc.pid;
1806                        } else {
1807                            proc = null;
1808                            pid = 0;
1809                        }
1810                        i++;
1811                    }
1812                    if (proc != null) {
1813                        long pss = Debug.getPss(pid, tmp);
1814                        synchronized (ActivityManagerService.this) {
1815                            if (proc.thread != null && proc.setProcState == procState
1816                                    && proc.pid == pid) {
1817                                num++;
1818                                proc.lastPssTime = SystemClock.uptimeMillis();
1819                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1820                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1821                                        + ": " + pss + " lastPss=" + proc.lastPss
1822                                        + " state=" + ProcessList.makeProcStateString(procState));
1823                                if (proc.initialIdlePss == 0) {
1824                                    proc.initialIdlePss = pss;
1825                                }
1826                                proc.lastPss = pss;
1827                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1828                                    proc.lastCachedPss = pss;
1829                                }
1830                            }
1831                        }
1832                    }
1833                } while (true);
1834            }
1835            }
1836        }
1837    };
1838
1839    /**
1840     * Monitor for package changes and update our internal state.
1841     */
1842    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1843        @Override
1844        public void onPackageRemoved(String packageName, int uid) {
1845            // Remove all tasks with activities in the specified package from the list of recent tasks
1846            final int eventUserId = getChangingUserId();
1847            synchronized (ActivityManagerService.this) {
1848                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1849                    TaskRecord tr = mRecentTasks.get(i);
1850                    if (tr.userId != eventUserId) continue;
1851
1852                    ComponentName cn = tr.intent.getComponent();
1853                    if (cn != null && cn.getPackageName().equals(packageName)) {
1854                        // If the package name matches, remove the task
1855                        removeTaskByIdLocked(tr.taskId, true);
1856                    }
1857                }
1858            }
1859        }
1860
1861        @Override
1862        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1863            onPackageModified(packageName);
1864            return true;
1865        }
1866
1867        @Override
1868        public void onPackageModified(String packageName) {
1869            final int eventUserId = getChangingUserId();
1870            final IPackageManager pm = AppGlobals.getPackageManager();
1871            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1872                    new ArrayList<Pair<Intent, Integer>>();
1873            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1874            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1875            // Copy the list of recent tasks so that we don't hold onto the lock on
1876            // ActivityManagerService for long periods while checking if components exist.
1877            synchronized (ActivityManagerService.this) {
1878                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1879                    TaskRecord tr = mRecentTasks.get(i);
1880                    if (tr.userId != eventUserId) continue;
1881
1882                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1883                }
1884            }
1885            // Check the recent tasks and filter out all tasks with components that no longer exist.
1886            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1887                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1888                ComponentName cn = p.first.getComponent();
1889                if (cn != null && cn.getPackageName().equals(packageName)) {
1890                    if (componentsKnownToExist.contains(cn)) {
1891                        // If we know that the component still exists in the package, then skip
1892                        continue;
1893                    }
1894                    try {
1895                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1896                        if (info != null) {
1897                            componentsKnownToExist.add(cn);
1898                        } else {
1899                            tasksToRemove.add(p.second);
1900                        }
1901                    } catch (RemoteException e) {
1902                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1903                    }
1904                }
1905            }
1906            // Prune all the tasks with removed components from the list of recent tasks
1907            synchronized (ActivityManagerService.this) {
1908                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1909                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1910                }
1911            }
1912        }
1913
1914        @Override
1915        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1916            // Force stop the specified packages
1917            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1918            if (packages != null) {
1919                for (String pkg : packages) {
1920                    synchronized (ActivityManagerService.this) {
1921                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1922                                userId, "finished booting")) {
1923                            return true;
1924                        }
1925                    }
1926                }
1927            }
1928            return false;
1929        }
1930    };
1931
1932    public void setSystemProcess() {
1933        try {
1934            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1935            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1936            ServiceManager.addService("meminfo", new MemBinder(this));
1937            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1938            ServiceManager.addService("dbinfo", new DbBinder(this));
1939            if (MONITOR_CPU_USAGE) {
1940                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1941            }
1942            ServiceManager.addService("permission", new PermissionController(this));
1943
1944            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1945                    "android", STOCK_PM_FLAGS);
1946            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1947
1948            synchronized (this) {
1949                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1950                app.persistent = true;
1951                app.pid = MY_PID;
1952                app.maxAdj = ProcessList.SYSTEM_ADJ;
1953                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1954                mProcessNames.put(app.processName, app.uid, app);
1955                synchronized (mPidsSelfLocked) {
1956                    mPidsSelfLocked.put(app.pid, app);
1957                }
1958                updateLruProcessLocked(app, false, null);
1959                updateOomAdjLocked();
1960            }
1961        } catch (PackageManager.NameNotFoundException e) {
1962            throw new RuntimeException(
1963                    "Unable to find android system package", e);
1964        }
1965    }
1966
1967    public void setWindowManager(WindowManagerService wm) {
1968        mWindowManager = wm;
1969        mStackSupervisor.setWindowManager(wm);
1970    }
1971
1972    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1973        mUsageStatsService = usageStatsManager;
1974    }
1975
1976    public void startObservingNativeCrashes() {
1977        final NativeCrashListener ncl = new NativeCrashListener(this);
1978        ncl.start();
1979    }
1980
1981    public IAppOpsService getAppOpsService() {
1982        return mAppOpsService;
1983    }
1984
1985    static class MemBinder extends Binder {
1986        ActivityManagerService mActivityManagerService;
1987        MemBinder(ActivityManagerService activityManagerService) {
1988            mActivityManagerService = activityManagerService;
1989        }
1990
1991        @Override
1992        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1993            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1994                    != PackageManager.PERMISSION_GRANTED) {
1995                pw.println("Permission Denial: can't dump meminfo from from pid="
1996                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1997                        + " without permission " + android.Manifest.permission.DUMP);
1998                return;
1999            }
2000
2001            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2002        }
2003    }
2004
2005    static class GraphicsBinder extends Binder {
2006        ActivityManagerService mActivityManagerService;
2007        GraphicsBinder(ActivityManagerService activityManagerService) {
2008            mActivityManagerService = activityManagerService;
2009        }
2010
2011        @Override
2012        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2013            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2014                    != PackageManager.PERMISSION_GRANTED) {
2015                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2016                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2017                        + " without permission " + android.Manifest.permission.DUMP);
2018                return;
2019            }
2020
2021            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2022        }
2023    }
2024
2025    static class DbBinder extends Binder {
2026        ActivityManagerService mActivityManagerService;
2027        DbBinder(ActivityManagerService activityManagerService) {
2028            mActivityManagerService = activityManagerService;
2029        }
2030
2031        @Override
2032        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2033            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2034                    != PackageManager.PERMISSION_GRANTED) {
2035                pw.println("Permission Denial: can't dump dbinfo from from pid="
2036                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2037                        + " without permission " + android.Manifest.permission.DUMP);
2038                return;
2039            }
2040
2041            mActivityManagerService.dumpDbInfo(fd, pw, args);
2042        }
2043    }
2044
2045    static class CpuBinder extends Binder {
2046        ActivityManagerService mActivityManagerService;
2047        CpuBinder(ActivityManagerService activityManagerService) {
2048            mActivityManagerService = activityManagerService;
2049        }
2050
2051        @Override
2052        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2053            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2054                    != PackageManager.PERMISSION_GRANTED) {
2055                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2056                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2057                        + " without permission " + android.Manifest.permission.DUMP);
2058                return;
2059            }
2060
2061            synchronized (mActivityManagerService.mProcessCpuTracker) {
2062                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2063                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2064                        SystemClock.uptimeMillis()));
2065            }
2066        }
2067    }
2068
2069    public static final class Lifecycle extends SystemService {
2070        private final ActivityManagerService mService;
2071
2072        public Lifecycle(Context context) {
2073            super(context);
2074            mService = new ActivityManagerService(context);
2075        }
2076
2077        @Override
2078        public void onStart() {
2079            mService.start();
2080        }
2081
2082        public ActivityManagerService getService() {
2083            return mService;
2084        }
2085    }
2086
2087    // Note: This method is invoked on the main thread but may need to attach various
2088    // handlers to other threads.  So take care to be explicit about the looper.
2089    public ActivityManagerService(Context systemContext) {
2090        mContext = systemContext;
2091        mFactoryTest = FactoryTest.getMode();
2092        mSystemThread = ActivityThread.currentActivityThread();
2093
2094        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2095
2096        mHandlerThread = new ServiceThread(TAG,
2097                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2098        mHandlerThread.start();
2099        mHandler = new MainHandler(mHandlerThread.getLooper());
2100
2101        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2102                "foreground", BROADCAST_FG_TIMEOUT, false);
2103        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2104                "background", BROADCAST_BG_TIMEOUT, true);
2105        mBroadcastQueues[0] = mFgBroadcastQueue;
2106        mBroadcastQueues[1] = mBgBroadcastQueue;
2107
2108        mServices = new ActiveServices(this);
2109        mProviderMap = new ProviderMap(this);
2110
2111        // TODO: Move creation of battery stats service outside of activity manager service.
2112        File dataDir = Environment.getDataDirectory();
2113        File systemDir = new File(dataDir, "system");
2114        systemDir.mkdirs();
2115        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2116        mBatteryStatsService.getActiveStatistics().readLocked();
2117        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2118        mOnBattery = DEBUG_POWER ? true
2119                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2120        mBatteryStatsService.getActiveStatistics().setCallback(this);
2121
2122        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2123
2124        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2125
2126        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2127
2128        // User 0 is the first and only user that runs at boot.
2129        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2130        mUserLru.add(Integer.valueOf(0));
2131        updateStartedUserArrayLocked();
2132
2133        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2134            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2135
2136        mConfiguration.setToDefaults();
2137        mConfiguration.setLocale(Locale.getDefault());
2138
2139        mConfigurationSeq = mConfiguration.seq = 1;
2140        mProcessCpuTracker.init();
2141
2142        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2143        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2144        mStackSupervisor = new ActivityStackSupervisor(this);
2145        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2146
2147        mProcessCpuThread = new Thread("CpuTracker") {
2148            @Override
2149            public void run() {
2150                while (true) {
2151                    try {
2152                        try {
2153                            synchronized(this) {
2154                                final long now = SystemClock.uptimeMillis();
2155                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2156                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2157                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2158                                //        + ", write delay=" + nextWriteDelay);
2159                                if (nextWriteDelay < nextCpuDelay) {
2160                                    nextCpuDelay = nextWriteDelay;
2161                                }
2162                                if (nextCpuDelay > 0) {
2163                                    mProcessCpuMutexFree.set(true);
2164                                    this.wait(nextCpuDelay);
2165                                }
2166                            }
2167                        } catch (InterruptedException e) {
2168                        }
2169                        updateCpuStatsNow();
2170                    } catch (Exception e) {
2171                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2172                    }
2173                }
2174            }
2175        };
2176
2177        Watchdog.getInstance().addMonitor(this);
2178        Watchdog.getInstance().addThread(mHandler);
2179    }
2180
2181    public void setSystemServiceManager(SystemServiceManager mgr) {
2182        mSystemServiceManager = mgr;
2183    }
2184
2185    public void setInstaller(Installer installer) {
2186        mInstaller = installer;
2187    }
2188
2189    private void start() {
2190        Process.removeAllProcessGroups();
2191        mProcessCpuThread.start();
2192
2193        mBatteryStatsService.publish(mContext);
2194        mAppOpsService.publish(mContext);
2195        Slog.d("AppOps", "AppOpsService published");
2196        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2197    }
2198
2199    public void initPowerManagement() {
2200        mStackSupervisor.initPowerManagement();
2201        mBatteryStatsService.initPowerManagement();
2202    }
2203
2204    @Override
2205    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2206            throws RemoteException {
2207        if (code == SYSPROPS_TRANSACTION) {
2208            // We need to tell all apps about the system property change.
2209            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2210            synchronized(this) {
2211                final int NP = mProcessNames.getMap().size();
2212                for (int ip=0; ip<NP; ip++) {
2213                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2214                    final int NA = apps.size();
2215                    for (int ia=0; ia<NA; ia++) {
2216                        ProcessRecord app = apps.valueAt(ia);
2217                        if (app.thread != null) {
2218                            procs.add(app.thread.asBinder());
2219                        }
2220                    }
2221                }
2222            }
2223
2224            int N = procs.size();
2225            for (int i=0; i<N; i++) {
2226                Parcel data2 = Parcel.obtain();
2227                try {
2228                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2229                } catch (RemoteException e) {
2230                }
2231                data2.recycle();
2232            }
2233        }
2234        try {
2235            return super.onTransact(code, data, reply, flags);
2236        } catch (RuntimeException e) {
2237            // The activity manager only throws security exceptions, so let's
2238            // log all others.
2239            if (!(e instanceof SecurityException)) {
2240                Slog.wtf(TAG, "Activity Manager Crash", e);
2241            }
2242            throw e;
2243        }
2244    }
2245
2246    void updateCpuStats() {
2247        final long now = SystemClock.uptimeMillis();
2248        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2249            return;
2250        }
2251        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2252            synchronized (mProcessCpuThread) {
2253                mProcessCpuThread.notify();
2254            }
2255        }
2256    }
2257
2258    void updateCpuStatsNow() {
2259        synchronized (mProcessCpuTracker) {
2260            mProcessCpuMutexFree.set(false);
2261            final long now = SystemClock.uptimeMillis();
2262            boolean haveNewCpuStats = false;
2263
2264            if (MONITOR_CPU_USAGE &&
2265                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2266                mLastCpuTime.set(now);
2267                haveNewCpuStats = true;
2268                mProcessCpuTracker.update();
2269                //Slog.i(TAG, mProcessCpu.printCurrentState());
2270                //Slog.i(TAG, "Total CPU usage: "
2271                //        + mProcessCpu.getTotalCpuPercent() + "%");
2272
2273                // Slog the cpu usage if the property is set.
2274                if ("true".equals(SystemProperties.get("events.cpu"))) {
2275                    int user = mProcessCpuTracker.getLastUserTime();
2276                    int system = mProcessCpuTracker.getLastSystemTime();
2277                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2278                    int irq = mProcessCpuTracker.getLastIrqTime();
2279                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2280                    int idle = mProcessCpuTracker.getLastIdleTime();
2281
2282                    int total = user + system + iowait + irq + softIrq + idle;
2283                    if (total == 0) total = 1;
2284
2285                    EventLog.writeEvent(EventLogTags.CPU,
2286                            ((user+system+iowait+irq+softIrq) * 100) / total,
2287                            (user * 100) / total,
2288                            (system * 100) / total,
2289                            (iowait * 100) / total,
2290                            (irq * 100) / total,
2291                            (softIrq * 100) / total);
2292                }
2293            }
2294
2295            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2296            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2297            synchronized(bstats) {
2298                synchronized(mPidsSelfLocked) {
2299                    if (haveNewCpuStats) {
2300                        if (mOnBattery) {
2301                            int perc = bstats.startAddingCpuLocked();
2302                            int totalUTime = 0;
2303                            int totalSTime = 0;
2304                            final int N = mProcessCpuTracker.countStats();
2305                            for (int i=0; i<N; i++) {
2306                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2307                                if (!st.working) {
2308                                    continue;
2309                                }
2310                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2311                                int otherUTime = (st.rel_utime*perc)/100;
2312                                int otherSTime = (st.rel_stime*perc)/100;
2313                                totalUTime += otherUTime;
2314                                totalSTime += otherSTime;
2315                                if (pr != null) {
2316                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2317                                    if (ps == null || !ps.isActive()) {
2318                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2319                                                pr.info.uid, pr.processName);
2320                                    }
2321                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2322                                            st.rel_stime-otherSTime);
2323                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2324                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2325                                } else {
2326                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2327                                    if (ps == null || !ps.isActive()) {
2328                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2329                                                bstats.mapUid(st.uid), st.name);
2330                                    }
2331                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2332                                            st.rel_stime-otherSTime);
2333                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2334                                }
2335                            }
2336                            bstats.finishAddingCpuLocked(perc, totalUTime,
2337                                    totalSTime, cpuSpeedTimes);
2338                        }
2339                    }
2340                }
2341
2342                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2343                    mLastWriteTime = now;
2344                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2345                }
2346            }
2347        }
2348    }
2349
2350    @Override
2351    public void batteryNeedsCpuUpdate() {
2352        updateCpuStatsNow();
2353    }
2354
2355    @Override
2356    public void batteryPowerChanged(boolean onBattery) {
2357        // When plugging in, update the CPU stats first before changing
2358        // the plug state.
2359        updateCpuStatsNow();
2360        synchronized (this) {
2361            synchronized(mPidsSelfLocked) {
2362                mOnBattery = DEBUG_POWER ? true : onBattery;
2363            }
2364        }
2365    }
2366
2367    /**
2368     * Initialize the application bind args. These are passed to each
2369     * process when the bindApplication() IPC is sent to the process. They're
2370     * lazily setup to make sure the services are running when they're asked for.
2371     */
2372    private HashMap<String, IBinder> getCommonServicesLocked() {
2373        if (mAppBindArgs == null) {
2374            mAppBindArgs = new HashMap<String, IBinder>();
2375
2376            // Setup the application init args
2377            mAppBindArgs.put("package", ServiceManager.getService("package"));
2378            mAppBindArgs.put("window", ServiceManager.getService("window"));
2379            mAppBindArgs.put(Context.ALARM_SERVICE,
2380                    ServiceManager.getService(Context.ALARM_SERVICE));
2381        }
2382        return mAppBindArgs;
2383    }
2384
2385    final void setFocusedActivityLocked(ActivityRecord r) {
2386        if (mFocusedActivity != r) {
2387            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2388            mFocusedActivity = r;
2389            if (r.task != null && r.task.voiceInteractor != null) {
2390                startRunningVoiceLocked();
2391            } else {
2392                finishRunningVoiceLocked();
2393            }
2394            mStackSupervisor.setFocusedStack(r);
2395            if (r != null) {
2396                mWindowManager.setFocusedApp(r.appToken, true);
2397            }
2398            applyUpdateLockStateLocked(r);
2399        }
2400    }
2401
2402    final void clearFocusedActivity(ActivityRecord r) {
2403        if (mFocusedActivity == r) {
2404            mFocusedActivity = null;
2405        }
2406    }
2407
2408    @Override
2409    public void setFocusedStack(int stackId) {
2410        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2411        synchronized (ActivityManagerService.this) {
2412            ActivityStack stack = mStackSupervisor.getStack(stackId);
2413            if (stack != null) {
2414                ActivityRecord r = stack.topRunningActivityLocked(null);
2415                if (r != null) {
2416                    setFocusedActivityLocked(r);
2417                }
2418            }
2419        }
2420    }
2421
2422    @Override
2423    public void notifyActivityDrawn(IBinder token) {
2424        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2425        synchronized (this) {
2426            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2427            if (r != null) {
2428                r.task.stack.notifyActivityDrawnLocked(r);
2429            }
2430        }
2431    }
2432
2433    final void applyUpdateLockStateLocked(ActivityRecord r) {
2434        // Modifications to the UpdateLock state are done on our handler, outside
2435        // the activity manager's locks.  The new state is determined based on the
2436        // state *now* of the relevant activity record.  The object is passed to
2437        // the handler solely for logging detail, not to be consulted/modified.
2438        final boolean nextState = r != null && r.immersive;
2439        mHandler.sendMessage(
2440                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2441    }
2442
2443    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2444        Message msg = Message.obtain();
2445        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2446        msg.obj = r.task.askedCompatMode ? null : r;
2447        mHandler.sendMessage(msg);
2448    }
2449
2450    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2451            String what, Object obj, ProcessRecord srcApp) {
2452        app.lastActivityTime = now;
2453
2454        if (app.activities.size() > 0) {
2455            // Don't want to touch dependent processes that are hosting activities.
2456            return index;
2457        }
2458
2459        int lrui = mLruProcesses.lastIndexOf(app);
2460        if (lrui < 0) {
2461            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2462                    + what + " " + obj + " from " + srcApp);
2463            return index;
2464        }
2465
2466        if (lrui >= index) {
2467            // Don't want to cause this to move dependent processes *back* in the
2468            // list as if they were less frequently used.
2469            return index;
2470        }
2471
2472        if (lrui >= mLruProcessActivityStart) {
2473            // Don't want to touch dependent processes that are hosting activities.
2474            return index;
2475        }
2476
2477        mLruProcesses.remove(lrui);
2478        if (index > 0) {
2479            index--;
2480        }
2481        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2482                + " in LRU list: " + app);
2483        mLruProcesses.add(index, app);
2484        return index;
2485    }
2486
2487    final void removeLruProcessLocked(ProcessRecord app) {
2488        int lrui = mLruProcesses.lastIndexOf(app);
2489        if (lrui >= 0) {
2490            if (!app.killed) {
2491                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2492                Process.killProcessQuiet(app.pid);
2493                Process.killProcessGroup(app.info.uid, app.pid);
2494            }
2495            if (lrui <= mLruProcessActivityStart) {
2496                mLruProcessActivityStart--;
2497            }
2498            if (lrui <= mLruProcessServiceStart) {
2499                mLruProcessServiceStart--;
2500            }
2501            mLruProcesses.remove(lrui);
2502        }
2503    }
2504
2505    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2506            ProcessRecord client) {
2507        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2508                || app.treatLikeActivity;
2509        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2510        if (!activityChange && hasActivity) {
2511            // The process has activities, so we are only allowing activity-based adjustments
2512            // to move it.  It should be kept in the front of the list with other
2513            // processes that have activities, and we don't want those to change their
2514            // order except due to activity operations.
2515            return;
2516        }
2517
2518        mLruSeq++;
2519        final long now = SystemClock.uptimeMillis();
2520        app.lastActivityTime = now;
2521
2522        // First a quick reject: if the app is already at the position we will
2523        // put it, then there is nothing to do.
2524        if (hasActivity) {
2525            final int N = mLruProcesses.size();
2526            if (N > 0 && mLruProcesses.get(N-1) == app) {
2527                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2528                return;
2529            }
2530        } else {
2531            if (mLruProcessServiceStart > 0
2532                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2533                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2534                return;
2535            }
2536        }
2537
2538        int lrui = mLruProcesses.lastIndexOf(app);
2539
2540        if (app.persistent && lrui >= 0) {
2541            // We don't care about the position of persistent processes, as long as
2542            // they are in the list.
2543            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2544            return;
2545        }
2546
2547        /* In progress: compute new position first, so we can avoid doing work
2548           if the process is not actually going to move.  Not yet working.
2549        int addIndex;
2550        int nextIndex;
2551        boolean inActivity = false, inService = false;
2552        if (hasActivity) {
2553            // Process has activities, put it at the very tipsy-top.
2554            addIndex = mLruProcesses.size();
2555            nextIndex = mLruProcessServiceStart;
2556            inActivity = true;
2557        } else if (hasService) {
2558            // Process has services, put it at the top of the service list.
2559            addIndex = mLruProcessActivityStart;
2560            nextIndex = mLruProcessServiceStart;
2561            inActivity = true;
2562            inService = true;
2563        } else  {
2564            // Process not otherwise of interest, it goes to the top of the non-service area.
2565            addIndex = mLruProcessServiceStart;
2566            if (client != null) {
2567                int clientIndex = mLruProcesses.lastIndexOf(client);
2568                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2569                        + app);
2570                if (clientIndex >= 0 && addIndex > clientIndex) {
2571                    addIndex = clientIndex;
2572                }
2573            }
2574            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2575        }
2576
2577        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2578                + mLruProcessActivityStart + "): " + app);
2579        */
2580
2581        if (lrui >= 0) {
2582            if (lrui < mLruProcessActivityStart) {
2583                mLruProcessActivityStart--;
2584            }
2585            if (lrui < mLruProcessServiceStart) {
2586                mLruProcessServiceStart--;
2587            }
2588            /*
2589            if (addIndex > lrui) {
2590                addIndex--;
2591            }
2592            if (nextIndex > lrui) {
2593                nextIndex--;
2594            }
2595            */
2596            mLruProcesses.remove(lrui);
2597        }
2598
2599        /*
2600        mLruProcesses.add(addIndex, app);
2601        if (inActivity) {
2602            mLruProcessActivityStart++;
2603        }
2604        if (inService) {
2605            mLruProcessActivityStart++;
2606        }
2607        */
2608
2609        int nextIndex;
2610        if (hasActivity) {
2611            final int N = mLruProcesses.size();
2612            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2613                // Process doesn't have activities, but has clients with
2614                // activities...  move it up, but one below the top (the top
2615                // should always have a real activity).
2616                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2617                mLruProcesses.add(N-1, app);
2618                // To keep it from spamming the LRU list (by making a bunch of clients),
2619                // we will push down any other entries owned by the app.
2620                final int uid = app.info.uid;
2621                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2622                    ProcessRecord subProc = mLruProcesses.get(i);
2623                    if (subProc.info.uid == uid) {
2624                        // We want to push this one down the list.  If the process after
2625                        // it is for the same uid, however, don't do so, because we don't
2626                        // want them internally to be re-ordered.
2627                        if (mLruProcesses.get(i-1).info.uid != uid) {
2628                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2629                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2630                            ProcessRecord tmp = mLruProcesses.get(i);
2631                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2632                            mLruProcesses.set(i-1, tmp);
2633                            i--;
2634                        }
2635                    } else {
2636                        // A gap, we can stop here.
2637                        break;
2638                    }
2639                }
2640            } else {
2641                // Process has activities, put it at the very tipsy-top.
2642                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2643                mLruProcesses.add(app);
2644            }
2645            nextIndex = mLruProcessServiceStart;
2646        } else if (hasService) {
2647            // Process has services, put it at the top of the service list.
2648            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2649            mLruProcesses.add(mLruProcessActivityStart, app);
2650            nextIndex = mLruProcessServiceStart;
2651            mLruProcessActivityStart++;
2652        } else  {
2653            // Process not otherwise of interest, it goes to the top of the non-service area.
2654            int index = mLruProcessServiceStart;
2655            if (client != null) {
2656                // If there is a client, don't allow the process to be moved up higher
2657                // in the list than that client.
2658                int clientIndex = mLruProcesses.lastIndexOf(client);
2659                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2660                        + " when updating " + app);
2661                if (clientIndex <= lrui) {
2662                    // Don't allow the client index restriction to push it down farther in the
2663                    // list than it already is.
2664                    clientIndex = lrui;
2665                }
2666                if (clientIndex >= 0 && index > clientIndex) {
2667                    index = clientIndex;
2668                }
2669            }
2670            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2671            mLruProcesses.add(index, app);
2672            nextIndex = index-1;
2673            mLruProcessActivityStart++;
2674            mLruProcessServiceStart++;
2675        }
2676
2677        // If the app is currently using a content provider or service,
2678        // bump those processes as well.
2679        for (int j=app.connections.size()-1; j>=0; j--) {
2680            ConnectionRecord cr = app.connections.valueAt(j);
2681            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2682                    && cr.binding.service.app != null
2683                    && cr.binding.service.app.lruSeq != mLruSeq
2684                    && !cr.binding.service.app.persistent) {
2685                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2686                        "service connection", cr, app);
2687            }
2688        }
2689        for (int j=app.conProviders.size()-1; j>=0; j--) {
2690            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2691            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2692                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2693                        "provider reference", cpr, app);
2694            }
2695        }
2696    }
2697
2698    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2699        if (uid == Process.SYSTEM_UID) {
2700            // The system gets to run in any process.  If there are multiple
2701            // processes with the same uid, just pick the first (this
2702            // should never happen).
2703            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2704            if (procs == null) return null;
2705            final int N = procs.size();
2706            for (int i = 0; i < N; i++) {
2707                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2708            }
2709        }
2710        ProcessRecord proc = mProcessNames.get(processName, uid);
2711        if (false && proc != null && !keepIfLarge
2712                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2713                && proc.lastCachedPss >= 4000) {
2714            // Turn this condition on to cause killing to happen regularly, for testing.
2715            if (proc.baseProcessTracker != null) {
2716                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2717            }
2718            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2719        } else if (proc != null && !keepIfLarge
2720                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2721                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2722            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2723            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2724                if (proc.baseProcessTracker != null) {
2725                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2726                }
2727                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2728            }
2729        }
2730        return proc;
2731    }
2732
2733    void ensurePackageDexOpt(String packageName) {
2734        IPackageManager pm = AppGlobals.getPackageManager();
2735        try {
2736            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2737                mDidDexOpt = true;
2738            }
2739        } catch (RemoteException e) {
2740        }
2741    }
2742
2743    boolean isNextTransitionForward() {
2744        int transit = mWindowManager.getPendingAppTransition();
2745        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2746                || transit == AppTransition.TRANSIT_TASK_OPEN
2747                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2748    }
2749
2750    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2751            String processName, String abiOverride, int uid, Runnable crashHandler) {
2752        synchronized(this) {
2753            ApplicationInfo info = new ApplicationInfo();
2754            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2755            // For isolated processes, the former contains the parent's uid and the latter the
2756            // actual uid of the isolated process.
2757            // In the special case introduced by this method (which is, starting an isolated
2758            // process directly from the SystemServer without an actual parent app process) the
2759            // closest thing to a parent's uid is SYSTEM_UID.
2760            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2761            // the |isolated| logic in the ProcessRecord constructor.
2762            info.uid = Process.SYSTEM_UID;
2763            info.processName = processName;
2764            info.className = entryPoint;
2765            info.packageName = "android";
2766            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2767                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2768                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2769                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2770                    crashHandler);
2771            return proc != null ? proc.pid : 0;
2772        }
2773    }
2774
2775    final ProcessRecord startProcessLocked(String processName,
2776            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2777            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2778            boolean isolated, boolean keepIfLarge) {
2779        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2780                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2781                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2782                null /* crashHandler */);
2783    }
2784
2785    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2786            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2787            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2788            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2789        long startTime = SystemClock.elapsedRealtime();
2790        ProcessRecord app;
2791        if (!isolated) {
2792            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2793            checkTime(startTime, "startProcess: after getProcessRecord");
2794        } else {
2795            // If this is an isolated process, it can't re-use an existing process.
2796            app = null;
2797        }
2798        // We don't have to do anything more if:
2799        // (1) There is an existing application record; and
2800        // (2) The caller doesn't think it is dead, OR there is no thread
2801        //     object attached to it so we know it couldn't have crashed; and
2802        // (3) There is a pid assigned to it, so it is either starting or
2803        //     already running.
2804        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2805                + " app=" + app + " knownToBeDead=" + knownToBeDead
2806                + " thread=" + (app != null ? app.thread : null)
2807                + " pid=" + (app != null ? app.pid : -1));
2808        if (app != null && app.pid > 0) {
2809            if (!knownToBeDead || app.thread == null) {
2810                // We already have the app running, or are waiting for it to
2811                // come up (we have a pid but not yet its thread), so keep it.
2812                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2813                // If this is a new package in the process, add the package to the list
2814                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2815                checkTime(startTime, "startProcess: done, added package to proc");
2816                return app;
2817            }
2818
2819            // An application record is attached to a previous process,
2820            // clean it up now.
2821            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2822            checkTime(startTime, "startProcess: bad proc running, killing");
2823            Process.killProcessGroup(app.info.uid, app.pid);
2824            handleAppDiedLocked(app, true, true);
2825            checkTime(startTime, "startProcess: done killing old proc");
2826        }
2827
2828        String hostingNameStr = hostingName != null
2829                ? hostingName.flattenToShortString() : null;
2830
2831        if (!isolated) {
2832            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2833                // If we are in the background, then check to see if this process
2834                // is bad.  If so, we will just silently fail.
2835                if (mBadProcesses.get(info.processName, info.uid) != null) {
2836                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2837                            + "/" + info.processName);
2838                    return null;
2839                }
2840            } else {
2841                // When the user is explicitly starting a process, then clear its
2842                // crash count so that we won't make it bad until they see at
2843                // least one crash dialog again, and make the process good again
2844                // if it had been bad.
2845                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2846                        + "/" + info.processName);
2847                mProcessCrashTimes.remove(info.processName, info.uid);
2848                if (mBadProcesses.get(info.processName, info.uid) != null) {
2849                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2850                            UserHandle.getUserId(info.uid), info.uid,
2851                            info.processName);
2852                    mBadProcesses.remove(info.processName, info.uid);
2853                    if (app != null) {
2854                        app.bad = false;
2855                    }
2856                }
2857            }
2858        }
2859
2860        if (app == null) {
2861            checkTime(startTime, "startProcess: creating new process record");
2862            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2863            app.crashHandler = crashHandler;
2864            if (app == null) {
2865                Slog.w(TAG, "Failed making new process record for "
2866                        + processName + "/" + info.uid + " isolated=" + isolated);
2867                return null;
2868            }
2869            mProcessNames.put(processName, app.uid, app);
2870            if (isolated) {
2871                mIsolatedProcesses.put(app.uid, app);
2872            }
2873            checkTime(startTime, "startProcess: done creating new process record");
2874        } else {
2875            // If this is a new package in the process, add the package to the list
2876            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2877            checkTime(startTime, "startProcess: added package to existing proc");
2878        }
2879
2880        // If the system is not ready yet, then hold off on starting this
2881        // process until it is.
2882        if (!mProcessesReady
2883                && !isAllowedWhileBooting(info)
2884                && !allowWhileBooting) {
2885            if (!mProcessesOnHold.contains(app)) {
2886                mProcessesOnHold.add(app);
2887            }
2888            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2889            checkTime(startTime, "startProcess: returning with proc on hold");
2890            return app;
2891        }
2892
2893        checkTime(startTime, "startProcess: stepping in to startProcess");
2894        startProcessLocked(
2895                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2896        checkTime(startTime, "startProcess: done starting proc!");
2897        return (app.pid != 0) ? app : null;
2898    }
2899
2900    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2901        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2902    }
2903
2904    private final void startProcessLocked(ProcessRecord app,
2905            String hostingType, String hostingNameStr) {
2906        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2907                null /* entryPoint */, null /* entryPointArgs */);
2908    }
2909
2910    private final void startProcessLocked(ProcessRecord app, String hostingType,
2911            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2912        long startTime = SystemClock.elapsedRealtime();
2913        if (app.pid > 0 && app.pid != MY_PID) {
2914            checkTime(startTime, "startProcess: removing from pids map");
2915            synchronized (mPidsSelfLocked) {
2916                mPidsSelfLocked.remove(app.pid);
2917                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2918            }
2919            checkTime(startTime, "startProcess: done removing from pids map");
2920            app.setPid(0);
2921        }
2922
2923        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2924                "startProcessLocked removing on hold: " + app);
2925        mProcessesOnHold.remove(app);
2926
2927        checkTime(startTime, "startProcess: starting to update cpu stats");
2928        updateCpuStats();
2929        checkTime(startTime, "startProcess: done updating cpu stats");
2930
2931        try {
2932            int uid = app.uid;
2933
2934            int[] gids = null;
2935            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2936            if (!app.isolated) {
2937                int[] permGids = null;
2938                try {
2939                    checkTime(startTime, "startProcess: getting gids from package manager");
2940                    final PackageManager pm = mContext.getPackageManager();
2941                    permGids = pm.getPackageGids(app.info.packageName);
2942
2943                    if (Environment.isExternalStorageEmulated()) {
2944                        checkTime(startTime, "startProcess: checking external storage perm");
2945                        if (pm.checkPermission(
2946                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2947                                app.info.packageName) == PERMISSION_GRANTED) {
2948                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2949                        } else {
2950                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2951                        }
2952                    }
2953                } catch (PackageManager.NameNotFoundException e) {
2954                    Slog.w(TAG, "Unable to retrieve gids", e);
2955                }
2956
2957                /*
2958                 * Add shared application and profile GIDs so applications can share some
2959                 * resources like shared libraries and access user-wide resources
2960                 */
2961                if (permGids == null) {
2962                    gids = new int[2];
2963                } else {
2964                    gids = new int[permGids.length + 2];
2965                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2966                }
2967                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2968                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2969            }
2970            checkTime(startTime, "startProcess: building args");
2971            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2972                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2973                        && mTopComponent != null
2974                        && app.processName.equals(mTopComponent.getPackageName())) {
2975                    uid = 0;
2976                }
2977                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2978                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2979                    uid = 0;
2980                }
2981            }
2982            int debugFlags = 0;
2983            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2984                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2985                // Also turn on CheckJNI for debuggable apps. It's quite
2986                // awkward to turn on otherwise.
2987                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2988            }
2989            // Run the app in safe mode if its manifest requests so or the
2990            // system is booted in safe mode.
2991            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2992                mSafeMode == true) {
2993                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2994            }
2995            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2996                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2997            }
2998            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2999                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3000            }
3001            if ("1".equals(SystemProperties.get("debug.assert"))) {
3002                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3003            }
3004
3005            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3006            if (requiredAbi == null) {
3007                requiredAbi = Build.SUPPORTED_ABIS[0];
3008            }
3009
3010            String instructionSet = null;
3011            if (app.info.primaryCpuAbi != null) {
3012                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3013            }
3014
3015            // Start the process.  It will either succeed and return a result containing
3016            // the PID of the new process, or else throw a RuntimeException.
3017            boolean isActivityProcess = (entryPoint == null);
3018            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3019            checkTime(startTime, "startProcess: asking zygote to start proc");
3020            Process.ProcessStartResult startResult = Process.start(entryPoint,
3021                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3022                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3023                    app.info.dataDir, entryPointArgs);
3024            checkTime(startTime, "startProcess: returned from zygote!");
3025
3026            if (app.isolated) {
3027                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3028            }
3029            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3030            checkTime(startTime, "startProcess: done updating battery stats");
3031
3032            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3033                    UserHandle.getUserId(uid), startResult.pid, uid,
3034                    app.processName, hostingType,
3035                    hostingNameStr != null ? hostingNameStr : "");
3036
3037            if (app.persistent) {
3038                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3039            }
3040
3041            checkTime(startTime, "startProcess: building log message");
3042            StringBuilder buf = mStringBuilder;
3043            buf.setLength(0);
3044            buf.append("Start proc ");
3045            buf.append(app.processName);
3046            if (!isActivityProcess) {
3047                buf.append(" [");
3048                buf.append(entryPoint);
3049                buf.append("]");
3050            }
3051            buf.append(" for ");
3052            buf.append(hostingType);
3053            if (hostingNameStr != null) {
3054                buf.append(" ");
3055                buf.append(hostingNameStr);
3056            }
3057            buf.append(": pid=");
3058            buf.append(startResult.pid);
3059            buf.append(" uid=");
3060            buf.append(uid);
3061            buf.append(" gids={");
3062            if (gids != null) {
3063                for (int gi=0; gi<gids.length; gi++) {
3064                    if (gi != 0) buf.append(", ");
3065                    buf.append(gids[gi]);
3066
3067                }
3068            }
3069            buf.append("}");
3070            if (requiredAbi != null) {
3071                buf.append(" abi=");
3072                buf.append(requiredAbi);
3073            }
3074            Slog.i(TAG, buf.toString());
3075            app.setPid(startResult.pid);
3076            app.usingWrapper = startResult.usingWrapper;
3077            app.removed = false;
3078            app.killed = false;
3079            app.killedByAm = false;
3080            checkTime(startTime, "startProcess: starting to update pids map");
3081            synchronized (mPidsSelfLocked) {
3082                this.mPidsSelfLocked.put(startResult.pid, app);
3083                if (isActivityProcess) {
3084                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3085                    msg.obj = app;
3086                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3087                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3088                }
3089            }
3090            checkTime(startTime, "startProcess: done updating pids map");
3091        } catch (RuntimeException e) {
3092            // XXX do better error recovery.
3093            app.setPid(0);
3094            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3095            if (app.isolated) {
3096                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3097            }
3098            Slog.e(TAG, "Failure starting process " + app.processName, e);
3099        }
3100    }
3101
3102    void updateUsageStats(ActivityRecord component, boolean resumed) {
3103        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3104        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3105        if (resumed) {
3106            if (mUsageStatsService != null) {
3107                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3108                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3109            }
3110            synchronized (stats) {
3111                stats.noteActivityResumedLocked(component.app.uid);
3112            }
3113        } else {
3114            if (mUsageStatsService != null) {
3115                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3116                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3117            }
3118            synchronized (stats) {
3119                stats.noteActivityPausedLocked(component.app.uid);
3120            }
3121        }
3122    }
3123
3124    Intent getHomeIntent() {
3125        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3126        intent.setComponent(mTopComponent);
3127        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3128            intent.addCategory(Intent.CATEGORY_HOME);
3129        }
3130        return intent;
3131    }
3132
3133    boolean startHomeActivityLocked(int userId) {
3134        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3135                && mTopAction == null) {
3136            // We are running in factory test mode, but unable to find
3137            // the factory test app, so just sit around displaying the
3138            // error message and don't try to start anything.
3139            return false;
3140        }
3141        Intent intent = getHomeIntent();
3142        ActivityInfo aInfo =
3143            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3144        if (aInfo != null) {
3145            intent.setComponent(new ComponentName(
3146                    aInfo.applicationInfo.packageName, aInfo.name));
3147            // Don't do this if the home app is currently being
3148            // instrumented.
3149            aInfo = new ActivityInfo(aInfo);
3150            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3151            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3152                    aInfo.applicationInfo.uid, true);
3153            if (app == null || app.instrumentationClass == null) {
3154                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3155                mStackSupervisor.startHomeActivity(intent, aInfo);
3156            }
3157        }
3158
3159        return true;
3160    }
3161
3162    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3163        ActivityInfo ai = null;
3164        ComponentName comp = intent.getComponent();
3165        try {
3166            if (comp != null) {
3167                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3168            } else {
3169                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3170                        intent,
3171                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3172                            flags, userId);
3173
3174                if (info != null) {
3175                    ai = info.activityInfo;
3176                }
3177            }
3178        } catch (RemoteException e) {
3179            // ignore
3180        }
3181
3182        return ai;
3183    }
3184
3185    /**
3186     * Starts the "new version setup screen" if appropriate.
3187     */
3188    void startSetupActivityLocked() {
3189        // Only do this once per boot.
3190        if (mCheckedForSetup) {
3191            return;
3192        }
3193
3194        // We will show this screen if the current one is a different
3195        // version than the last one shown, and we are not running in
3196        // low-level factory test mode.
3197        final ContentResolver resolver = mContext.getContentResolver();
3198        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3199                Settings.Global.getInt(resolver,
3200                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3201            mCheckedForSetup = true;
3202
3203            // See if we should be showing the platform update setup UI.
3204            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3205            List<ResolveInfo> ris = mContext.getPackageManager()
3206                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3207
3208            // We don't allow third party apps to replace this.
3209            ResolveInfo ri = null;
3210            for (int i=0; ris != null && i<ris.size(); i++) {
3211                if ((ris.get(i).activityInfo.applicationInfo.flags
3212                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3213                    ri = ris.get(i);
3214                    break;
3215                }
3216            }
3217
3218            if (ri != null) {
3219                String vers = ri.activityInfo.metaData != null
3220                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3221                        : null;
3222                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3223                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3224                            Intent.METADATA_SETUP_VERSION);
3225                }
3226                String lastVers = Settings.Secure.getString(
3227                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3228                if (vers != null && !vers.equals(lastVers)) {
3229                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3230                    intent.setComponent(new ComponentName(
3231                            ri.activityInfo.packageName, ri.activityInfo.name));
3232                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3233                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3234                            null);
3235                }
3236            }
3237        }
3238    }
3239
3240    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3241        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3242    }
3243
3244    void enforceNotIsolatedCaller(String caller) {
3245        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3246            throw new SecurityException("Isolated process not allowed to call " + caller);
3247        }
3248    }
3249
3250    void enforceShellRestriction(String restriction, int userHandle) {
3251        if (Binder.getCallingUid() == Process.SHELL_UID) {
3252            if (userHandle < 0
3253                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3254                throw new SecurityException("Shell does not have permission to access user "
3255                        + userHandle);
3256            }
3257        }
3258    }
3259
3260    @Override
3261    public int getFrontActivityScreenCompatMode() {
3262        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3263        synchronized (this) {
3264            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3265        }
3266    }
3267
3268    @Override
3269    public void setFrontActivityScreenCompatMode(int mode) {
3270        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3271                "setFrontActivityScreenCompatMode");
3272        synchronized (this) {
3273            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3274        }
3275    }
3276
3277    @Override
3278    public int getPackageScreenCompatMode(String packageName) {
3279        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3280        synchronized (this) {
3281            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3282        }
3283    }
3284
3285    @Override
3286    public void setPackageScreenCompatMode(String packageName, int mode) {
3287        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3288                "setPackageScreenCompatMode");
3289        synchronized (this) {
3290            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3291        }
3292    }
3293
3294    @Override
3295    public boolean getPackageAskScreenCompat(String packageName) {
3296        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3297        synchronized (this) {
3298            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3299        }
3300    }
3301
3302    @Override
3303    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3304        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3305                "setPackageAskScreenCompat");
3306        synchronized (this) {
3307            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3308        }
3309    }
3310
3311    private void dispatchProcessesChanged() {
3312        int N;
3313        synchronized (this) {
3314            N = mPendingProcessChanges.size();
3315            if (mActiveProcessChanges.length < N) {
3316                mActiveProcessChanges = new ProcessChangeItem[N];
3317            }
3318            mPendingProcessChanges.toArray(mActiveProcessChanges);
3319            mAvailProcessChanges.addAll(mPendingProcessChanges);
3320            mPendingProcessChanges.clear();
3321            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3322        }
3323
3324        int i = mProcessObservers.beginBroadcast();
3325        while (i > 0) {
3326            i--;
3327            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3328            if (observer != null) {
3329                try {
3330                    for (int j=0; j<N; j++) {
3331                        ProcessChangeItem item = mActiveProcessChanges[j];
3332                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3333                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3334                                    + item.pid + " uid=" + item.uid + ": "
3335                                    + item.foregroundActivities);
3336                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3337                                    item.foregroundActivities);
3338                        }
3339                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3340                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3341                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3342                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3343                        }
3344                    }
3345                } catch (RemoteException e) {
3346                }
3347            }
3348        }
3349        mProcessObservers.finishBroadcast();
3350    }
3351
3352    private void dispatchProcessDied(int pid, int uid) {
3353        int i = mProcessObservers.beginBroadcast();
3354        while (i > 0) {
3355            i--;
3356            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3357            if (observer != null) {
3358                try {
3359                    observer.onProcessDied(pid, uid);
3360                } catch (RemoteException e) {
3361                }
3362            }
3363        }
3364        mProcessObservers.finishBroadcast();
3365    }
3366
3367    @Override
3368    public final int startActivity(IApplicationThread caller, String callingPackage,
3369            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3370            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3371        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3372            resultWho, requestCode, startFlags, profilerInfo, options,
3373            UserHandle.getCallingUserId());
3374    }
3375
3376    @Override
3377    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3378            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3379            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3380        enforceNotIsolatedCaller("startActivity");
3381        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3382                false, ALLOW_FULL_ONLY, "startActivity", null);
3383        // TODO: Switch to user app stacks here.
3384        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3385                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3386                profilerInfo, null, null, options, userId, null, null);
3387    }
3388
3389    @Override
3390    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3391            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3392            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3393
3394        // This is very dangerous -- it allows you to perform a start activity (including
3395        // permission grants) as any app that may launch one of your own activities.  So
3396        // we will only allow this to be done from activities that are part of the core framework,
3397        // and then only when they are running as the system.
3398        final ActivityRecord sourceRecord;
3399        final int targetUid;
3400        final String targetPackage;
3401        synchronized (this) {
3402            if (resultTo == null) {
3403                throw new SecurityException("Must be called from an activity");
3404            }
3405            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3406            if (sourceRecord == null) {
3407                throw new SecurityException("Called with bad activity token: " + resultTo);
3408            }
3409            if (!sourceRecord.info.packageName.equals("android")) {
3410                throw new SecurityException(
3411                        "Must be called from an activity that is declared in the android package");
3412            }
3413            if (sourceRecord.app == null) {
3414                throw new SecurityException("Called without a process attached to activity");
3415            }
3416            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3417                // This is still okay, as long as this activity is running under the
3418                // uid of the original calling activity.
3419                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3420                    throw new SecurityException(
3421                            "Calling activity in uid " + sourceRecord.app.uid
3422                                    + " must be system uid or original calling uid "
3423                                    + sourceRecord.launchedFromUid);
3424                }
3425            }
3426            targetUid = sourceRecord.launchedFromUid;
3427            targetPackage = sourceRecord.launchedFromPackage;
3428        }
3429
3430        if (userId == UserHandle.USER_NULL) {
3431            userId = UserHandle.getUserId(sourceRecord.app.uid);
3432        }
3433
3434        // TODO: Switch to user app stacks here.
3435        try {
3436            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3437                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3438                    null, null, options, userId, null, null);
3439            return ret;
3440        } catch (SecurityException e) {
3441            // XXX need to figure out how to propagate to original app.
3442            // A SecurityException here is generally actually a fault of the original
3443            // calling activity (such as a fairly granting permissions), so propagate it
3444            // back to them.
3445            /*
3446            StringBuilder msg = new StringBuilder();
3447            msg.append("While launching");
3448            msg.append(intent.toString());
3449            msg.append(": ");
3450            msg.append(e.getMessage());
3451            */
3452            throw e;
3453        }
3454    }
3455
3456    @Override
3457    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3458            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3459            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3460        enforceNotIsolatedCaller("startActivityAndWait");
3461        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3462                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3463        WaitResult res = new WaitResult();
3464        // TODO: Switch to user app stacks here.
3465        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3466                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3467                options, userId, null, null);
3468        return res;
3469    }
3470
3471    @Override
3472    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3473            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3474            int startFlags, Configuration config, Bundle options, int userId) {
3475        enforceNotIsolatedCaller("startActivityWithConfig");
3476        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3477                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3478        // TODO: Switch to user app stacks here.
3479        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3480                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3481                null, null, config, options, userId, null, null);
3482        return ret;
3483    }
3484
3485    @Override
3486    public int startActivityIntentSender(IApplicationThread caller,
3487            IntentSender intent, Intent fillInIntent, String resolvedType,
3488            IBinder resultTo, String resultWho, int requestCode,
3489            int flagsMask, int flagsValues, Bundle options) {
3490        enforceNotIsolatedCaller("startActivityIntentSender");
3491        // Refuse possible leaked file descriptors
3492        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3493            throw new IllegalArgumentException("File descriptors passed in Intent");
3494        }
3495
3496        IIntentSender sender = intent.getTarget();
3497        if (!(sender instanceof PendingIntentRecord)) {
3498            throw new IllegalArgumentException("Bad PendingIntent object");
3499        }
3500
3501        PendingIntentRecord pir = (PendingIntentRecord)sender;
3502
3503        synchronized (this) {
3504            // If this is coming from the currently resumed activity, it is
3505            // effectively saying that app switches are allowed at this point.
3506            final ActivityStack stack = getFocusedStack();
3507            if (stack.mResumedActivity != null &&
3508                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3509                mAppSwitchesAllowedTime = 0;
3510            }
3511        }
3512        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3513                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3514        return ret;
3515    }
3516
3517    @Override
3518    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3519            Intent intent, String resolvedType, IVoiceInteractionSession session,
3520            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3521            Bundle options, int userId) {
3522        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3523                != PackageManager.PERMISSION_GRANTED) {
3524            String msg = "Permission Denial: startVoiceActivity() from pid="
3525                    + Binder.getCallingPid()
3526                    + ", uid=" + Binder.getCallingUid()
3527                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3528            Slog.w(TAG, msg);
3529            throw new SecurityException(msg);
3530        }
3531        if (session == null || interactor == null) {
3532            throw new NullPointerException("null session or interactor");
3533        }
3534        userId = handleIncomingUser(callingPid, callingUid, userId,
3535                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3536        // TODO: Switch to user app stacks here.
3537        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3538                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3539                null, options, userId, null, null);
3540    }
3541
3542    @Override
3543    public boolean startNextMatchingActivity(IBinder callingActivity,
3544            Intent intent, Bundle options) {
3545        // Refuse possible leaked file descriptors
3546        if (intent != null && intent.hasFileDescriptors() == true) {
3547            throw new IllegalArgumentException("File descriptors passed in Intent");
3548        }
3549
3550        synchronized (this) {
3551            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3552            if (r == null) {
3553                ActivityOptions.abort(options);
3554                return false;
3555            }
3556            if (r.app == null || r.app.thread == null) {
3557                // The caller is not running...  d'oh!
3558                ActivityOptions.abort(options);
3559                return false;
3560            }
3561            intent = new Intent(intent);
3562            // The caller is not allowed to change the data.
3563            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3564            // And we are resetting to find the next component...
3565            intent.setComponent(null);
3566
3567            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3568
3569            ActivityInfo aInfo = null;
3570            try {
3571                List<ResolveInfo> resolves =
3572                    AppGlobals.getPackageManager().queryIntentActivities(
3573                            intent, r.resolvedType,
3574                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3575                            UserHandle.getCallingUserId());
3576
3577                // Look for the original activity in the list...
3578                final int N = resolves != null ? resolves.size() : 0;
3579                for (int i=0; i<N; i++) {
3580                    ResolveInfo rInfo = resolves.get(i);
3581                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3582                            && rInfo.activityInfo.name.equals(r.info.name)) {
3583                        // We found the current one...  the next matching is
3584                        // after it.
3585                        i++;
3586                        if (i<N) {
3587                            aInfo = resolves.get(i).activityInfo;
3588                        }
3589                        if (debug) {
3590                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3591                                    + "/" + r.info.name);
3592                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3593                                    + "/" + aInfo.name);
3594                        }
3595                        break;
3596                    }
3597                }
3598            } catch (RemoteException e) {
3599            }
3600
3601            if (aInfo == null) {
3602                // Nobody who is next!
3603                ActivityOptions.abort(options);
3604                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3605                return false;
3606            }
3607
3608            intent.setComponent(new ComponentName(
3609                    aInfo.applicationInfo.packageName, aInfo.name));
3610            intent.setFlags(intent.getFlags()&~(
3611                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3612                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3613                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3614                    Intent.FLAG_ACTIVITY_NEW_TASK));
3615
3616            // Okay now we need to start the new activity, replacing the
3617            // currently running activity.  This is a little tricky because
3618            // we want to start the new one as if the current one is finished,
3619            // but not finish the current one first so that there is no flicker.
3620            // And thus...
3621            final boolean wasFinishing = r.finishing;
3622            r.finishing = true;
3623
3624            // Propagate reply information over to the new activity.
3625            final ActivityRecord resultTo = r.resultTo;
3626            final String resultWho = r.resultWho;
3627            final int requestCode = r.requestCode;
3628            r.resultTo = null;
3629            if (resultTo != null) {
3630                resultTo.removeResultsLocked(r, resultWho, requestCode);
3631            }
3632
3633            final long origId = Binder.clearCallingIdentity();
3634            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3635                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3636                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3637                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3638            Binder.restoreCallingIdentity(origId);
3639
3640            r.finishing = wasFinishing;
3641            if (res != ActivityManager.START_SUCCESS) {
3642                return false;
3643            }
3644            return true;
3645        }
3646    }
3647
3648    @Override
3649    public final int startActivityFromRecents(int taskId, Bundle options) {
3650        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3651            String msg = "Permission Denial: startActivityFromRecents called without " +
3652                    START_TASKS_FROM_RECENTS;
3653            Slog.w(TAG, msg);
3654            throw new SecurityException(msg);
3655        }
3656        return startActivityFromRecentsInner(taskId, options);
3657    }
3658
3659    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3660        final TaskRecord task;
3661        final int callingUid;
3662        final String callingPackage;
3663        final Intent intent;
3664        final int userId;
3665        synchronized (this) {
3666            task = recentTaskForIdLocked(taskId);
3667            if (task == null) {
3668                throw new IllegalArgumentException("Task " + taskId + " not found.");
3669            }
3670            callingUid = task.mCallingUid;
3671            callingPackage = task.mCallingPackage;
3672            intent = task.intent;
3673            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3674            userId = task.userId;
3675        }
3676        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3677                options, userId, null, task);
3678    }
3679
3680    final int startActivityInPackage(int uid, String callingPackage,
3681            Intent intent, String resolvedType, IBinder resultTo,
3682            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3683            IActivityContainer container, TaskRecord inTask) {
3684
3685        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3686                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3687
3688        // TODO: Switch to user app stacks here.
3689        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3690                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3691                null, null, null, options, userId, container, inTask);
3692        return ret;
3693    }
3694
3695    @Override
3696    public final int startActivities(IApplicationThread caller, String callingPackage,
3697            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3698            int userId) {
3699        enforceNotIsolatedCaller("startActivities");
3700        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3701                false, ALLOW_FULL_ONLY, "startActivity", null);
3702        // TODO: Switch to user app stacks here.
3703        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3704                resolvedTypes, resultTo, options, userId);
3705        return ret;
3706    }
3707
3708    final int startActivitiesInPackage(int uid, String callingPackage,
3709            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3710            Bundle options, int userId) {
3711
3712        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3713                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3714        // TODO: Switch to user app stacks here.
3715        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3716                resultTo, options, userId);
3717        return ret;
3718    }
3719
3720    //explicitly remove thd old information in mRecentTasks when removing existing user.
3721    private void removeRecentTasksForUserLocked(int userId) {
3722        if(userId <= 0) {
3723            Slog.i(TAG, "Can't remove recent task on user " + userId);
3724            return;
3725        }
3726
3727        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3728            TaskRecord tr = mRecentTasks.get(i);
3729            if (tr.userId == userId) {
3730                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3731                        + " when finishing user" + userId);
3732                mRecentTasks.remove(i);
3733                tr.removedFromRecents(mTaskPersister);
3734            }
3735        }
3736
3737        // Remove tasks from persistent storage.
3738        mTaskPersister.wakeup(null, true);
3739    }
3740
3741    // Sort by taskId
3742    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3743        @Override
3744        public int compare(TaskRecord lhs, TaskRecord rhs) {
3745            return rhs.taskId - lhs.taskId;
3746        }
3747    };
3748
3749    // Extract the affiliates of the chain containing mRecentTasks[start].
3750    private int processNextAffiliateChain(int start) {
3751        final TaskRecord startTask = mRecentTasks.get(start);
3752        final int affiliateId = startTask.mAffiliatedTaskId;
3753
3754        // Quick identification of isolated tasks. I.e. those not launched behind.
3755        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3756                startTask.mNextAffiliate == null) {
3757            // There is still a slim chance that there are other tasks that point to this task
3758            // and that the chain is so messed up that this task no longer points to them but
3759            // the gain of this optimization outweighs the risk.
3760            startTask.inRecents = true;
3761            return start + 1;
3762        }
3763
3764        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3765        mTmpRecents.clear();
3766        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3767            final TaskRecord task = mRecentTasks.get(i);
3768            if (task.mAffiliatedTaskId == affiliateId) {
3769                mRecentTasks.remove(i);
3770                mTmpRecents.add(task);
3771            }
3772        }
3773
3774        // Sort them all by taskId. That is the order they were create in and that order will
3775        // always be correct.
3776        Collections.sort(mTmpRecents, mTaskRecordComparator);
3777
3778        // Go through and fix up the linked list.
3779        // The first one is the end of the chain and has no next.
3780        final TaskRecord first = mTmpRecents.get(0);
3781        first.inRecents = true;
3782        if (first.mNextAffiliate != null) {
3783            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3784            first.setNextAffiliate(null);
3785            mTaskPersister.wakeup(first, false);
3786        }
3787        // Everything in the middle is doubly linked from next to prev.
3788        final int tmpSize = mTmpRecents.size();
3789        for (int i = 0; i < tmpSize - 1; ++i) {
3790            final TaskRecord next = mTmpRecents.get(i);
3791            final TaskRecord prev = mTmpRecents.get(i + 1);
3792            if (next.mPrevAffiliate != prev) {
3793                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3794                        " setting prev=" + prev);
3795                next.setPrevAffiliate(prev);
3796                mTaskPersister.wakeup(next, false);
3797            }
3798            if (prev.mNextAffiliate != next) {
3799                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3800                        " setting next=" + next);
3801                prev.setNextAffiliate(next);
3802                mTaskPersister.wakeup(prev, false);
3803            }
3804            prev.inRecents = true;
3805        }
3806        // The last one is the beginning of the list and has no prev.
3807        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3808        if (last.mPrevAffiliate != null) {
3809            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3810            last.setPrevAffiliate(null);
3811            mTaskPersister.wakeup(last, false);
3812        }
3813
3814        // Insert the group back into mRecentTasks at start.
3815        mRecentTasks.addAll(start, mTmpRecents);
3816
3817        // Let the caller know where we left off.
3818        return start + tmpSize;
3819    }
3820
3821    /**
3822     * Update the recent tasks lists: make sure tasks should still be here (their
3823     * applications / activities still exist), update their availability, fixup ordering
3824     * of affiliations.
3825     */
3826    void cleanupRecentTasksLocked(int userId) {
3827        if (mRecentTasks == null) {
3828            // Happens when called from the packagemanager broadcast before boot.
3829            return;
3830        }
3831
3832        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3833        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3834        final IPackageManager pm = AppGlobals.getPackageManager();
3835        final ActivityInfo dummyAct = new ActivityInfo();
3836        final ApplicationInfo dummyApp = new ApplicationInfo();
3837
3838        int N = mRecentTasks.size();
3839
3840        int[] users = userId == UserHandle.USER_ALL
3841                ? getUsersLocked() : new int[] { userId };
3842        for (int user : users) {
3843            for (int i = 0; i < N; i++) {
3844                TaskRecord task = mRecentTasks.get(i);
3845                if (task.userId != user) {
3846                    // Only look at tasks for the user ID of interest.
3847                    continue;
3848                }
3849                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3850                    // This situation is broken, and we should just get rid of it now.
3851                    mRecentTasks.remove(i);
3852                    task.removedFromRecents(mTaskPersister);
3853                    i--;
3854                    N--;
3855                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3856                    continue;
3857                }
3858                // Check whether this activity is currently available.
3859                if (task.realActivity != null) {
3860                    ActivityInfo ai = availActCache.get(task.realActivity);
3861                    if (ai == null) {
3862                        try {
3863                            ai = pm.getActivityInfo(task.realActivity,
3864                                    PackageManager.GET_UNINSTALLED_PACKAGES
3865                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3866                        } catch (RemoteException e) {
3867                            // Will never happen.
3868                            continue;
3869                        }
3870                        if (ai == null) {
3871                            ai = dummyAct;
3872                        }
3873                        availActCache.put(task.realActivity, ai);
3874                    }
3875                    if (ai == dummyAct) {
3876                        // This could be either because the activity no longer exists, or the
3877                        // app is temporarily gone.  For the former we want to remove the recents
3878                        // entry; for the latter we want to mark it as unavailable.
3879                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3880                        if (app == null) {
3881                            try {
3882                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3883                                        PackageManager.GET_UNINSTALLED_PACKAGES
3884                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3885                            } catch (RemoteException e) {
3886                                // Will never happen.
3887                                continue;
3888                            }
3889                            if (app == null) {
3890                                app = dummyApp;
3891                            }
3892                            availAppCache.put(task.realActivity.getPackageName(), app);
3893                        }
3894                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3895                            // Doesn't exist any more!  Good-bye.
3896                            mRecentTasks.remove(i);
3897                            task.removedFromRecents(mTaskPersister);
3898                            i--;
3899                            N--;
3900                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3901                            continue;
3902                        } else {
3903                            // Otherwise just not available for now.
3904                            if (task.isAvailable) {
3905                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3906                                        + task);
3907                            }
3908                            task.isAvailable = false;
3909                        }
3910                    } else {
3911                        if (!ai.enabled || !ai.applicationInfo.enabled
3912                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3913                            if (task.isAvailable) {
3914                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3915                                        + task + " (enabled=" + ai.enabled + "/"
3916                                        + ai.applicationInfo.enabled +  " flags="
3917                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3918                            }
3919                            task.isAvailable = false;
3920                        } else {
3921                            if (!task.isAvailable) {
3922                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3923                                        + task);
3924                            }
3925                            task.isAvailable = true;
3926                        }
3927                    }
3928                }
3929            }
3930        }
3931
3932        // Verify the affiliate chain for each task.
3933        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3934        }
3935
3936        mTmpRecents.clear();
3937        // mRecentTasks is now in sorted, affiliated order.
3938    }
3939
3940    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3941        int N = mRecentTasks.size();
3942        TaskRecord top = task;
3943        int topIndex = taskIndex;
3944        while (top.mNextAffiliate != null && topIndex > 0) {
3945            top = top.mNextAffiliate;
3946            topIndex--;
3947        }
3948        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3949                + topIndex + " from intial " + taskIndex);
3950        // Find the end of the chain, doing a sanity check along the way.
3951        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3952        int endIndex = topIndex;
3953        TaskRecord prev = top;
3954        while (endIndex < N) {
3955            TaskRecord cur = mRecentTasks.get(endIndex);
3956            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3957                    + endIndex + " " + cur);
3958            if (cur == top) {
3959                // Verify start of the chain.
3960                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3961                    Slog.wtf(TAG, "Bad chain @" + endIndex
3962                            + ": first task has next affiliate: " + prev);
3963                    sane = false;
3964                    break;
3965                }
3966            } else {
3967                // Verify middle of the chain's next points back to the one before.
3968                if (cur.mNextAffiliate != prev
3969                        || cur.mNextAffiliateTaskId != prev.taskId) {
3970                    Slog.wtf(TAG, "Bad chain @" + endIndex
3971                            + ": middle task " + cur + " @" + endIndex
3972                            + " has bad next affiliate "
3973                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3974                            + ", expected " + prev);
3975                    sane = false;
3976                    break;
3977                }
3978            }
3979            if (cur.mPrevAffiliateTaskId == -1) {
3980                // Chain ends here.
3981                if (cur.mPrevAffiliate != null) {
3982                    Slog.wtf(TAG, "Bad chain @" + endIndex
3983                            + ": last task " + cur + " has previous affiliate "
3984                            + cur.mPrevAffiliate);
3985                    sane = false;
3986                }
3987                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3988                break;
3989            } else {
3990                // Verify middle of the chain's prev points to a valid item.
3991                if (cur.mPrevAffiliate == null) {
3992                    Slog.wtf(TAG, "Bad chain @" + endIndex
3993                            + ": task " + cur + " has previous affiliate "
3994                            + cur.mPrevAffiliate + " but should be id "
3995                            + cur.mPrevAffiliate);
3996                    sane = false;
3997                    break;
3998                }
3999            }
4000            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4001                Slog.wtf(TAG, "Bad chain @" + endIndex
4002                        + ": task " + cur + " has affiliated id "
4003                        + cur.mAffiliatedTaskId + " but should be "
4004                        + task.mAffiliatedTaskId);
4005                sane = false;
4006                break;
4007            }
4008            prev = cur;
4009            endIndex++;
4010            if (endIndex >= N) {
4011                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4012                        + ": last task " + prev);
4013                sane = false;
4014                break;
4015            }
4016        }
4017        if (sane) {
4018            if (endIndex < taskIndex) {
4019                Slog.wtf(TAG, "Bad chain @" + endIndex
4020                        + ": did not extend to task " + task + " @" + taskIndex);
4021                sane = false;
4022            }
4023        }
4024        if (sane) {
4025            // All looks good, we can just move all of the affiliated tasks
4026            // to the top.
4027            for (int i=topIndex; i<=endIndex; i++) {
4028                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4029                        + " from " + i + " to " + (i-topIndex));
4030                TaskRecord cur = mRecentTasks.remove(i);
4031                mRecentTasks.add(i-topIndex, cur);
4032            }
4033            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4034                    + " to " + endIndex);
4035            return true;
4036        }
4037
4038        // Whoops, couldn't do it.
4039        return false;
4040    }
4041
4042    final void addRecentTaskLocked(TaskRecord task) {
4043        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4044                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4045
4046        int N = mRecentTasks.size();
4047        // Quick case: check if the top-most recent task is the same.
4048        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4049            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4050            return;
4051        }
4052        // Another quick case: check if this is part of a set of affiliated
4053        // tasks that are at the top.
4054        if (isAffiliated && N > 0 && task.inRecents
4055                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4056            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4057                    + " at top when adding " + task);
4058            return;
4059        }
4060        // Another quick case: never add voice sessions.
4061        if (task.voiceSession != null) {
4062            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4063            return;
4064        }
4065
4066        boolean needAffiliationFix = false;
4067
4068        // Slightly less quick case: the task is already in recents, so all we need
4069        // to do is move it.
4070        if (task.inRecents) {
4071            int taskIndex = mRecentTasks.indexOf(task);
4072            if (taskIndex >= 0) {
4073                if (!isAffiliated) {
4074                    // Simple case: this is not an affiliated task, so we just move it to the front.
4075                    mRecentTasks.remove(taskIndex);
4076                    mRecentTasks.add(0, task);
4077                    notifyTaskPersisterLocked(task, false);
4078                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4079                            + " from " + taskIndex);
4080                    return;
4081                } else {
4082                    // More complicated: need to keep all affiliated tasks together.
4083                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4084                        // All went well.
4085                        return;
4086                    }
4087
4088                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4089                    // everything and then go through our general path of adding a new task.
4090                    needAffiliationFix = true;
4091                }
4092            } else {
4093                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4094                needAffiliationFix = true;
4095            }
4096        }
4097
4098        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4099        trimRecentsForTask(task, true);
4100
4101        N = mRecentTasks.size();
4102        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4103            final TaskRecord tr = mRecentTasks.remove(N - 1);
4104            tr.removedFromRecents(mTaskPersister);
4105            N--;
4106        }
4107        task.inRecents = true;
4108        if (!isAffiliated || needAffiliationFix) {
4109            // If this is a simple non-affiliated task, or we had some failure trying to
4110            // handle it as part of an affilated task, then just place it at the top.
4111            mRecentTasks.add(0, task);
4112        } else if (isAffiliated) {
4113            // If this is a new affiliated task, then move all of the affiliated tasks
4114            // to the front and insert this new one.
4115            TaskRecord other = task.mNextAffiliate;
4116            if (other == null) {
4117                other = task.mPrevAffiliate;
4118            }
4119            if (other != null) {
4120                int otherIndex = mRecentTasks.indexOf(other);
4121                if (otherIndex >= 0) {
4122                    // Insert new task at appropriate location.
4123                    int taskIndex;
4124                    if (other == task.mNextAffiliate) {
4125                        // We found the index of our next affiliation, which is who is
4126                        // before us in the list, so add after that point.
4127                        taskIndex = otherIndex+1;
4128                    } else {
4129                        // We found the index of our previous affiliation, which is who is
4130                        // after us in the list, so add at their position.
4131                        taskIndex = otherIndex;
4132                    }
4133                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4134                            + taskIndex + ": " + task);
4135                    mRecentTasks.add(taskIndex, task);
4136
4137                    // Now move everything to the front.
4138                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4139                        // All went well.
4140                        return;
4141                    }
4142
4143                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4144                    // everything and then go through our general path of adding a new task.
4145                    needAffiliationFix = true;
4146                } else {
4147                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4148                            + other);
4149                    needAffiliationFix = true;
4150                }
4151            } else {
4152                if (DEBUG_RECENTS) Slog.d(TAG,
4153                        "addRecent: adding affiliated task without next/prev:" + task);
4154                needAffiliationFix = true;
4155            }
4156        }
4157        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4158
4159        if (needAffiliationFix) {
4160            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4161            cleanupRecentTasksLocked(task.userId);
4162        }
4163    }
4164
4165    /**
4166     * If needed, remove oldest existing entries in recents that are for the same kind
4167     * of task as the given one.
4168     */
4169    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4170        int N = mRecentTasks.size();
4171        final Intent intent = task.intent;
4172        final boolean document = intent != null && intent.isDocument();
4173
4174        int maxRecents = task.maxRecents - 1;
4175        for (int i=0; i<N; i++) {
4176            final TaskRecord tr = mRecentTasks.get(i);
4177            if (task != tr) {
4178                if (task.userId != tr.userId) {
4179                    continue;
4180                }
4181                if (i > MAX_RECENT_BITMAPS) {
4182                    tr.freeLastThumbnail();
4183                }
4184                final Intent trIntent = tr.intent;
4185                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4186                    (intent == null || !intent.filterEquals(trIntent))) {
4187                    continue;
4188                }
4189                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4190                if (document && trIsDocument) {
4191                    // These are the same document activity (not necessarily the same doc).
4192                    if (maxRecents > 0) {
4193                        --maxRecents;
4194                        continue;
4195                    }
4196                    // Hit the maximum number of documents for this task. Fall through
4197                    // and remove this document from recents.
4198                } else if (document || trIsDocument) {
4199                    // Only one of these is a document. Not the droid we're looking for.
4200                    continue;
4201                }
4202            }
4203
4204            if (!doTrim) {
4205                // If the caller is not actually asking for a trim, just tell them we reached
4206                // a point where the trim would happen.
4207                return i;
4208            }
4209
4210            // Either task and tr are the same or, their affinities match or their intents match
4211            // and neither of them is a document, or they are documents using the same activity
4212            // and their maxRecents has been reached.
4213            tr.disposeThumbnail();
4214            mRecentTasks.remove(i);
4215            if (task != tr) {
4216                tr.removedFromRecents(mTaskPersister);
4217            }
4218            i--;
4219            N--;
4220            if (task.intent == null) {
4221                // If the new recent task we are adding is not fully
4222                // specified, then replace it with the existing recent task.
4223                task = tr;
4224            }
4225            notifyTaskPersisterLocked(tr, false);
4226        }
4227
4228        return -1;
4229    }
4230
4231    @Override
4232    public void reportActivityFullyDrawn(IBinder token) {
4233        synchronized (this) {
4234            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4235            if (r == null) {
4236                return;
4237            }
4238            r.reportFullyDrawnLocked();
4239        }
4240    }
4241
4242    @Override
4243    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4244        synchronized (this) {
4245            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4246            if (r == null) {
4247                return;
4248            }
4249            final long origId = Binder.clearCallingIdentity();
4250            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4251            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4252                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4253            if (config != null) {
4254                r.frozenBeforeDestroy = true;
4255                if (!updateConfigurationLocked(config, r, false, false)) {
4256                    mStackSupervisor.resumeTopActivitiesLocked();
4257                }
4258            }
4259            Binder.restoreCallingIdentity(origId);
4260        }
4261    }
4262
4263    @Override
4264    public int getRequestedOrientation(IBinder token) {
4265        synchronized (this) {
4266            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4267            if (r == null) {
4268                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4269            }
4270            return mWindowManager.getAppOrientation(r.appToken);
4271        }
4272    }
4273
4274    /**
4275     * This is the internal entry point for handling Activity.finish().
4276     *
4277     * @param token The Binder token referencing the Activity we want to finish.
4278     * @param resultCode Result code, if any, from this Activity.
4279     * @param resultData Result data (Intent), if any, from this Activity.
4280     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4281     *            the root Activity in the task.
4282     *
4283     * @return Returns true if the activity successfully finished, or false if it is still running.
4284     */
4285    @Override
4286    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4287            boolean finishTask) {
4288        // Refuse possible leaked file descriptors
4289        if (resultData != null && resultData.hasFileDescriptors() == true) {
4290            throw new IllegalArgumentException("File descriptors passed in Intent");
4291        }
4292
4293        synchronized(this) {
4294            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4295            if (r == null) {
4296                return true;
4297            }
4298            // Keep track of the root activity of the task before we finish it
4299            TaskRecord tr = r.task;
4300            ActivityRecord rootR = tr.getRootActivity();
4301            if (rootR == null) {
4302                Slog.w(TAG, "Finishing task with all activities already finished");
4303            }
4304            // Do not allow task to finish in Lock Task mode.
4305            if (tr == mStackSupervisor.mLockTaskModeTask) {
4306                if (rootR == r) {
4307                    Slog.i(TAG, "Not finishing task in lock task mode");
4308                    mStackSupervisor.showLockTaskToast();
4309                    return false;
4310                }
4311            }
4312            if (mController != null) {
4313                // Find the first activity that is not finishing.
4314                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4315                if (next != null) {
4316                    // ask watcher if this is allowed
4317                    boolean resumeOK = true;
4318                    try {
4319                        resumeOK = mController.activityResuming(next.packageName);
4320                    } catch (RemoteException e) {
4321                        mController = null;
4322                        Watchdog.getInstance().setActivityController(null);
4323                    }
4324
4325                    if (!resumeOK) {
4326                        Slog.i(TAG, "Not finishing activity because controller resumed");
4327                        return false;
4328                    }
4329                }
4330            }
4331            final long origId = Binder.clearCallingIdentity();
4332            try {
4333                boolean res;
4334                if (finishTask && r == rootR) {
4335                    // If requested, remove the task that is associated to this activity only if it
4336                    // was the root activity in the task. The result code and data is ignored
4337                    // because we don't support returning them across task boundaries.
4338                    res = removeTaskByIdLocked(tr.taskId, false);
4339                    if (!res) {
4340                        Slog.i(TAG, "Removing task failed to finish activity");
4341                    }
4342                } else {
4343                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4344                            resultData, "app-request", true);
4345                    if (!res) {
4346                        Slog.i(TAG, "Failed to finish by app-request");
4347                    }
4348                }
4349                return res;
4350            } finally {
4351                Binder.restoreCallingIdentity(origId);
4352            }
4353        }
4354    }
4355
4356    @Override
4357    public final void finishHeavyWeightApp() {
4358        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4359                != PackageManager.PERMISSION_GRANTED) {
4360            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4361                    + Binder.getCallingPid()
4362                    + ", uid=" + Binder.getCallingUid()
4363                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4364            Slog.w(TAG, msg);
4365            throw new SecurityException(msg);
4366        }
4367
4368        synchronized(this) {
4369            if (mHeavyWeightProcess == null) {
4370                return;
4371            }
4372
4373            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4374                    mHeavyWeightProcess.activities);
4375            for (int i=0; i<activities.size(); i++) {
4376                ActivityRecord r = activities.get(i);
4377                if (!r.finishing) {
4378                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4379                            null, "finish-heavy", true);
4380                }
4381            }
4382
4383            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4384                    mHeavyWeightProcess.userId, 0));
4385            mHeavyWeightProcess = null;
4386        }
4387    }
4388
4389    @Override
4390    public void crashApplication(int uid, int initialPid, String packageName,
4391            String message) {
4392        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4393                != PackageManager.PERMISSION_GRANTED) {
4394            String msg = "Permission Denial: crashApplication() from pid="
4395                    + Binder.getCallingPid()
4396                    + ", uid=" + Binder.getCallingUid()
4397                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4398            Slog.w(TAG, msg);
4399            throw new SecurityException(msg);
4400        }
4401
4402        synchronized(this) {
4403            ProcessRecord proc = null;
4404
4405            // Figure out which process to kill.  We don't trust that initialPid
4406            // still has any relation to current pids, so must scan through the
4407            // list.
4408            synchronized (mPidsSelfLocked) {
4409                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4410                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4411                    if (p.uid != uid) {
4412                        continue;
4413                    }
4414                    if (p.pid == initialPid) {
4415                        proc = p;
4416                        break;
4417                    }
4418                    if (p.pkgList.containsKey(packageName)) {
4419                        proc = p;
4420                    }
4421                }
4422            }
4423
4424            if (proc == null) {
4425                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4426                        + " initialPid=" + initialPid
4427                        + " packageName=" + packageName);
4428                return;
4429            }
4430
4431            if (proc.thread != null) {
4432                if (proc.pid == Process.myPid()) {
4433                    Log.w(TAG, "crashApplication: trying to crash self!");
4434                    return;
4435                }
4436                long ident = Binder.clearCallingIdentity();
4437                try {
4438                    proc.thread.scheduleCrash(message);
4439                } catch (RemoteException e) {
4440                }
4441                Binder.restoreCallingIdentity(ident);
4442            }
4443        }
4444    }
4445
4446    @Override
4447    public final void finishSubActivity(IBinder token, String resultWho,
4448            int requestCode) {
4449        synchronized(this) {
4450            final long origId = Binder.clearCallingIdentity();
4451            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4452            if (r != null) {
4453                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4454            }
4455            Binder.restoreCallingIdentity(origId);
4456        }
4457    }
4458
4459    @Override
4460    public boolean finishActivityAffinity(IBinder token) {
4461        synchronized(this) {
4462            final long origId = Binder.clearCallingIdentity();
4463            try {
4464                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4465
4466                ActivityRecord rootR = r.task.getRootActivity();
4467                // Do not allow task to finish in Lock Task mode.
4468                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4469                    if (rootR == r) {
4470                        mStackSupervisor.showLockTaskToast();
4471                        return false;
4472                    }
4473                }
4474                boolean res = false;
4475                if (r != null) {
4476                    res = r.task.stack.finishActivityAffinityLocked(r);
4477                }
4478                return res;
4479            } finally {
4480                Binder.restoreCallingIdentity(origId);
4481            }
4482        }
4483    }
4484
4485    @Override
4486    public void finishVoiceTask(IVoiceInteractionSession session) {
4487        synchronized(this) {
4488            final long origId = Binder.clearCallingIdentity();
4489            try {
4490                mStackSupervisor.finishVoiceTask(session);
4491            } finally {
4492                Binder.restoreCallingIdentity(origId);
4493            }
4494        }
4495
4496    }
4497
4498    @Override
4499    public boolean releaseActivityInstance(IBinder token) {
4500        synchronized(this) {
4501            final long origId = Binder.clearCallingIdentity();
4502            try {
4503                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4504                if (r.task == null || r.task.stack == null) {
4505                    return false;
4506                }
4507                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4508            } finally {
4509                Binder.restoreCallingIdentity(origId);
4510            }
4511        }
4512    }
4513
4514    @Override
4515    public void releaseSomeActivities(IApplicationThread appInt) {
4516        synchronized(this) {
4517            final long origId = Binder.clearCallingIdentity();
4518            try {
4519                ProcessRecord app = getRecordForAppLocked(appInt);
4520                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4521            } finally {
4522                Binder.restoreCallingIdentity(origId);
4523            }
4524        }
4525    }
4526
4527    @Override
4528    public boolean willActivityBeVisible(IBinder token) {
4529        synchronized(this) {
4530            ActivityStack stack = ActivityRecord.getStackLocked(token);
4531            if (stack != null) {
4532                return stack.willActivityBeVisibleLocked(token);
4533            }
4534            return false;
4535        }
4536    }
4537
4538    @Override
4539    public void overridePendingTransition(IBinder token, String packageName,
4540            int enterAnim, int exitAnim) {
4541        synchronized(this) {
4542            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4543            if (self == null) {
4544                return;
4545            }
4546
4547            final long origId = Binder.clearCallingIdentity();
4548
4549            if (self.state == ActivityState.RESUMED
4550                    || self.state == ActivityState.PAUSING) {
4551                mWindowManager.overridePendingAppTransition(packageName,
4552                        enterAnim, exitAnim, null);
4553            }
4554
4555            Binder.restoreCallingIdentity(origId);
4556        }
4557    }
4558
4559    /**
4560     * Main function for removing an existing process from the activity manager
4561     * as a result of that process going away.  Clears out all connections
4562     * to the process.
4563     */
4564    private final void handleAppDiedLocked(ProcessRecord app,
4565            boolean restarting, boolean allowRestart) {
4566        int pid = app.pid;
4567        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4568        if (!kept && !restarting) {
4569            removeLruProcessLocked(app);
4570            if (pid > 0) {
4571                ProcessList.remove(pid);
4572            }
4573        }
4574
4575        if (mProfileProc == app) {
4576            clearProfilerLocked();
4577        }
4578
4579        // Remove this application's activities from active lists.
4580        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4581
4582        app.activities.clear();
4583
4584        if (app.instrumentationClass != null) {
4585            Slog.w(TAG, "Crash of app " + app.processName
4586                  + " running instrumentation " + app.instrumentationClass);
4587            Bundle info = new Bundle();
4588            info.putString("shortMsg", "Process crashed.");
4589            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4590        }
4591
4592        if (!restarting) {
4593            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4594                // If there was nothing to resume, and we are not already
4595                // restarting this process, but there is a visible activity that
4596                // is hosted by the process...  then make sure all visible
4597                // activities are running, taking care of restarting this
4598                // process.
4599                if (hasVisibleActivities) {
4600                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4601                }
4602            }
4603        }
4604    }
4605
4606    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4607        IBinder threadBinder = thread.asBinder();
4608        // Find the application record.
4609        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4610            ProcessRecord rec = mLruProcesses.get(i);
4611            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4612                return i;
4613            }
4614        }
4615        return -1;
4616    }
4617
4618    final ProcessRecord getRecordForAppLocked(
4619            IApplicationThread thread) {
4620        if (thread == null) {
4621            return null;
4622        }
4623
4624        int appIndex = getLRURecordIndexForAppLocked(thread);
4625        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4626    }
4627
4628    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4629        // If there are no longer any background processes running,
4630        // and the app that died was not running instrumentation,
4631        // then tell everyone we are now low on memory.
4632        boolean haveBg = false;
4633        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4634            ProcessRecord rec = mLruProcesses.get(i);
4635            if (rec.thread != null
4636                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4637                haveBg = true;
4638                break;
4639            }
4640        }
4641
4642        if (!haveBg) {
4643            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4644            if (doReport) {
4645                long now = SystemClock.uptimeMillis();
4646                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4647                    doReport = false;
4648                } else {
4649                    mLastMemUsageReportTime = now;
4650                }
4651            }
4652            final ArrayList<ProcessMemInfo> memInfos
4653                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4654            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4655            long now = SystemClock.uptimeMillis();
4656            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4657                ProcessRecord rec = mLruProcesses.get(i);
4658                if (rec == dyingProc || rec.thread == null) {
4659                    continue;
4660                }
4661                if (doReport) {
4662                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4663                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4664                }
4665                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4666                    // The low memory report is overriding any current
4667                    // state for a GC request.  Make sure to do
4668                    // heavy/important/visible/foreground processes first.
4669                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4670                        rec.lastRequestedGc = 0;
4671                    } else {
4672                        rec.lastRequestedGc = rec.lastLowMemory;
4673                    }
4674                    rec.reportLowMemory = true;
4675                    rec.lastLowMemory = now;
4676                    mProcessesToGc.remove(rec);
4677                    addProcessToGcListLocked(rec);
4678                }
4679            }
4680            if (doReport) {
4681                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4682                mHandler.sendMessage(msg);
4683            }
4684            scheduleAppGcsLocked();
4685        }
4686    }
4687
4688    final void appDiedLocked(ProcessRecord app) {
4689       appDiedLocked(app, app.pid, app.thread);
4690    }
4691
4692    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4693        // First check if this ProcessRecord is actually active for the pid.
4694        synchronized (mPidsSelfLocked) {
4695            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4696            if (curProc != app) {
4697                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4698                return;
4699            }
4700        }
4701
4702        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4703        synchronized (stats) {
4704            stats.noteProcessDiedLocked(app.info.uid, pid);
4705        }
4706
4707        Process.killProcessQuiet(pid);
4708        Process.killProcessGroup(app.info.uid, pid);
4709        app.killed = true;
4710
4711        // Clean up already done if the process has been re-started.
4712        if (app.pid == pid && app.thread != null &&
4713                app.thread.asBinder() == thread.asBinder()) {
4714            boolean doLowMem = app.instrumentationClass == null;
4715            boolean doOomAdj = doLowMem;
4716            if (!app.killedByAm) {
4717                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4718                        + ") has died");
4719                mAllowLowerMemLevel = true;
4720            } else {
4721                // Note that we always want to do oom adj to update our state with the
4722                // new number of procs.
4723                mAllowLowerMemLevel = false;
4724                doLowMem = false;
4725            }
4726            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4727            if (DEBUG_CLEANUP) Slog.v(
4728                TAG, "Dying app: " + app + ", pid: " + pid
4729                + ", thread: " + thread.asBinder());
4730            handleAppDiedLocked(app, false, true);
4731
4732            if (doOomAdj) {
4733                updateOomAdjLocked();
4734            }
4735            if (doLowMem) {
4736                doLowMemReportIfNeededLocked(app);
4737            }
4738        } else if (app.pid != pid) {
4739            // A new process has already been started.
4740            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4741                    + ") has died and restarted (pid " + app.pid + ").");
4742            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4743        } else if (DEBUG_PROCESSES) {
4744            Slog.d(TAG, "Received spurious death notification for thread "
4745                    + thread.asBinder());
4746        }
4747    }
4748
4749    /**
4750     * If a stack trace dump file is configured, dump process stack traces.
4751     * @param clearTraces causes the dump file to be erased prior to the new
4752     *    traces being written, if true; when false, the new traces will be
4753     *    appended to any existing file content.
4754     * @param firstPids of dalvik VM processes to dump stack traces for first
4755     * @param lastPids of dalvik VM processes to dump stack traces for last
4756     * @param nativeProcs optional list of native process names to dump stack crawls
4757     * @return file containing stack traces, or null if no dump file is configured
4758     */
4759    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4760            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4761        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4762        if (tracesPath == null || tracesPath.length() == 0) {
4763            return null;
4764        }
4765
4766        File tracesFile = new File(tracesPath);
4767        try {
4768            File tracesDir = tracesFile.getParentFile();
4769            if (!tracesDir.exists()) {
4770                tracesDir.mkdirs();
4771                if (!SELinux.restorecon(tracesDir)) {
4772                    return null;
4773                }
4774            }
4775            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4776
4777            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4778            tracesFile.createNewFile();
4779            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4780        } catch (IOException e) {
4781            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4782            return null;
4783        }
4784
4785        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4786        return tracesFile;
4787    }
4788
4789    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4790            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4791        // Use a FileObserver to detect when traces finish writing.
4792        // The order of traces is considered important to maintain for legibility.
4793        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4794            @Override
4795            public synchronized void onEvent(int event, String path) { notify(); }
4796        };
4797
4798        try {
4799            observer.startWatching();
4800
4801            // First collect all of the stacks of the most important pids.
4802            if (firstPids != null) {
4803                try {
4804                    int num = firstPids.size();
4805                    for (int i = 0; i < num; i++) {
4806                        synchronized (observer) {
4807                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4808                            observer.wait(200);  // Wait for write-close, give up after 200msec
4809                        }
4810                    }
4811                } catch (InterruptedException e) {
4812                    Slog.wtf(TAG, e);
4813                }
4814            }
4815
4816            // Next collect the stacks of the native pids
4817            if (nativeProcs != null) {
4818                int[] pids = Process.getPidsForCommands(nativeProcs);
4819                if (pids != null) {
4820                    for (int pid : pids) {
4821                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4822                    }
4823                }
4824            }
4825
4826            // Lastly, measure CPU usage.
4827            if (processCpuTracker != null) {
4828                processCpuTracker.init();
4829                System.gc();
4830                processCpuTracker.update();
4831                try {
4832                    synchronized (processCpuTracker) {
4833                        processCpuTracker.wait(500); // measure over 1/2 second.
4834                    }
4835                } catch (InterruptedException e) {
4836                }
4837                processCpuTracker.update();
4838
4839                // We'll take the stack crawls of just the top apps using CPU.
4840                final int N = processCpuTracker.countWorkingStats();
4841                int numProcs = 0;
4842                for (int i=0; i<N && numProcs<5; i++) {
4843                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4844                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4845                        numProcs++;
4846                        try {
4847                            synchronized (observer) {
4848                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4849                                observer.wait(200);  // Wait for write-close, give up after 200msec
4850                            }
4851                        } catch (InterruptedException e) {
4852                            Slog.wtf(TAG, e);
4853                        }
4854
4855                    }
4856                }
4857            }
4858        } finally {
4859            observer.stopWatching();
4860        }
4861    }
4862
4863    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4864        if (true || IS_USER_BUILD) {
4865            return;
4866        }
4867        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4868        if (tracesPath == null || tracesPath.length() == 0) {
4869            return;
4870        }
4871
4872        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4873        StrictMode.allowThreadDiskWrites();
4874        try {
4875            final File tracesFile = new File(tracesPath);
4876            final File tracesDir = tracesFile.getParentFile();
4877            final File tracesTmp = new File(tracesDir, "__tmp__");
4878            try {
4879                if (!tracesDir.exists()) {
4880                    tracesDir.mkdirs();
4881                    if (!SELinux.restorecon(tracesDir.getPath())) {
4882                        return;
4883                    }
4884                }
4885                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4886
4887                if (tracesFile.exists()) {
4888                    tracesTmp.delete();
4889                    tracesFile.renameTo(tracesTmp);
4890                }
4891                StringBuilder sb = new StringBuilder();
4892                Time tobj = new Time();
4893                tobj.set(System.currentTimeMillis());
4894                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4895                sb.append(": ");
4896                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4897                sb.append(" since ");
4898                sb.append(msg);
4899                FileOutputStream fos = new FileOutputStream(tracesFile);
4900                fos.write(sb.toString().getBytes());
4901                if (app == null) {
4902                    fos.write("\n*** No application process!".getBytes());
4903                }
4904                fos.close();
4905                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4906            } catch (IOException e) {
4907                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4908                return;
4909            }
4910
4911            if (app != null) {
4912                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4913                firstPids.add(app.pid);
4914                dumpStackTraces(tracesPath, firstPids, null, null, null);
4915            }
4916
4917            File lastTracesFile = null;
4918            File curTracesFile = null;
4919            for (int i=9; i>=0; i--) {
4920                String name = String.format(Locale.US, "slow%02d.txt", i);
4921                curTracesFile = new File(tracesDir, name);
4922                if (curTracesFile.exists()) {
4923                    if (lastTracesFile != null) {
4924                        curTracesFile.renameTo(lastTracesFile);
4925                    } else {
4926                        curTracesFile.delete();
4927                    }
4928                }
4929                lastTracesFile = curTracesFile;
4930            }
4931            tracesFile.renameTo(curTracesFile);
4932            if (tracesTmp.exists()) {
4933                tracesTmp.renameTo(tracesFile);
4934            }
4935        } finally {
4936            StrictMode.setThreadPolicy(oldPolicy);
4937        }
4938    }
4939
4940    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4941            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4942        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4943        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4944
4945        if (mController != null) {
4946            try {
4947                // 0 == continue, -1 = kill process immediately
4948                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4949                if (res < 0 && app.pid != MY_PID) {
4950                    app.kill("anr", true);
4951                }
4952            } catch (RemoteException e) {
4953                mController = null;
4954                Watchdog.getInstance().setActivityController(null);
4955            }
4956        }
4957
4958        long anrTime = SystemClock.uptimeMillis();
4959        if (MONITOR_CPU_USAGE) {
4960            updateCpuStatsNow();
4961        }
4962
4963        synchronized (this) {
4964            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4965            if (mShuttingDown) {
4966                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4967                return;
4968            } else if (app.notResponding) {
4969                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4970                return;
4971            } else if (app.crashing) {
4972                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4973                return;
4974            }
4975
4976            // In case we come through here for the same app before completing
4977            // this one, mark as anring now so we will bail out.
4978            app.notResponding = true;
4979
4980            // Log the ANR to the event log.
4981            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4982                    app.processName, app.info.flags, annotation);
4983
4984            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4985            firstPids.add(app.pid);
4986
4987            int parentPid = app.pid;
4988            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4989            if (parentPid != app.pid) firstPids.add(parentPid);
4990
4991            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4992
4993            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4994                ProcessRecord r = mLruProcesses.get(i);
4995                if (r != null && r.thread != null) {
4996                    int pid = r.pid;
4997                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4998                        if (r.persistent) {
4999                            firstPids.add(pid);
5000                        } else {
5001                            lastPids.put(pid, Boolean.TRUE);
5002                        }
5003                    }
5004                }
5005            }
5006        }
5007
5008        // Log the ANR to the main log.
5009        StringBuilder info = new StringBuilder();
5010        info.setLength(0);
5011        info.append("ANR in ").append(app.processName);
5012        if (activity != null && activity.shortComponentName != null) {
5013            info.append(" (").append(activity.shortComponentName).append(")");
5014        }
5015        info.append("\n");
5016        info.append("PID: ").append(app.pid).append("\n");
5017        if (annotation != null) {
5018            info.append("Reason: ").append(annotation).append("\n");
5019        }
5020        if (parent != null && parent != activity) {
5021            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5022        }
5023
5024        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5025
5026        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5027                NATIVE_STACKS_OF_INTEREST);
5028
5029        String cpuInfo = null;
5030        if (MONITOR_CPU_USAGE) {
5031            updateCpuStatsNow();
5032            synchronized (mProcessCpuTracker) {
5033                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5034            }
5035            info.append(processCpuTracker.printCurrentLoad());
5036            info.append(cpuInfo);
5037        }
5038
5039        info.append(processCpuTracker.printCurrentState(anrTime));
5040
5041        Slog.e(TAG, info.toString());
5042        if (tracesFile == null) {
5043            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5044            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5045        }
5046
5047        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5048                cpuInfo, tracesFile, null);
5049
5050        if (mController != null) {
5051            try {
5052                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5053                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5054                if (res != 0) {
5055                    if (res < 0 && app.pid != MY_PID) {
5056                        app.kill("anr", true);
5057                    } else {
5058                        synchronized (this) {
5059                            mServices.scheduleServiceTimeoutLocked(app);
5060                        }
5061                    }
5062                    return;
5063                }
5064            } catch (RemoteException e) {
5065                mController = null;
5066                Watchdog.getInstance().setActivityController(null);
5067            }
5068        }
5069
5070        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5071        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5072                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5073
5074        synchronized (this) {
5075            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5076                app.kill("bg anr", true);
5077                return;
5078            }
5079
5080            // Set the app's notResponding state, and look up the errorReportReceiver
5081            makeAppNotRespondingLocked(app,
5082                    activity != null ? activity.shortComponentName : null,
5083                    annotation != null ? "ANR " + annotation : "ANR",
5084                    info.toString());
5085
5086            // Bring up the infamous App Not Responding dialog
5087            Message msg = Message.obtain();
5088            HashMap<String, Object> map = new HashMap<String, Object>();
5089            msg.what = SHOW_NOT_RESPONDING_MSG;
5090            msg.obj = map;
5091            msg.arg1 = aboveSystem ? 1 : 0;
5092            map.put("app", app);
5093            if (activity != null) {
5094                map.put("activity", activity);
5095            }
5096
5097            mHandler.sendMessage(msg);
5098        }
5099    }
5100
5101    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5102        if (!mLaunchWarningShown) {
5103            mLaunchWarningShown = true;
5104            mHandler.post(new Runnable() {
5105                @Override
5106                public void run() {
5107                    synchronized (ActivityManagerService.this) {
5108                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5109                        d.show();
5110                        mHandler.postDelayed(new Runnable() {
5111                            @Override
5112                            public void run() {
5113                                synchronized (ActivityManagerService.this) {
5114                                    d.dismiss();
5115                                    mLaunchWarningShown = false;
5116                                }
5117                            }
5118                        }, 4000);
5119                    }
5120                }
5121            });
5122        }
5123    }
5124
5125    @Override
5126    public boolean clearApplicationUserData(final String packageName,
5127            final IPackageDataObserver observer, int userId) {
5128        enforceNotIsolatedCaller("clearApplicationUserData");
5129        int uid = Binder.getCallingUid();
5130        int pid = Binder.getCallingPid();
5131        userId = handleIncomingUser(pid, uid,
5132                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5133        long callingId = Binder.clearCallingIdentity();
5134        try {
5135            IPackageManager pm = AppGlobals.getPackageManager();
5136            int pkgUid = -1;
5137            synchronized(this) {
5138                try {
5139                    pkgUid = pm.getPackageUid(packageName, userId);
5140                } catch (RemoteException e) {
5141                }
5142                if (pkgUid == -1) {
5143                    Slog.w(TAG, "Invalid packageName: " + packageName);
5144                    if (observer != null) {
5145                        try {
5146                            observer.onRemoveCompleted(packageName, false);
5147                        } catch (RemoteException e) {
5148                            Slog.i(TAG, "Observer no longer exists.");
5149                        }
5150                    }
5151                    return false;
5152                }
5153                if (uid == pkgUid || checkComponentPermission(
5154                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5155                        pid, uid, -1, true)
5156                        == PackageManager.PERMISSION_GRANTED) {
5157                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5158                } else {
5159                    throw new SecurityException("PID " + pid + " does not have permission "
5160                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5161                                    + " of package " + packageName);
5162                }
5163
5164                // Remove all tasks match the cleared application package and user
5165                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5166                    final TaskRecord tr = mRecentTasks.get(i);
5167                    final String taskPackageName =
5168                            tr.getBaseIntent().getComponent().getPackageName();
5169                    if (tr.userId != userId) continue;
5170                    if (!taskPackageName.equals(packageName)) continue;
5171                    removeTaskByIdLocked(tr.taskId, false);
5172                }
5173            }
5174
5175            try {
5176                // Clear application user data
5177                pm.clearApplicationUserData(packageName, observer, userId);
5178
5179                synchronized(this) {
5180                    // Remove all permissions granted from/to this package
5181                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5182                }
5183
5184                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5185                        Uri.fromParts("package", packageName, null));
5186                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5187                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5188                        null, null, 0, null, null, null, false, false, userId);
5189            } catch (RemoteException e) {
5190            }
5191        } finally {
5192            Binder.restoreCallingIdentity(callingId);
5193        }
5194        return true;
5195    }
5196
5197    @Override
5198    public void killBackgroundProcesses(final String packageName, int userId) {
5199        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5200                != PackageManager.PERMISSION_GRANTED &&
5201                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5202                        != PackageManager.PERMISSION_GRANTED) {
5203            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5204                    + Binder.getCallingPid()
5205                    + ", uid=" + Binder.getCallingUid()
5206                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5207            Slog.w(TAG, msg);
5208            throw new SecurityException(msg);
5209        }
5210
5211        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5212                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5213        long callingId = Binder.clearCallingIdentity();
5214        try {
5215            IPackageManager pm = AppGlobals.getPackageManager();
5216            synchronized(this) {
5217                int appId = -1;
5218                try {
5219                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5220                } catch (RemoteException e) {
5221                }
5222                if (appId == -1) {
5223                    Slog.w(TAG, "Invalid packageName: " + packageName);
5224                    return;
5225                }
5226                killPackageProcessesLocked(packageName, appId, userId,
5227                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5228            }
5229        } finally {
5230            Binder.restoreCallingIdentity(callingId);
5231        }
5232    }
5233
5234    @Override
5235    public void killAllBackgroundProcesses() {
5236        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5237                != PackageManager.PERMISSION_GRANTED) {
5238            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5239                    + Binder.getCallingPid()
5240                    + ", uid=" + Binder.getCallingUid()
5241                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5242            Slog.w(TAG, msg);
5243            throw new SecurityException(msg);
5244        }
5245
5246        long callingId = Binder.clearCallingIdentity();
5247        try {
5248            synchronized(this) {
5249                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5250                final int NP = mProcessNames.getMap().size();
5251                for (int ip=0; ip<NP; ip++) {
5252                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5253                    final int NA = apps.size();
5254                    for (int ia=0; ia<NA; ia++) {
5255                        ProcessRecord app = apps.valueAt(ia);
5256                        if (app.persistent) {
5257                            // we don't kill persistent processes
5258                            continue;
5259                        }
5260                        if (app.removed) {
5261                            procs.add(app);
5262                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5263                            app.removed = true;
5264                            procs.add(app);
5265                        }
5266                    }
5267                }
5268
5269                int N = procs.size();
5270                for (int i=0; i<N; i++) {
5271                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5272                }
5273                mAllowLowerMemLevel = true;
5274                updateOomAdjLocked();
5275                doLowMemReportIfNeededLocked(null);
5276            }
5277        } finally {
5278            Binder.restoreCallingIdentity(callingId);
5279        }
5280    }
5281
5282    @Override
5283    public void forceStopPackage(final String packageName, int userId) {
5284        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5285                != PackageManager.PERMISSION_GRANTED) {
5286            String msg = "Permission Denial: forceStopPackage() from pid="
5287                    + Binder.getCallingPid()
5288                    + ", uid=" + Binder.getCallingUid()
5289                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5290            Slog.w(TAG, msg);
5291            throw new SecurityException(msg);
5292        }
5293        final int callingPid = Binder.getCallingPid();
5294        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5295                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5296        long callingId = Binder.clearCallingIdentity();
5297        try {
5298            IPackageManager pm = AppGlobals.getPackageManager();
5299            synchronized(this) {
5300                int[] users = userId == UserHandle.USER_ALL
5301                        ? getUsersLocked() : new int[] { userId };
5302                for (int user : users) {
5303                    int pkgUid = -1;
5304                    try {
5305                        pkgUid = pm.getPackageUid(packageName, user);
5306                    } catch (RemoteException e) {
5307                    }
5308                    if (pkgUid == -1) {
5309                        Slog.w(TAG, "Invalid packageName: " + packageName);
5310                        continue;
5311                    }
5312                    try {
5313                        pm.setPackageStoppedState(packageName, true, user);
5314                    } catch (RemoteException e) {
5315                    } catch (IllegalArgumentException e) {
5316                        Slog.w(TAG, "Failed trying to unstop package "
5317                                + packageName + ": " + e);
5318                    }
5319                    if (isUserRunningLocked(user, false)) {
5320                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5321                    }
5322                }
5323            }
5324        } finally {
5325            Binder.restoreCallingIdentity(callingId);
5326        }
5327    }
5328
5329    @Override
5330    public void addPackageDependency(String packageName) {
5331        synchronized (this) {
5332            int callingPid = Binder.getCallingPid();
5333            if (callingPid == Process.myPid()) {
5334                //  Yeah, um, no.
5335                Slog.w(TAG, "Can't addPackageDependency on system process");
5336                return;
5337            }
5338            ProcessRecord proc;
5339            synchronized (mPidsSelfLocked) {
5340                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5341            }
5342            if (proc != null) {
5343                if (proc.pkgDeps == null) {
5344                    proc.pkgDeps = new ArraySet<String>(1);
5345                }
5346                proc.pkgDeps.add(packageName);
5347            }
5348        }
5349    }
5350
5351    /*
5352     * The pkg name and app id have to be specified.
5353     */
5354    @Override
5355    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5356        if (pkg == null) {
5357            return;
5358        }
5359        // Make sure the uid is valid.
5360        if (appid < 0) {
5361            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5362            return;
5363        }
5364        int callerUid = Binder.getCallingUid();
5365        // Only the system server can kill an application
5366        if (callerUid == Process.SYSTEM_UID) {
5367            // Post an aysnc message to kill the application
5368            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5369            msg.arg1 = appid;
5370            msg.arg2 = 0;
5371            Bundle bundle = new Bundle();
5372            bundle.putString("pkg", pkg);
5373            bundle.putString("reason", reason);
5374            msg.obj = bundle;
5375            mHandler.sendMessage(msg);
5376        } else {
5377            throw new SecurityException(callerUid + " cannot kill pkg: " +
5378                    pkg);
5379        }
5380    }
5381
5382    @Override
5383    public void closeSystemDialogs(String reason) {
5384        enforceNotIsolatedCaller("closeSystemDialogs");
5385
5386        final int pid = Binder.getCallingPid();
5387        final int uid = Binder.getCallingUid();
5388        final long origId = Binder.clearCallingIdentity();
5389        try {
5390            synchronized (this) {
5391                // Only allow this from foreground processes, so that background
5392                // applications can't abuse it to prevent system UI from being shown.
5393                if (uid >= Process.FIRST_APPLICATION_UID) {
5394                    ProcessRecord proc;
5395                    synchronized (mPidsSelfLocked) {
5396                        proc = mPidsSelfLocked.get(pid);
5397                    }
5398                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5399                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5400                                + " from background process " + proc);
5401                        return;
5402                    }
5403                }
5404                closeSystemDialogsLocked(reason);
5405            }
5406        } finally {
5407            Binder.restoreCallingIdentity(origId);
5408        }
5409    }
5410
5411    void closeSystemDialogsLocked(String reason) {
5412        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5413        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5414                | Intent.FLAG_RECEIVER_FOREGROUND);
5415        if (reason != null) {
5416            intent.putExtra("reason", reason);
5417        }
5418        mWindowManager.closeSystemDialogs(reason);
5419
5420        mStackSupervisor.closeSystemDialogsLocked();
5421
5422        broadcastIntentLocked(null, null, intent, null,
5423                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5424                Process.SYSTEM_UID, UserHandle.USER_ALL);
5425    }
5426
5427    @Override
5428    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5429        enforceNotIsolatedCaller("getProcessMemoryInfo");
5430        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5431        for (int i=pids.length-1; i>=0; i--) {
5432            ProcessRecord proc;
5433            int oomAdj;
5434            synchronized (this) {
5435                synchronized (mPidsSelfLocked) {
5436                    proc = mPidsSelfLocked.get(pids[i]);
5437                    oomAdj = proc != null ? proc.setAdj : 0;
5438                }
5439            }
5440            infos[i] = new Debug.MemoryInfo();
5441            Debug.getMemoryInfo(pids[i], infos[i]);
5442            if (proc != null) {
5443                synchronized (this) {
5444                    if (proc.thread != null && proc.setAdj == oomAdj) {
5445                        // Record this for posterity if the process has been stable.
5446                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5447                                infos[i].getTotalUss(), false, proc.pkgList);
5448                    }
5449                }
5450            }
5451        }
5452        return infos;
5453    }
5454
5455    @Override
5456    public long[] getProcessPss(int[] pids) {
5457        enforceNotIsolatedCaller("getProcessPss");
5458        long[] pss = new long[pids.length];
5459        for (int i=pids.length-1; i>=0; i--) {
5460            ProcessRecord proc;
5461            int oomAdj;
5462            synchronized (this) {
5463                synchronized (mPidsSelfLocked) {
5464                    proc = mPidsSelfLocked.get(pids[i]);
5465                    oomAdj = proc != null ? proc.setAdj : 0;
5466                }
5467            }
5468            long[] tmpUss = new long[1];
5469            pss[i] = Debug.getPss(pids[i], tmpUss);
5470            if (proc != null) {
5471                synchronized (this) {
5472                    if (proc.thread != null && proc.setAdj == oomAdj) {
5473                        // Record this for posterity if the process has been stable.
5474                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5475                    }
5476                }
5477            }
5478        }
5479        return pss;
5480    }
5481
5482    @Override
5483    public void killApplicationProcess(String processName, int uid) {
5484        if (processName == null) {
5485            return;
5486        }
5487
5488        int callerUid = Binder.getCallingUid();
5489        // Only the system server can kill an application
5490        if (callerUid == Process.SYSTEM_UID) {
5491            synchronized (this) {
5492                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5493                if (app != null && app.thread != null) {
5494                    try {
5495                        app.thread.scheduleSuicide();
5496                    } catch (RemoteException e) {
5497                        // If the other end already died, then our work here is done.
5498                    }
5499                } else {
5500                    Slog.w(TAG, "Process/uid not found attempting kill of "
5501                            + processName + " / " + uid);
5502                }
5503            }
5504        } else {
5505            throw new SecurityException(callerUid + " cannot kill app process: " +
5506                    processName);
5507        }
5508    }
5509
5510    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5511        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5512                false, true, false, false, UserHandle.getUserId(uid), reason);
5513        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5514                Uri.fromParts("package", packageName, null));
5515        if (!mProcessesReady) {
5516            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5517                    | Intent.FLAG_RECEIVER_FOREGROUND);
5518        }
5519        intent.putExtra(Intent.EXTRA_UID, uid);
5520        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5521        broadcastIntentLocked(null, null, intent,
5522                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5523                false, false,
5524                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5525    }
5526
5527    private void forceStopUserLocked(int userId, String reason) {
5528        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5529        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5530        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5531                | Intent.FLAG_RECEIVER_FOREGROUND);
5532        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5533        broadcastIntentLocked(null, null, intent,
5534                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5535                false, false,
5536                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5537    }
5538
5539    private final boolean killPackageProcessesLocked(String packageName, int appId,
5540            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5541            boolean doit, boolean evenPersistent, String reason) {
5542        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5543
5544        // Remove all processes this package may have touched: all with the
5545        // same UID (except for the system or root user), and all whose name
5546        // matches the package name.
5547        final int NP = mProcessNames.getMap().size();
5548        for (int ip=0; ip<NP; ip++) {
5549            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5550            final int NA = apps.size();
5551            for (int ia=0; ia<NA; ia++) {
5552                ProcessRecord app = apps.valueAt(ia);
5553                if (app.persistent && !evenPersistent) {
5554                    // we don't kill persistent processes
5555                    continue;
5556                }
5557                if (app.removed) {
5558                    if (doit) {
5559                        procs.add(app);
5560                    }
5561                    continue;
5562                }
5563
5564                // Skip process if it doesn't meet our oom adj requirement.
5565                if (app.setAdj < minOomAdj) {
5566                    continue;
5567                }
5568
5569                // If no package is specified, we call all processes under the
5570                // give user id.
5571                if (packageName == null) {
5572                    if (app.userId != userId) {
5573                        continue;
5574                    }
5575                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5576                        continue;
5577                    }
5578                // Package has been specified, we want to hit all processes
5579                // that match it.  We need to qualify this by the processes
5580                // that are running under the specified app and user ID.
5581                } else {
5582                    final boolean isDep = app.pkgDeps != null
5583                            && app.pkgDeps.contains(packageName);
5584                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5585                        continue;
5586                    }
5587                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5588                        continue;
5589                    }
5590                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5591                        continue;
5592                    }
5593                }
5594
5595                // Process has passed all conditions, kill it!
5596                if (!doit) {
5597                    return true;
5598                }
5599                app.removed = true;
5600                procs.add(app);
5601            }
5602        }
5603
5604        int N = procs.size();
5605        for (int i=0; i<N; i++) {
5606            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5607        }
5608        updateOomAdjLocked();
5609        return N > 0;
5610    }
5611
5612    private final boolean forceStopPackageLocked(String name, int appId,
5613            boolean callerWillRestart, boolean purgeCache, boolean doit,
5614            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5615        int i;
5616        int N;
5617
5618        if (userId == UserHandle.USER_ALL && name == null) {
5619            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5620        }
5621
5622        if (appId < 0 && name != null) {
5623            try {
5624                appId = UserHandle.getAppId(
5625                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5626            } catch (RemoteException e) {
5627            }
5628        }
5629
5630        if (doit) {
5631            if (name != null) {
5632                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5633                        + " user=" + userId + ": " + reason);
5634            } else {
5635                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5636            }
5637
5638            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5639            for (int ip=pmap.size()-1; ip>=0; ip--) {
5640                SparseArray<Long> ba = pmap.valueAt(ip);
5641                for (i=ba.size()-1; i>=0; i--) {
5642                    boolean remove = false;
5643                    final int entUid = ba.keyAt(i);
5644                    if (name != null) {
5645                        if (userId == UserHandle.USER_ALL) {
5646                            if (UserHandle.getAppId(entUid) == appId) {
5647                                remove = true;
5648                            }
5649                        } else {
5650                            if (entUid == UserHandle.getUid(userId, appId)) {
5651                                remove = true;
5652                            }
5653                        }
5654                    } else if (UserHandle.getUserId(entUid) == userId) {
5655                        remove = true;
5656                    }
5657                    if (remove) {
5658                        ba.removeAt(i);
5659                    }
5660                }
5661                if (ba.size() == 0) {
5662                    pmap.removeAt(ip);
5663                }
5664            }
5665        }
5666
5667        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5668                -100, callerWillRestart, true, doit, evenPersistent,
5669                name == null ? ("stop user " + userId) : ("stop " + name));
5670
5671        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5672            if (!doit) {
5673                return true;
5674            }
5675            didSomething = true;
5676        }
5677
5678        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5679            if (!doit) {
5680                return true;
5681            }
5682            didSomething = true;
5683        }
5684
5685        if (name == null) {
5686            // Remove all sticky broadcasts from this user.
5687            mStickyBroadcasts.remove(userId);
5688        }
5689
5690        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5691        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5692                userId, providers)) {
5693            if (!doit) {
5694                return true;
5695            }
5696            didSomething = true;
5697        }
5698        N = providers.size();
5699        for (i=0; i<N; i++) {
5700            removeDyingProviderLocked(null, providers.get(i), true);
5701        }
5702
5703        // Remove transient permissions granted from/to this package/user
5704        removeUriPermissionsForPackageLocked(name, userId, false);
5705
5706        if (name == null || uninstalling) {
5707            // Remove pending intents.  For now we only do this when force
5708            // stopping users, because we have some problems when doing this
5709            // for packages -- app widgets are not currently cleaned up for
5710            // such packages, so they can be left with bad pending intents.
5711            if (mIntentSenderRecords.size() > 0) {
5712                Iterator<WeakReference<PendingIntentRecord>> it
5713                        = mIntentSenderRecords.values().iterator();
5714                while (it.hasNext()) {
5715                    WeakReference<PendingIntentRecord> wpir = it.next();
5716                    if (wpir == null) {
5717                        it.remove();
5718                        continue;
5719                    }
5720                    PendingIntentRecord pir = wpir.get();
5721                    if (pir == null) {
5722                        it.remove();
5723                        continue;
5724                    }
5725                    if (name == null) {
5726                        // Stopping user, remove all objects for the user.
5727                        if (pir.key.userId != userId) {
5728                            // Not the same user, skip it.
5729                            continue;
5730                        }
5731                    } else {
5732                        if (UserHandle.getAppId(pir.uid) != appId) {
5733                            // Different app id, skip it.
5734                            continue;
5735                        }
5736                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5737                            // Different user, skip it.
5738                            continue;
5739                        }
5740                        if (!pir.key.packageName.equals(name)) {
5741                            // Different package, skip it.
5742                            continue;
5743                        }
5744                    }
5745                    if (!doit) {
5746                        return true;
5747                    }
5748                    didSomething = true;
5749                    it.remove();
5750                    pir.canceled = true;
5751                    if (pir.key.activity != null) {
5752                        pir.key.activity.pendingResults.remove(pir.ref);
5753                    }
5754                }
5755            }
5756        }
5757
5758        if (doit) {
5759            if (purgeCache && name != null) {
5760                AttributeCache ac = AttributeCache.instance();
5761                if (ac != null) {
5762                    ac.removePackage(name);
5763                }
5764            }
5765            if (mBooted) {
5766                mStackSupervisor.resumeTopActivitiesLocked();
5767                mStackSupervisor.scheduleIdleLocked();
5768            }
5769        }
5770
5771        return didSomething;
5772    }
5773
5774    private final boolean removeProcessLocked(ProcessRecord app,
5775            boolean callerWillRestart, boolean allowRestart, String reason) {
5776        final String name = app.processName;
5777        final int uid = app.uid;
5778        if (DEBUG_PROCESSES) Slog.d(
5779            TAG, "Force removing proc " + app.toShortString() + " (" + name
5780            + "/" + uid + ")");
5781
5782        mProcessNames.remove(name, uid);
5783        mIsolatedProcesses.remove(app.uid);
5784        if (mHeavyWeightProcess == app) {
5785            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5786                    mHeavyWeightProcess.userId, 0));
5787            mHeavyWeightProcess = null;
5788        }
5789        boolean needRestart = false;
5790        if (app.pid > 0 && app.pid != MY_PID) {
5791            int pid = app.pid;
5792            synchronized (mPidsSelfLocked) {
5793                mPidsSelfLocked.remove(pid);
5794                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5795            }
5796            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5797            if (app.isolated) {
5798                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5799            }
5800            app.kill(reason, true);
5801            handleAppDiedLocked(app, true, allowRestart);
5802            removeLruProcessLocked(app);
5803
5804            if (app.persistent && !app.isolated) {
5805                if (!callerWillRestart) {
5806                    addAppLocked(app.info, false, null /* ABI override */);
5807                } else {
5808                    needRestart = true;
5809                }
5810            }
5811        } else {
5812            mRemovedProcesses.add(app);
5813        }
5814
5815        return needRestart;
5816    }
5817
5818    private final void processStartTimedOutLocked(ProcessRecord app) {
5819        final int pid = app.pid;
5820        boolean gone = false;
5821        synchronized (mPidsSelfLocked) {
5822            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5823            if (knownApp != null && knownApp.thread == null) {
5824                mPidsSelfLocked.remove(pid);
5825                gone = true;
5826            }
5827        }
5828
5829        if (gone) {
5830            Slog.w(TAG, "Process " + app + " failed to attach");
5831            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5832                    pid, app.uid, app.processName);
5833            mProcessNames.remove(app.processName, app.uid);
5834            mIsolatedProcesses.remove(app.uid);
5835            if (mHeavyWeightProcess == app) {
5836                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5837                        mHeavyWeightProcess.userId, 0));
5838                mHeavyWeightProcess = null;
5839            }
5840            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5841            if (app.isolated) {
5842                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5843            }
5844            // Take care of any launching providers waiting for this process.
5845            checkAppInLaunchingProvidersLocked(app, true);
5846            // Take care of any services that are waiting for the process.
5847            mServices.processStartTimedOutLocked(app);
5848            app.kill("start timeout", true);
5849            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5850                Slog.w(TAG, "Unattached app died before backup, skipping");
5851                try {
5852                    IBackupManager bm = IBackupManager.Stub.asInterface(
5853                            ServiceManager.getService(Context.BACKUP_SERVICE));
5854                    bm.agentDisconnected(app.info.packageName);
5855                } catch (RemoteException e) {
5856                    // Can't happen; the backup manager is local
5857                }
5858            }
5859            if (isPendingBroadcastProcessLocked(pid)) {
5860                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5861                skipPendingBroadcastLocked(pid);
5862            }
5863        } else {
5864            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5865        }
5866    }
5867
5868    private final boolean attachApplicationLocked(IApplicationThread thread,
5869            int pid) {
5870
5871        // Find the application record that is being attached...  either via
5872        // the pid if we are running in multiple processes, or just pull the
5873        // next app record if we are emulating process with anonymous threads.
5874        ProcessRecord app;
5875        if (pid != MY_PID && pid >= 0) {
5876            synchronized (mPidsSelfLocked) {
5877                app = mPidsSelfLocked.get(pid);
5878            }
5879        } else {
5880            app = null;
5881        }
5882
5883        if (app == null) {
5884            Slog.w(TAG, "No pending application record for pid " + pid
5885                    + " (IApplicationThread " + thread + "); dropping process");
5886            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5887            if (pid > 0 && pid != MY_PID) {
5888                Process.killProcessQuiet(pid);
5889                //TODO: Process.killProcessGroup(app.info.uid, pid);
5890            } else {
5891                try {
5892                    thread.scheduleExit();
5893                } catch (Exception e) {
5894                    // Ignore exceptions.
5895                }
5896            }
5897            return false;
5898        }
5899
5900        // If this application record is still attached to a previous
5901        // process, clean it up now.
5902        if (app.thread != null) {
5903            handleAppDiedLocked(app, true, true);
5904        }
5905
5906        // Tell the process all about itself.
5907
5908        if (localLOGV) Slog.v(
5909                TAG, "Binding process pid " + pid + " to record " + app);
5910
5911        final String processName = app.processName;
5912        try {
5913            AppDeathRecipient adr = new AppDeathRecipient(
5914                    app, pid, thread);
5915            thread.asBinder().linkToDeath(adr, 0);
5916            app.deathRecipient = adr;
5917        } catch (RemoteException e) {
5918            app.resetPackageList(mProcessStats);
5919            startProcessLocked(app, "link fail", processName);
5920            return false;
5921        }
5922
5923        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5924
5925        app.makeActive(thread, mProcessStats);
5926        app.curAdj = app.setAdj = -100;
5927        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5928        app.forcingToForeground = null;
5929        updateProcessForegroundLocked(app, false, false);
5930        app.hasShownUi = false;
5931        app.debugging = false;
5932        app.cached = false;
5933
5934        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5935
5936        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5937        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5938
5939        if (!normalMode) {
5940            Slog.i(TAG, "Launching preboot mode app: " + app);
5941        }
5942
5943        if (localLOGV) Slog.v(
5944            TAG, "New app record " + app
5945            + " thread=" + thread.asBinder() + " pid=" + pid);
5946        try {
5947            int testMode = IApplicationThread.DEBUG_OFF;
5948            if (mDebugApp != null && mDebugApp.equals(processName)) {
5949                testMode = mWaitForDebugger
5950                    ? IApplicationThread.DEBUG_WAIT
5951                    : IApplicationThread.DEBUG_ON;
5952                app.debugging = true;
5953                if (mDebugTransient) {
5954                    mDebugApp = mOrigDebugApp;
5955                    mWaitForDebugger = mOrigWaitForDebugger;
5956                }
5957            }
5958            String profileFile = app.instrumentationProfileFile;
5959            ParcelFileDescriptor profileFd = null;
5960            int samplingInterval = 0;
5961            boolean profileAutoStop = false;
5962            if (mProfileApp != null && mProfileApp.equals(processName)) {
5963                mProfileProc = app;
5964                profileFile = mProfileFile;
5965                profileFd = mProfileFd;
5966                samplingInterval = mSamplingInterval;
5967                profileAutoStop = mAutoStopProfiler;
5968            }
5969            boolean enableOpenGlTrace = false;
5970            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5971                enableOpenGlTrace = true;
5972                mOpenGlTraceApp = null;
5973            }
5974
5975            // If the app is being launched for restore or full backup, set it up specially
5976            boolean isRestrictedBackupMode = false;
5977            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5978                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5979                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5980                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5981            }
5982
5983            ensurePackageDexOpt(app.instrumentationInfo != null
5984                    ? app.instrumentationInfo.packageName
5985                    : app.info.packageName);
5986            if (app.instrumentationClass != null) {
5987                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5988            }
5989            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5990                    + processName + " with config " + mConfiguration);
5991            ApplicationInfo appInfo = app.instrumentationInfo != null
5992                    ? app.instrumentationInfo : app.info;
5993            app.compat = compatibilityInfoForPackageLocked(appInfo);
5994            if (profileFd != null) {
5995                profileFd = profileFd.dup();
5996            }
5997            ProfilerInfo profilerInfo = profileFile == null ? null
5998                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5999            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6000                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6001                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6002                    isRestrictedBackupMode || !normalMode, app.persistent,
6003                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6004                    mCoreSettingsObserver.getCoreSettingsLocked());
6005            updateLruProcessLocked(app, false, null);
6006            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6007        } catch (Exception e) {
6008            // todo: Yikes!  What should we do?  For now we will try to
6009            // start another process, but that could easily get us in
6010            // an infinite loop of restarting processes...
6011            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6012
6013            app.resetPackageList(mProcessStats);
6014            app.unlinkDeathRecipient();
6015            startProcessLocked(app, "bind fail", processName);
6016            return false;
6017        }
6018
6019        // Remove this record from the list of starting applications.
6020        mPersistentStartingProcesses.remove(app);
6021        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6022                "Attach application locked removing on hold: " + app);
6023        mProcessesOnHold.remove(app);
6024
6025        boolean badApp = false;
6026        boolean didSomething = false;
6027
6028        // See if the top visible activity is waiting to run in this process...
6029        if (normalMode) {
6030            try {
6031                if (mStackSupervisor.attachApplicationLocked(app)) {
6032                    didSomething = true;
6033                }
6034            } catch (Exception e) {
6035                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6036                badApp = true;
6037            }
6038        }
6039
6040        // Find any services that should be running in this process...
6041        if (!badApp) {
6042            try {
6043                didSomething |= mServices.attachApplicationLocked(app, processName);
6044            } catch (Exception e) {
6045                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6046                badApp = true;
6047            }
6048        }
6049
6050        // Check if a next-broadcast receiver is in this process...
6051        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6052            try {
6053                didSomething |= sendPendingBroadcastsLocked(app);
6054            } catch (Exception e) {
6055                // If the app died trying to launch the receiver we declare it 'bad'
6056                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6057                badApp = true;
6058            }
6059        }
6060
6061        // Check whether the next backup agent is in this process...
6062        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6063            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6064            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6065            try {
6066                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6067                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6068                        mBackupTarget.backupMode);
6069            } catch (Exception e) {
6070                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6071                badApp = true;
6072            }
6073        }
6074
6075        if (badApp) {
6076            app.kill("error during init", true);
6077            handleAppDiedLocked(app, false, true);
6078            return false;
6079        }
6080
6081        if (!didSomething) {
6082            updateOomAdjLocked();
6083        }
6084
6085        return true;
6086    }
6087
6088    @Override
6089    public final void attachApplication(IApplicationThread thread) {
6090        synchronized (this) {
6091            int callingPid = Binder.getCallingPid();
6092            final long origId = Binder.clearCallingIdentity();
6093            attachApplicationLocked(thread, callingPid);
6094            Binder.restoreCallingIdentity(origId);
6095        }
6096    }
6097
6098    @Override
6099    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6100        final long origId = Binder.clearCallingIdentity();
6101        synchronized (this) {
6102            ActivityStack stack = ActivityRecord.getStackLocked(token);
6103            if (stack != null) {
6104                ActivityRecord r =
6105                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6106                if (stopProfiling) {
6107                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6108                        try {
6109                            mProfileFd.close();
6110                        } catch (IOException e) {
6111                        }
6112                        clearProfilerLocked();
6113                    }
6114                }
6115            }
6116        }
6117        Binder.restoreCallingIdentity(origId);
6118    }
6119
6120    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6121        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6122                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6123    }
6124
6125    void enableScreenAfterBoot() {
6126        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6127                SystemClock.uptimeMillis());
6128        mWindowManager.enableScreenAfterBoot();
6129
6130        synchronized (this) {
6131            updateEventDispatchingLocked();
6132        }
6133    }
6134
6135    @Override
6136    public void showBootMessage(final CharSequence msg, final boolean always) {
6137        enforceNotIsolatedCaller("showBootMessage");
6138        mWindowManager.showBootMessage(msg, always);
6139    }
6140
6141    @Override
6142    public void keyguardWaitingForActivityDrawn() {
6143        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6144        final long token = Binder.clearCallingIdentity();
6145        try {
6146            synchronized (this) {
6147                if (DEBUG_LOCKSCREEN) logLockScreen("");
6148                mWindowManager.keyguardWaitingForActivityDrawn();
6149                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6150                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6151                }
6152            }
6153        } finally {
6154            Binder.restoreCallingIdentity(token);
6155        }
6156    }
6157
6158    final void finishBooting() {
6159        synchronized (this) {
6160            if (!mBootAnimationComplete) {
6161                mCallFinishBooting = true;
6162                return;
6163            }
6164            mCallFinishBooting = false;
6165        }
6166
6167        ArraySet<String> completedIsas = new ArraySet<String>();
6168        for (String abi : Build.SUPPORTED_ABIS) {
6169            Process.establishZygoteConnectionForAbi(abi);
6170            final String instructionSet = VMRuntime.getInstructionSet(abi);
6171            if (!completedIsas.contains(instructionSet)) {
6172                if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6173                    Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6174                }
6175                completedIsas.add(instructionSet);
6176            }
6177        }
6178
6179        // Register receivers to handle package update events
6180        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6181
6182        // Let system services know.
6183        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6184
6185        synchronized (this) {
6186            // Ensure that any processes we had put on hold are now started
6187            // up.
6188            final int NP = mProcessesOnHold.size();
6189            if (NP > 0) {
6190                ArrayList<ProcessRecord> procs =
6191                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6192                for (int ip=0; ip<NP; ip++) {
6193                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6194                            + procs.get(ip));
6195                    startProcessLocked(procs.get(ip), "on-hold", null);
6196                }
6197            }
6198
6199            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6200                // Start looking for apps that are abusing wake locks.
6201                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6202                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6203                // Tell anyone interested that we are done booting!
6204                SystemProperties.set("sys.boot_completed", "1");
6205
6206                // And trigger dev.bootcomplete if we are not showing encryption progress
6207                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6208                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6209                    SystemProperties.set("dev.bootcomplete", "1");
6210                }
6211                for (int i=0; i<mStartedUsers.size(); i++) {
6212                    UserStartedState uss = mStartedUsers.valueAt(i);
6213                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6214                        uss.mState = UserStartedState.STATE_RUNNING;
6215                        final int userId = mStartedUsers.keyAt(i);
6216                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6217                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6218                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6219                        broadcastIntentLocked(null, null, intent, null,
6220                                new IIntentReceiver.Stub() {
6221                                    @Override
6222                                    public void performReceive(Intent intent, int resultCode,
6223                                            String data, Bundle extras, boolean ordered,
6224                                            boolean sticky, int sendingUser) {
6225                                        synchronized (ActivityManagerService.this) {
6226                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6227                                                    true, false);
6228                                        }
6229                                    }
6230                                },
6231                                0, null, null,
6232                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6233                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6234                                userId);
6235                    }
6236                }
6237                scheduleStartProfilesLocked();
6238            }
6239        }
6240    }
6241
6242    @Override
6243    public void bootAnimationComplete() {
6244        final boolean callFinishBooting;
6245        synchronized (this) {
6246            callFinishBooting = mCallFinishBooting;
6247            mBootAnimationComplete = true;
6248        }
6249        if (callFinishBooting) {
6250            finishBooting();
6251        }
6252    }
6253
6254    final void ensureBootCompleted() {
6255        boolean booting;
6256        boolean enableScreen;
6257        synchronized (this) {
6258            booting = mBooting;
6259            mBooting = false;
6260            enableScreen = !mBooted;
6261            mBooted = true;
6262        }
6263
6264        if (booting) {
6265            finishBooting();
6266        }
6267
6268        if (enableScreen) {
6269            enableScreenAfterBoot();
6270        }
6271    }
6272
6273    @Override
6274    public final void activityResumed(IBinder token) {
6275        final long origId = Binder.clearCallingIdentity();
6276        synchronized(this) {
6277            ActivityStack stack = ActivityRecord.getStackLocked(token);
6278            if (stack != null) {
6279                ActivityRecord.activityResumedLocked(token);
6280            }
6281        }
6282        Binder.restoreCallingIdentity(origId);
6283    }
6284
6285    @Override
6286    public final void activityPaused(IBinder token) {
6287        final long origId = Binder.clearCallingIdentity();
6288        synchronized(this) {
6289            ActivityStack stack = ActivityRecord.getStackLocked(token);
6290            if (stack != null) {
6291                stack.activityPausedLocked(token, false);
6292            }
6293        }
6294        Binder.restoreCallingIdentity(origId);
6295    }
6296
6297    @Override
6298    public final void activityStopped(IBinder token, Bundle icicle,
6299            PersistableBundle persistentState, CharSequence description) {
6300        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6301
6302        // Refuse possible leaked file descriptors
6303        if (icicle != null && icicle.hasFileDescriptors()) {
6304            throw new IllegalArgumentException("File descriptors passed in Bundle");
6305        }
6306
6307        final long origId = Binder.clearCallingIdentity();
6308
6309        synchronized (this) {
6310            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6311            if (r != null) {
6312                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6313            }
6314        }
6315
6316        trimApplications();
6317
6318        Binder.restoreCallingIdentity(origId);
6319    }
6320
6321    @Override
6322    public final void activityDestroyed(IBinder token) {
6323        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6324        synchronized (this) {
6325            ActivityStack stack = ActivityRecord.getStackLocked(token);
6326            if (stack != null) {
6327                stack.activityDestroyedLocked(token);
6328            }
6329        }
6330    }
6331
6332    @Override
6333    public final void backgroundResourcesReleased(IBinder token) {
6334        final long origId = Binder.clearCallingIdentity();
6335        try {
6336            synchronized (this) {
6337                ActivityStack stack = ActivityRecord.getStackLocked(token);
6338                if (stack != null) {
6339                    stack.backgroundResourcesReleased(token);
6340                }
6341            }
6342        } finally {
6343            Binder.restoreCallingIdentity(origId);
6344        }
6345    }
6346
6347    @Override
6348    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6349        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6350    }
6351
6352    @Override
6353    public final void notifyEnterAnimationComplete(IBinder token) {
6354        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6355    }
6356
6357    @Override
6358    public String getCallingPackage(IBinder token) {
6359        synchronized (this) {
6360            ActivityRecord r = getCallingRecordLocked(token);
6361            return r != null ? r.info.packageName : null;
6362        }
6363    }
6364
6365    @Override
6366    public ComponentName getCallingActivity(IBinder token) {
6367        synchronized (this) {
6368            ActivityRecord r = getCallingRecordLocked(token);
6369            return r != null ? r.intent.getComponent() : null;
6370        }
6371    }
6372
6373    private ActivityRecord getCallingRecordLocked(IBinder token) {
6374        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6375        if (r == null) {
6376            return null;
6377        }
6378        return r.resultTo;
6379    }
6380
6381    @Override
6382    public ComponentName getActivityClassForToken(IBinder token) {
6383        synchronized(this) {
6384            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6385            if (r == null) {
6386                return null;
6387            }
6388            return r.intent.getComponent();
6389        }
6390    }
6391
6392    @Override
6393    public String getPackageForToken(IBinder token) {
6394        synchronized(this) {
6395            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6396            if (r == null) {
6397                return null;
6398            }
6399            return r.packageName;
6400        }
6401    }
6402
6403    @Override
6404    public IIntentSender getIntentSender(int type,
6405            String packageName, IBinder token, String resultWho,
6406            int requestCode, Intent[] intents, String[] resolvedTypes,
6407            int flags, Bundle options, int userId) {
6408        enforceNotIsolatedCaller("getIntentSender");
6409        // Refuse possible leaked file descriptors
6410        if (intents != null) {
6411            if (intents.length < 1) {
6412                throw new IllegalArgumentException("Intents array length must be >= 1");
6413            }
6414            for (int i=0; i<intents.length; i++) {
6415                Intent intent = intents[i];
6416                if (intent != null) {
6417                    if (intent.hasFileDescriptors()) {
6418                        throw new IllegalArgumentException("File descriptors passed in Intent");
6419                    }
6420                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6421                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6422                        throw new IllegalArgumentException(
6423                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6424                    }
6425                    intents[i] = new Intent(intent);
6426                }
6427            }
6428            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6429                throw new IllegalArgumentException(
6430                        "Intent array length does not match resolvedTypes length");
6431            }
6432        }
6433        if (options != null) {
6434            if (options.hasFileDescriptors()) {
6435                throw new IllegalArgumentException("File descriptors passed in options");
6436            }
6437        }
6438
6439        synchronized(this) {
6440            int callingUid = Binder.getCallingUid();
6441            int origUserId = userId;
6442            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6443                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6444                    ALLOW_NON_FULL, "getIntentSender", null);
6445            if (origUserId == UserHandle.USER_CURRENT) {
6446                // We don't want to evaluate this until the pending intent is
6447                // actually executed.  However, we do want to always do the
6448                // security checking for it above.
6449                userId = UserHandle.USER_CURRENT;
6450            }
6451            try {
6452                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6453                    int uid = AppGlobals.getPackageManager()
6454                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6455                    if (!UserHandle.isSameApp(callingUid, uid)) {
6456                        String msg = "Permission Denial: getIntentSender() from pid="
6457                            + Binder.getCallingPid()
6458                            + ", uid=" + Binder.getCallingUid()
6459                            + ", (need uid=" + uid + ")"
6460                            + " is not allowed to send as package " + packageName;
6461                        Slog.w(TAG, msg);
6462                        throw new SecurityException(msg);
6463                    }
6464                }
6465
6466                return getIntentSenderLocked(type, packageName, callingUid, userId,
6467                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6468
6469            } catch (RemoteException e) {
6470                throw new SecurityException(e);
6471            }
6472        }
6473    }
6474
6475    IIntentSender getIntentSenderLocked(int type, String packageName,
6476            int callingUid, int userId, IBinder token, String resultWho,
6477            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6478            Bundle options) {
6479        if (DEBUG_MU)
6480            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6481        ActivityRecord activity = null;
6482        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6483            activity = ActivityRecord.isInStackLocked(token);
6484            if (activity == null) {
6485                return null;
6486            }
6487            if (activity.finishing) {
6488                return null;
6489            }
6490        }
6491
6492        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6493        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6494        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6495        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6496                |PendingIntent.FLAG_UPDATE_CURRENT);
6497
6498        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6499                type, packageName, activity, resultWho,
6500                requestCode, intents, resolvedTypes, flags, options, userId);
6501        WeakReference<PendingIntentRecord> ref;
6502        ref = mIntentSenderRecords.get(key);
6503        PendingIntentRecord rec = ref != null ? ref.get() : null;
6504        if (rec != null) {
6505            if (!cancelCurrent) {
6506                if (updateCurrent) {
6507                    if (rec.key.requestIntent != null) {
6508                        rec.key.requestIntent.replaceExtras(intents != null ?
6509                                intents[intents.length - 1] : null);
6510                    }
6511                    if (intents != null) {
6512                        intents[intents.length-1] = rec.key.requestIntent;
6513                        rec.key.allIntents = intents;
6514                        rec.key.allResolvedTypes = resolvedTypes;
6515                    } else {
6516                        rec.key.allIntents = null;
6517                        rec.key.allResolvedTypes = null;
6518                    }
6519                }
6520                return rec;
6521            }
6522            rec.canceled = true;
6523            mIntentSenderRecords.remove(key);
6524        }
6525        if (noCreate) {
6526            return rec;
6527        }
6528        rec = new PendingIntentRecord(this, key, callingUid);
6529        mIntentSenderRecords.put(key, rec.ref);
6530        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6531            if (activity.pendingResults == null) {
6532                activity.pendingResults
6533                        = new HashSet<WeakReference<PendingIntentRecord>>();
6534            }
6535            activity.pendingResults.add(rec.ref);
6536        }
6537        return rec;
6538    }
6539
6540    @Override
6541    public void cancelIntentSender(IIntentSender sender) {
6542        if (!(sender instanceof PendingIntentRecord)) {
6543            return;
6544        }
6545        synchronized(this) {
6546            PendingIntentRecord rec = (PendingIntentRecord)sender;
6547            try {
6548                int uid = AppGlobals.getPackageManager()
6549                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6550                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6551                    String msg = "Permission Denial: cancelIntentSender() from pid="
6552                        + Binder.getCallingPid()
6553                        + ", uid=" + Binder.getCallingUid()
6554                        + " is not allowed to cancel packges "
6555                        + rec.key.packageName;
6556                    Slog.w(TAG, msg);
6557                    throw new SecurityException(msg);
6558                }
6559            } catch (RemoteException e) {
6560                throw new SecurityException(e);
6561            }
6562            cancelIntentSenderLocked(rec, true);
6563        }
6564    }
6565
6566    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6567        rec.canceled = true;
6568        mIntentSenderRecords.remove(rec.key);
6569        if (cleanActivity && rec.key.activity != null) {
6570            rec.key.activity.pendingResults.remove(rec.ref);
6571        }
6572    }
6573
6574    @Override
6575    public String getPackageForIntentSender(IIntentSender pendingResult) {
6576        if (!(pendingResult instanceof PendingIntentRecord)) {
6577            return null;
6578        }
6579        try {
6580            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6581            return res.key.packageName;
6582        } catch (ClassCastException e) {
6583        }
6584        return null;
6585    }
6586
6587    @Override
6588    public int getUidForIntentSender(IIntentSender sender) {
6589        if (sender instanceof PendingIntentRecord) {
6590            try {
6591                PendingIntentRecord res = (PendingIntentRecord)sender;
6592                return res.uid;
6593            } catch (ClassCastException e) {
6594            }
6595        }
6596        return -1;
6597    }
6598
6599    @Override
6600    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6601        if (!(pendingResult instanceof PendingIntentRecord)) {
6602            return false;
6603        }
6604        try {
6605            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6606            if (res.key.allIntents == null) {
6607                return false;
6608            }
6609            for (int i=0; i<res.key.allIntents.length; i++) {
6610                Intent intent = res.key.allIntents[i];
6611                if (intent.getPackage() != null && intent.getComponent() != null) {
6612                    return false;
6613                }
6614            }
6615            return true;
6616        } catch (ClassCastException e) {
6617        }
6618        return false;
6619    }
6620
6621    @Override
6622    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6623        if (!(pendingResult instanceof PendingIntentRecord)) {
6624            return false;
6625        }
6626        try {
6627            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6628            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6629                return true;
6630            }
6631            return false;
6632        } catch (ClassCastException e) {
6633        }
6634        return false;
6635    }
6636
6637    @Override
6638    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6639        if (!(pendingResult instanceof PendingIntentRecord)) {
6640            return null;
6641        }
6642        try {
6643            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6644            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6645        } catch (ClassCastException e) {
6646        }
6647        return null;
6648    }
6649
6650    @Override
6651    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6652        if (!(pendingResult instanceof PendingIntentRecord)) {
6653            return null;
6654        }
6655        try {
6656            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6657            Intent intent = res.key.requestIntent;
6658            if (intent != null) {
6659                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6660                        || res.lastTagPrefix.equals(prefix))) {
6661                    return res.lastTag;
6662                }
6663                res.lastTagPrefix = prefix;
6664                StringBuilder sb = new StringBuilder(128);
6665                if (prefix != null) {
6666                    sb.append(prefix);
6667                }
6668                if (intent.getAction() != null) {
6669                    sb.append(intent.getAction());
6670                } else if (intent.getComponent() != null) {
6671                    intent.getComponent().appendShortString(sb);
6672                } else {
6673                    sb.append("?");
6674                }
6675                return res.lastTag = sb.toString();
6676            }
6677        } catch (ClassCastException e) {
6678        }
6679        return null;
6680    }
6681
6682    @Override
6683    public void setProcessLimit(int max) {
6684        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6685                "setProcessLimit()");
6686        synchronized (this) {
6687            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6688            mProcessLimitOverride = max;
6689        }
6690        trimApplications();
6691    }
6692
6693    @Override
6694    public int getProcessLimit() {
6695        synchronized (this) {
6696            return mProcessLimitOverride;
6697        }
6698    }
6699
6700    void foregroundTokenDied(ForegroundToken token) {
6701        synchronized (ActivityManagerService.this) {
6702            synchronized (mPidsSelfLocked) {
6703                ForegroundToken cur
6704                    = mForegroundProcesses.get(token.pid);
6705                if (cur != token) {
6706                    return;
6707                }
6708                mForegroundProcesses.remove(token.pid);
6709                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6710                if (pr == null) {
6711                    return;
6712                }
6713                pr.forcingToForeground = null;
6714                updateProcessForegroundLocked(pr, false, false);
6715            }
6716            updateOomAdjLocked();
6717        }
6718    }
6719
6720    @Override
6721    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6722        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6723                "setProcessForeground()");
6724        synchronized(this) {
6725            boolean changed = false;
6726
6727            synchronized (mPidsSelfLocked) {
6728                ProcessRecord pr = mPidsSelfLocked.get(pid);
6729                if (pr == null && isForeground) {
6730                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6731                    return;
6732                }
6733                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6734                if (oldToken != null) {
6735                    oldToken.token.unlinkToDeath(oldToken, 0);
6736                    mForegroundProcesses.remove(pid);
6737                    if (pr != null) {
6738                        pr.forcingToForeground = null;
6739                    }
6740                    changed = true;
6741                }
6742                if (isForeground && token != null) {
6743                    ForegroundToken newToken = new ForegroundToken() {
6744                        @Override
6745                        public void binderDied() {
6746                            foregroundTokenDied(this);
6747                        }
6748                    };
6749                    newToken.pid = pid;
6750                    newToken.token = token;
6751                    try {
6752                        token.linkToDeath(newToken, 0);
6753                        mForegroundProcesses.put(pid, newToken);
6754                        pr.forcingToForeground = token;
6755                        changed = true;
6756                    } catch (RemoteException e) {
6757                        // If the process died while doing this, we will later
6758                        // do the cleanup with the process death link.
6759                    }
6760                }
6761            }
6762
6763            if (changed) {
6764                updateOomAdjLocked();
6765            }
6766        }
6767    }
6768
6769    // =========================================================
6770    // PERMISSIONS
6771    // =========================================================
6772
6773    static class PermissionController extends IPermissionController.Stub {
6774        ActivityManagerService mActivityManagerService;
6775        PermissionController(ActivityManagerService activityManagerService) {
6776            mActivityManagerService = activityManagerService;
6777        }
6778
6779        @Override
6780        public boolean checkPermission(String permission, int pid, int uid) {
6781            return mActivityManagerService.checkPermission(permission, pid,
6782                    uid) == PackageManager.PERMISSION_GRANTED;
6783        }
6784    }
6785
6786    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6787        @Override
6788        public int checkComponentPermission(String permission, int pid, int uid,
6789                int owningUid, boolean exported) {
6790            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6791                    owningUid, exported);
6792        }
6793
6794        @Override
6795        public Object getAMSLock() {
6796            return ActivityManagerService.this;
6797        }
6798    }
6799
6800    /**
6801     * This can be called with or without the global lock held.
6802     */
6803    int checkComponentPermission(String permission, int pid, int uid,
6804            int owningUid, boolean exported) {
6805        // We might be performing an operation on behalf of an indirect binder
6806        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6807        // client identity accordingly before proceeding.
6808        Identity tlsIdentity = sCallerIdentity.get();
6809        if (tlsIdentity != null) {
6810            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6811                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6812            uid = tlsIdentity.uid;
6813            pid = tlsIdentity.pid;
6814        }
6815
6816        if (pid == MY_PID) {
6817            return PackageManager.PERMISSION_GRANTED;
6818        }
6819
6820        return ActivityManager.checkComponentPermission(permission, uid,
6821                owningUid, exported);
6822    }
6823
6824    /**
6825     * As the only public entry point for permissions checking, this method
6826     * can enforce the semantic that requesting a check on a null global
6827     * permission is automatically denied.  (Internally a null permission
6828     * string is used when calling {@link #checkComponentPermission} in cases
6829     * when only uid-based security is needed.)
6830     *
6831     * This can be called with or without the global lock held.
6832     */
6833    @Override
6834    public int checkPermission(String permission, int pid, int uid) {
6835        if (permission == null) {
6836            return PackageManager.PERMISSION_DENIED;
6837        }
6838        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6839    }
6840
6841    /**
6842     * Binder IPC calls go through the public entry point.
6843     * This can be called with or without the global lock held.
6844     */
6845    int checkCallingPermission(String permission) {
6846        return checkPermission(permission,
6847                Binder.getCallingPid(),
6848                UserHandle.getAppId(Binder.getCallingUid()));
6849    }
6850
6851    /**
6852     * This can be called with or without the global lock held.
6853     */
6854    void enforceCallingPermission(String permission, String func) {
6855        if (checkCallingPermission(permission)
6856                == PackageManager.PERMISSION_GRANTED) {
6857            return;
6858        }
6859
6860        String msg = "Permission Denial: " + func + " from pid="
6861                + Binder.getCallingPid()
6862                + ", uid=" + Binder.getCallingUid()
6863                + " requires " + permission;
6864        Slog.w(TAG, msg);
6865        throw new SecurityException(msg);
6866    }
6867
6868    /**
6869     * Determine if UID is holding permissions required to access {@link Uri} in
6870     * the given {@link ProviderInfo}. Final permission checking is always done
6871     * in {@link ContentProvider}.
6872     */
6873    private final boolean checkHoldingPermissionsLocked(
6874            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6875        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6876                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6877        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6878            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6879                    != PERMISSION_GRANTED) {
6880                return false;
6881            }
6882        }
6883        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6884    }
6885
6886    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6887            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6888        if (pi.applicationInfo.uid == uid) {
6889            return true;
6890        } else if (!pi.exported) {
6891            return false;
6892        }
6893
6894        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6895        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6896        try {
6897            // check if target holds top-level <provider> permissions
6898            if (!readMet && pi.readPermission != null && considerUidPermissions
6899                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6900                readMet = true;
6901            }
6902            if (!writeMet && pi.writePermission != null && considerUidPermissions
6903                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6904                writeMet = true;
6905            }
6906
6907            // track if unprotected read/write is allowed; any denied
6908            // <path-permission> below removes this ability
6909            boolean allowDefaultRead = pi.readPermission == null;
6910            boolean allowDefaultWrite = pi.writePermission == null;
6911
6912            // check if target holds any <path-permission> that match uri
6913            final PathPermission[] pps = pi.pathPermissions;
6914            if (pps != null) {
6915                final String path = grantUri.uri.getPath();
6916                int i = pps.length;
6917                while (i > 0 && (!readMet || !writeMet)) {
6918                    i--;
6919                    PathPermission pp = pps[i];
6920                    if (pp.match(path)) {
6921                        if (!readMet) {
6922                            final String pprperm = pp.getReadPermission();
6923                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6924                                    + pprperm + " for " + pp.getPath()
6925                                    + ": match=" + pp.match(path)
6926                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6927                            if (pprperm != null) {
6928                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6929                                        == PERMISSION_GRANTED) {
6930                                    readMet = true;
6931                                } else {
6932                                    allowDefaultRead = false;
6933                                }
6934                            }
6935                        }
6936                        if (!writeMet) {
6937                            final String ppwperm = pp.getWritePermission();
6938                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6939                                    + ppwperm + " for " + pp.getPath()
6940                                    + ": match=" + pp.match(path)
6941                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6942                            if (ppwperm != null) {
6943                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6944                                        == PERMISSION_GRANTED) {
6945                                    writeMet = true;
6946                                } else {
6947                                    allowDefaultWrite = false;
6948                                }
6949                            }
6950                        }
6951                    }
6952                }
6953            }
6954
6955            // grant unprotected <provider> read/write, if not blocked by
6956            // <path-permission> above
6957            if (allowDefaultRead) readMet = true;
6958            if (allowDefaultWrite) writeMet = true;
6959
6960        } catch (RemoteException e) {
6961            return false;
6962        }
6963
6964        return readMet && writeMet;
6965    }
6966
6967    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6968        ProviderInfo pi = null;
6969        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6970        if (cpr != null) {
6971            pi = cpr.info;
6972        } else {
6973            try {
6974                pi = AppGlobals.getPackageManager().resolveContentProvider(
6975                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6976            } catch (RemoteException ex) {
6977            }
6978        }
6979        return pi;
6980    }
6981
6982    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6983        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6984        if (targetUris != null) {
6985            return targetUris.get(grantUri);
6986        }
6987        return null;
6988    }
6989
6990    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6991            String targetPkg, int targetUid, GrantUri grantUri) {
6992        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6993        if (targetUris == null) {
6994            targetUris = Maps.newArrayMap();
6995            mGrantedUriPermissions.put(targetUid, targetUris);
6996        }
6997
6998        UriPermission perm = targetUris.get(grantUri);
6999        if (perm == null) {
7000            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7001            targetUris.put(grantUri, perm);
7002        }
7003
7004        return perm;
7005    }
7006
7007    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7008            final int modeFlags) {
7009        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7010        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7011                : UriPermission.STRENGTH_OWNED;
7012
7013        // Root gets to do everything.
7014        if (uid == 0) {
7015            return true;
7016        }
7017
7018        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7019        if (perms == null) return false;
7020
7021        // First look for exact match
7022        final UriPermission exactPerm = perms.get(grantUri);
7023        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7024            return true;
7025        }
7026
7027        // No exact match, look for prefixes
7028        final int N = perms.size();
7029        for (int i = 0; i < N; i++) {
7030            final UriPermission perm = perms.valueAt(i);
7031            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7032                    && perm.getStrength(modeFlags) >= minStrength) {
7033                return true;
7034            }
7035        }
7036
7037        return false;
7038    }
7039
7040    /**
7041     * @param uri This uri must NOT contain an embedded userId.
7042     * @param userId The userId in which the uri is to be resolved.
7043     */
7044    @Override
7045    public int checkUriPermission(Uri uri, int pid, int uid,
7046            final int modeFlags, int userId) {
7047        enforceNotIsolatedCaller("checkUriPermission");
7048
7049        // Another redirected-binder-call permissions check as in
7050        // {@link checkComponentPermission}.
7051        Identity tlsIdentity = sCallerIdentity.get();
7052        if (tlsIdentity != null) {
7053            uid = tlsIdentity.uid;
7054            pid = tlsIdentity.pid;
7055        }
7056
7057        // Our own process gets to do everything.
7058        if (pid == MY_PID) {
7059            return PackageManager.PERMISSION_GRANTED;
7060        }
7061        synchronized (this) {
7062            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7063                    ? PackageManager.PERMISSION_GRANTED
7064                    : PackageManager.PERMISSION_DENIED;
7065        }
7066    }
7067
7068    /**
7069     * Check if the targetPkg can be granted permission to access uri by
7070     * the callingUid using the given modeFlags.  Throws a security exception
7071     * if callingUid is not allowed to do this.  Returns the uid of the target
7072     * if the URI permission grant should be performed; returns -1 if it is not
7073     * needed (for example targetPkg already has permission to access the URI).
7074     * If you already know the uid of the target, you can supply it in
7075     * lastTargetUid else set that to -1.
7076     */
7077    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7078            final int modeFlags, int lastTargetUid) {
7079        if (!Intent.isAccessUriMode(modeFlags)) {
7080            return -1;
7081        }
7082
7083        if (targetPkg != null) {
7084            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7085                    "Checking grant " + targetPkg + " permission to " + grantUri);
7086        }
7087
7088        final IPackageManager pm = AppGlobals.getPackageManager();
7089
7090        // If this is not a content: uri, we can't do anything with it.
7091        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7092            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7093                    "Can't grant URI permission for non-content URI: " + grantUri);
7094            return -1;
7095        }
7096
7097        final String authority = grantUri.uri.getAuthority();
7098        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7099        if (pi == null) {
7100            Slog.w(TAG, "No content provider found for permission check: " +
7101                    grantUri.uri.toSafeString());
7102            return -1;
7103        }
7104
7105        int targetUid = lastTargetUid;
7106        if (targetUid < 0 && targetPkg != null) {
7107            try {
7108                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7109                if (targetUid < 0) {
7110                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7111                            "Can't grant URI permission no uid for: " + targetPkg);
7112                    return -1;
7113                }
7114            } catch (RemoteException ex) {
7115                return -1;
7116            }
7117        }
7118
7119        if (targetUid >= 0) {
7120            // First...  does the target actually need this permission?
7121            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7122                // No need to grant the target this permission.
7123                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7124                        "Target " + targetPkg + " already has full permission to " + grantUri);
7125                return -1;
7126            }
7127        } else {
7128            // First...  there is no target package, so can anyone access it?
7129            boolean allowed = pi.exported;
7130            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7131                if (pi.readPermission != null) {
7132                    allowed = false;
7133                }
7134            }
7135            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7136                if (pi.writePermission != null) {
7137                    allowed = false;
7138                }
7139            }
7140            if (allowed) {
7141                return -1;
7142            }
7143        }
7144
7145        /* There is a special cross user grant if:
7146         * - The target is on another user.
7147         * - Apps on the current user can access the uri without any uid permissions.
7148         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7149         * grant uri permissions.
7150         */
7151        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7152                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7153                modeFlags, false /*without considering the uid permissions*/);
7154
7155        // Second...  is the provider allowing granting of URI permissions?
7156        if (!specialCrossUserGrant) {
7157            if (!pi.grantUriPermissions) {
7158                throw new SecurityException("Provider " + pi.packageName
7159                        + "/" + pi.name
7160                        + " does not allow granting of Uri permissions (uri "
7161                        + grantUri + ")");
7162            }
7163            if (pi.uriPermissionPatterns != null) {
7164                final int N = pi.uriPermissionPatterns.length;
7165                boolean allowed = false;
7166                for (int i=0; i<N; i++) {
7167                    if (pi.uriPermissionPatterns[i] != null
7168                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7169                        allowed = true;
7170                        break;
7171                    }
7172                }
7173                if (!allowed) {
7174                    throw new SecurityException("Provider " + pi.packageName
7175                            + "/" + pi.name
7176                            + " does not allow granting of permission to path of Uri "
7177                            + grantUri);
7178                }
7179            }
7180        }
7181
7182        // Third...  does the caller itself have permission to access
7183        // this uri?
7184        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7185            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7186                // Require they hold a strong enough Uri permission
7187                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7188                    throw new SecurityException("Uid " + callingUid
7189                            + " does not have permission to uri " + grantUri);
7190                }
7191            }
7192        }
7193        return targetUid;
7194    }
7195
7196    /**
7197     * @param uri This uri must NOT contain an embedded userId.
7198     * @param userId The userId in which the uri is to be resolved.
7199     */
7200    @Override
7201    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7202            final int modeFlags, int userId) {
7203        enforceNotIsolatedCaller("checkGrantUriPermission");
7204        synchronized(this) {
7205            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7206                    new GrantUri(userId, uri, false), modeFlags, -1);
7207        }
7208    }
7209
7210    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7211            final int modeFlags, UriPermissionOwner owner) {
7212        if (!Intent.isAccessUriMode(modeFlags)) {
7213            return;
7214        }
7215
7216        // So here we are: the caller has the assumed permission
7217        // to the uri, and the target doesn't.  Let's now give this to
7218        // the target.
7219
7220        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7221                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7222
7223        final String authority = grantUri.uri.getAuthority();
7224        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7225        if (pi == null) {
7226            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7227            return;
7228        }
7229
7230        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7231            grantUri.prefix = true;
7232        }
7233        final UriPermission perm = findOrCreateUriPermissionLocked(
7234                pi.packageName, targetPkg, targetUid, grantUri);
7235        perm.grantModes(modeFlags, owner);
7236    }
7237
7238    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7239            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7240        if (targetPkg == null) {
7241            throw new NullPointerException("targetPkg");
7242        }
7243        int targetUid;
7244        final IPackageManager pm = AppGlobals.getPackageManager();
7245        try {
7246            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7247        } catch (RemoteException ex) {
7248            return;
7249        }
7250
7251        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7252                targetUid);
7253        if (targetUid < 0) {
7254            return;
7255        }
7256
7257        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7258                owner);
7259    }
7260
7261    static class NeededUriGrants extends ArrayList<GrantUri> {
7262        final String targetPkg;
7263        final int targetUid;
7264        final int flags;
7265
7266        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7267            this.targetPkg = targetPkg;
7268            this.targetUid = targetUid;
7269            this.flags = flags;
7270        }
7271    }
7272
7273    /**
7274     * Like checkGrantUriPermissionLocked, but takes an Intent.
7275     */
7276    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7277            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7278        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7279                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7280                + " clip=" + (intent != null ? intent.getClipData() : null)
7281                + " from " + intent + "; flags=0x"
7282                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7283
7284        if (targetPkg == null) {
7285            throw new NullPointerException("targetPkg");
7286        }
7287
7288        if (intent == null) {
7289            return null;
7290        }
7291        Uri data = intent.getData();
7292        ClipData clip = intent.getClipData();
7293        if (data == null && clip == null) {
7294            return null;
7295        }
7296        // Default userId for uris in the intent (if they don't specify it themselves)
7297        int contentUserHint = intent.getContentUserHint();
7298        if (contentUserHint == UserHandle.USER_CURRENT) {
7299            contentUserHint = UserHandle.getUserId(callingUid);
7300        }
7301        final IPackageManager pm = AppGlobals.getPackageManager();
7302        int targetUid;
7303        if (needed != null) {
7304            targetUid = needed.targetUid;
7305        } else {
7306            try {
7307                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7308            } catch (RemoteException ex) {
7309                return null;
7310            }
7311            if (targetUid < 0) {
7312                if (DEBUG_URI_PERMISSION) {
7313                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7314                            + " on user " + targetUserId);
7315                }
7316                return null;
7317            }
7318        }
7319        if (data != null) {
7320            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7321            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7322                    targetUid);
7323            if (targetUid > 0) {
7324                if (needed == null) {
7325                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7326                }
7327                needed.add(grantUri);
7328            }
7329        }
7330        if (clip != null) {
7331            for (int i=0; i<clip.getItemCount(); i++) {
7332                Uri uri = clip.getItemAt(i).getUri();
7333                if (uri != null) {
7334                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7335                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7336                            targetUid);
7337                    if (targetUid > 0) {
7338                        if (needed == null) {
7339                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7340                        }
7341                        needed.add(grantUri);
7342                    }
7343                } else {
7344                    Intent clipIntent = clip.getItemAt(i).getIntent();
7345                    if (clipIntent != null) {
7346                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7347                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7348                        if (newNeeded != null) {
7349                            needed = newNeeded;
7350                        }
7351                    }
7352                }
7353            }
7354        }
7355
7356        return needed;
7357    }
7358
7359    /**
7360     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7361     */
7362    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7363            UriPermissionOwner owner) {
7364        if (needed != null) {
7365            for (int i=0; i<needed.size(); i++) {
7366                GrantUri grantUri = needed.get(i);
7367                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7368                        grantUri, needed.flags, owner);
7369            }
7370        }
7371    }
7372
7373    void grantUriPermissionFromIntentLocked(int callingUid,
7374            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7375        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7376                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7377        if (needed == null) {
7378            return;
7379        }
7380
7381        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7382    }
7383
7384    /**
7385     * @param uri This uri must NOT contain an embedded userId.
7386     * @param userId The userId in which the uri is to be resolved.
7387     */
7388    @Override
7389    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7390            final int modeFlags, int userId) {
7391        enforceNotIsolatedCaller("grantUriPermission");
7392        GrantUri grantUri = new GrantUri(userId, uri, false);
7393        synchronized(this) {
7394            final ProcessRecord r = getRecordForAppLocked(caller);
7395            if (r == null) {
7396                throw new SecurityException("Unable to find app for caller "
7397                        + caller
7398                        + " when granting permission to uri " + grantUri);
7399            }
7400            if (targetPkg == null) {
7401                throw new IllegalArgumentException("null target");
7402            }
7403            if (grantUri == null) {
7404                throw new IllegalArgumentException("null uri");
7405            }
7406
7407            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7408                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7409                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7410                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7411
7412            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7413                    UserHandle.getUserId(r.uid));
7414        }
7415    }
7416
7417    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7418        if (perm.modeFlags == 0) {
7419            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7420                    perm.targetUid);
7421            if (perms != null) {
7422                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7423                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7424
7425                perms.remove(perm.uri);
7426                if (perms.isEmpty()) {
7427                    mGrantedUriPermissions.remove(perm.targetUid);
7428                }
7429            }
7430        }
7431    }
7432
7433    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7434        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7435
7436        final IPackageManager pm = AppGlobals.getPackageManager();
7437        final String authority = grantUri.uri.getAuthority();
7438        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7439        if (pi == null) {
7440            Slog.w(TAG, "No content provider found for permission revoke: "
7441                    + grantUri.toSafeString());
7442            return;
7443        }
7444
7445        // Does the caller have this permission on the URI?
7446        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7447            // If they don't have direct access to the URI, then revoke any
7448            // ownerless URI permissions that have been granted to them.
7449            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7450            if (perms != null) {
7451                boolean persistChanged = false;
7452                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7453                    final UriPermission perm = it.next();
7454                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7455                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7456                        if (DEBUG_URI_PERMISSION)
7457                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7458                                    " permission to " + perm.uri);
7459                        persistChanged |= perm.revokeModes(
7460                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7461                        if (perm.modeFlags == 0) {
7462                            it.remove();
7463                        }
7464                    }
7465                }
7466                if (perms.isEmpty()) {
7467                    mGrantedUriPermissions.remove(callingUid);
7468                }
7469                if (persistChanged) {
7470                    schedulePersistUriGrants();
7471                }
7472            }
7473            return;
7474        }
7475
7476        boolean persistChanged = false;
7477
7478        // Go through all of the permissions and remove any that match.
7479        int N = mGrantedUriPermissions.size();
7480        for (int i = 0; i < N; i++) {
7481            final int targetUid = mGrantedUriPermissions.keyAt(i);
7482            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7483
7484            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7485                final UriPermission perm = it.next();
7486                if (perm.uri.sourceUserId == grantUri.sourceUserId
7487                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7488                    if (DEBUG_URI_PERMISSION)
7489                        Slog.v(TAG,
7490                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7491                    persistChanged |= perm.revokeModes(
7492                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7493                    if (perm.modeFlags == 0) {
7494                        it.remove();
7495                    }
7496                }
7497            }
7498
7499            if (perms.isEmpty()) {
7500                mGrantedUriPermissions.remove(targetUid);
7501                N--;
7502                i--;
7503            }
7504        }
7505
7506        if (persistChanged) {
7507            schedulePersistUriGrants();
7508        }
7509    }
7510
7511    /**
7512     * @param uri This uri must NOT contain an embedded userId.
7513     * @param userId The userId in which the uri is to be resolved.
7514     */
7515    @Override
7516    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7517            int userId) {
7518        enforceNotIsolatedCaller("revokeUriPermission");
7519        synchronized(this) {
7520            final ProcessRecord r = getRecordForAppLocked(caller);
7521            if (r == null) {
7522                throw new SecurityException("Unable to find app for caller "
7523                        + caller
7524                        + " when revoking permission to uri " + uri);
7525            }
7526            if (uri == null) {
7527                Slog.w(TAG, "revokeUriPermission: null uri");
7528                return;
7529            }
7530
7531            if (!Intent.isAccessUriMode(modeFlags)) {
7532                return;
7533            }
7534
7535            final IPackageManager pm = AppGlobals.getPackageManager();
7536            final String authority = uri.getAuthority();
7537            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7538            if (pi == null) {
7539                Slog.w(TAG, "No content provider found for permission revoke: "
7540                        + uri.toSafeString());
7541                return;
7542            }
7543
7544            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7545        }
7546    }
7547
7548    /**
7549     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7550     * given package.
7551     *
7552     * @param packageName Package name to match, or {@code null} to apply to all
7553     *            packages.
7554     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7555     *            to all users.
7556     * @param persistable If persistable grants should be removed.
7557     */
7558    private void removeUriPermissionsForPackageLocked(
7559            String packageName, int userHandle, boolean persistable) {
7560        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7561            throw new IllegalArgumentException("Must narrow by either package or user");
7562        }
7563
7564        boolean persistChanged = false;
7565
7566        int N = mGrantedUriPermissions.size();
7567        for (int i = 0; i < N; i++) {
7568            final int targetUid = mGrantedUriPermissions.keyAt(i);
7569            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7570
7571            // Only inspect grants matching user
7572            if (userHandle == UserHandle.USER_ALL
7573                    || userHandle == UserHandle.getUserId(targetUid)) {
7574                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7575                    final UriPermission perm = it.next();
7576
7577                    // Only inspect grants matching package
7578                    if (packageName == null || perm.sourcePkg.equals(packageName)
7579                            || perm.targetPkg.equals(packageName)) {
7580                        persistChanged |= perm.revokeModes(persistable
7581                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7582
7583                        // Only remove when no modes remain; any persisted grants
7584                        // will keep this alive.
7585                        if (perm.modeFlags == 0) {
7586                            it.remove();
7587                        }
7588                    }
7589                }
7590
7591                if (perms.isEmpty()) {
7592                    mGrantedUriPermissions.remove(targetUid);
7593                    N--;
7594                    i--;
7595                }
7596            }
7597        }
7598
7599        if (persistChanged) {
7600            schedulePersistUriGrants();
7601        }
7602    }
7603
7604    @Override
7605    public IBinder newUriPermissionOwner(String name) {
7606        enforceNotIsolatedCaller("newUriPermissionOwner");
7607        synchronized(this) {
7608            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7609            return owner.getExternalTokenLocked();
7610        }
7611    }
7612
7613    /**
7614     * @param uri This uri must NOT contain an embedded userId.
7615     * @param sourceUserId The userId in which the uri is to be resolved.
7616     * @param targetUserId The userId of the app that receives the grant.
7617     */
7618    @Override
7619    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7620            final int modeFlags, int sourceUserId, int targetUserId) {
7621        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7622                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7623        synchronized(this) {
7624            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7625            if (owner == null) {
7626                throw new IllegalArgumentException("Unknown owner: " + token);
7627            }
7628            if (fromUid != Binder.getCallingUid()) {
7629                if (Binder.getCallingUid() != Process.myUid()) {
7630                    // Only system code can grant URI permissions on behalf
7631                    // of other users.
7632                    throw new SecurityException("nice try");
7633                }
7634            }
7635            if (targetPkg == null) {
7636                throw new IllegalArgumentException("null target");
7637            }
7638            if (uri == null) {
7639                throw new IllegalArgumentException("null uri");
7640            }
7641
7642            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7643                    modeFlags, owner, targetUserId);
7644        }
7645    }
7646
7647    /**
7648     * @param uri This uri must NOT contain an embedded userId.
7649     * @param userId The userId in which the uri is to be resolved.
7650     */
7651    @Override
7652    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7653        synchronized(this) {
7654            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7655            if (owner == null) {
7656                throw new IllegalArgumentException("Unknown owner: " + token);
7657            }
7658
7659            if (uri == null) {
7660                owner.removeUriPermissionsLocked(mode);
7661            } else {
7662                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7663            }
7664        }
7665    }
7666
7667    private void schedulePersistUriGrants() {
7668        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7669            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7670                    10 * DateUtils.SECOND_IN_MILLIS);
7671        }
7672    }
7673
7674    private void writeGrantedUriPermissions() {
7675        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7676
7677        // Snapshot permissions so we can persist without lock
7678        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7679        synchronized (this) {
7680            final int size = mGrantedUriPermissions.size();
7681            for (int i = 0; i < size; i++) {
7682                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7683                for (UriPermission perm : perms.values()) {
7684                    if (perm.persistedModeFlags != 0) {
7685                        persist.add(perm.snapshot());
7686                    }
7687                }
7688            }
7689        }
7690
7691        FileOutputStream fos = null;
7692        try {
7693            fos = mGrantFile.startWrite();
7694
7695            XmlSerializer out = new FastXmlSerializer();
7696            out.setOutput(fos, "utf-8");
7697            out.startDocument(null, true);
7698            out.startTag(null, TAG_URI_GRANTS);
7699            for (UriPermission.Snapshot perm : persist) {
7700                out.startTag(null, TAG_URI_GRANT);
7701                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7702                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7703                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7704                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7705                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7706                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7707                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7708                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7709                out.endTag(null, TAG_URI_GRANT);
7710            }
7711            out.endTag(null, TAG_URI_GRANTS);
7712            out.endDocument();
7713
7714            mGrantFile.finishWrite(fos);
7715        } catch (IOException e) {
7716            if (fos != null) {
7717                mGrantFile.failWrite(fos);
7718            }
7719        }
7720    }
7721
7722    private void readGrantedUriPermissionsLocked() {
7723        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7724
7725        final long now = System.currentTimeMillis();
7726
7727        FileInputStream fis = null;
7728        try {
7729            fis = mGrantFile.openRead();
7730            final XmlPullParser in = Xml.newPullParser();
7731            in.setInput(fis, null);
7732
7733            int type;
7734            while ((type = in.next()) != END_DOCUMENT) {
7735                final String tag = in.getName();
7736                if (type == START_TAG) {
7737                    if (TAG_URI_GRANT.equals(tag)) {
7738                        final int sourceUserId;
7739                        final int targetUserId;
7740                        final int userHandle = readIntAttribute(in,
7741                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7742                        if (userHandle != UserHandle.USER_NULL) {
7743                            // For backwards compatibility.
7744                            sourceUserId = userHandle;
7745                            targetUserId = userHandle;
7746                        } else {
7747                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7748                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7749                        }
7750                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7751                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7752                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7753                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7754                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7755                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7756
7757                        // Sanity check that provider still belongs to source package
7758                        final ProviderInfo pi = getProviderInfoLocked(
7759                                uri.getAuthority(), sourceUserId);
7760                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7761                            int targetUid = -1;
7762                            try {
7763                                targetUid = AppGlobals.getPackageManager()
7764                                        .getPackageUid(targetPkg, targetUserId);
7765                            } catch (RemoteException e) {
7766                            }
7767                            if (targetUid != -1) {
7768                                final UriPermission perm = findOrCreateUriPermissionLocked(
7769                                        sourcePkg, targetPkg, targetUid,
7770                                        new GrantUri(sourceUserId, uri, prefix));
7771                                perm.initPersistedModes(modeFlags, createdTime);
7772                            }
7773                        } else {
7774                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7775                                    + " but instead found " + pi);
7776                        }
7777                    }
7778                }
7779            }
7780        } catch (FileNotFoundException e) {
7781            // Missing grants is okay
7782        } catch (IOException e) {
7783            Slog.wtf(TAG, "Failed reading Uri grants", e);
7784        } catch (XmlPullParserException e) {
7785            Slog.wtf(TAG, "Failed reading Uri grants", e);
7786        } finally {
7787            IoUtils.closeQuietly(fis);
7788        }
7789    }
7790
7791    /**
7792     * @param uri This uri must NOT contain an embedded userId.
7793     * @param userId The userId in which the uri is to be resolved.
7794     */
7795    @Override
7796    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7797        enforceNotIsolatedCaller("takePersistableUriPermission");
7798
7799        Preconditions.checkFlagsArgument(modeFlags,
7800                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7801
7802        synchronized (this) {
7803            final int callingUid = Binder.getCallingUid();
7804            boolean persistChanged = false;
7805            GrantUri grantUri = new GrantUri(userId, uri, false);
7806
7807            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7808                    new GrantUri(userId, uri, false));
7809            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7810                    new GrantUri(userId, uri, true));
7811
7812            final boolean exactValid = (exactPerm != null)
7813                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7814            final boolean prefixValid = (prefixPerm != null)
7815                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7816
7817            if (!(exactValid || prefixValid)) {
7818                throw new SecurityException("No persistable permission grants found for UID "
7819                        + callingUid + " and Uri " + grantUri.toSafeString());
7820            }
7821
7822            if (exactValid) {
7823                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7824            }
7825            if (prefixValid) {
7826                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7827            }
7828
7829            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7830
7831            if (persistChanged) {
7832                schedulePersistUriGrants();
7833            }
7834        }
7835    }
7836
7837    /**
7838     * @param uri This uri must NOT contain an embedded userId.
7839     * @param userId The userId in which the uri is to be resolved.
7840     */
7841    @Override
7842    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7843        enforceNotIsolatedCaller("releasePersistableUriPermission");
7844
7845        Preconditions.checkFlagsArgument(modeFlags,
7846                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7847
7848        synchronized (this) {
7849            final int callingUid = Binder.getCallingUid();
7850            boolean persistChanged = false;
7851
7852            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7853                    new GrantUri(userId, uri, false));
7854            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7855                    new GrantUri(userId, uri, true));
7856            if (exactPerm == null && prefixPerm == null) {
7857                throw new SecurityException("No permission grants found for UID " + callingUid
7858                        + " and Uri " + uri.toSafeString());
7859            }
7860
7861            if (exactPerm != null) {
7862                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7863                removeUriPermissionIfNeededLocked(exactPerm);
7864            }
7865            if (prefixPerm != null) {
7866                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7867                removeUriPermissionIfNeededLocked(prefixPerm);
7868            }
7869
7870            if (persistChanged) {
7871                schedulePersistUriGrants();
7872            }
7873        }
7874    }
7875
7876    /**
7877     * Prune any older {@link UriPermission} for the given UID until outstanding
7878     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7879     *
7880     * @return if any mutations occured that require persisting.
7881     */
7882    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7883        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7884        if (perms == null) return false;
7885        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7886
7887        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7888        for (UriPermission perm : perms.values()) {
7889            if (perm.persistedModeFlags != 0) {
7890                persisted.add(perm);
7891            }
7892        }
7893
7894        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7895        if (trimCount <= 0) return false;
7896
7897        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7898        for (int i = 0; i < trimCount; i++) {
7899            final UriPermission perm = persisted.get(i);
7900
7901            if (DEBUG_URI_PERMISSION) {
7902                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7903            }
7904
7905            perm.releasePersistableModes(~0);
7906            removeUriPermissionIfNeededLocked(perm);
7907        }
7908
7909        return true;
7910    }
7911
7912    @Override
7913    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7914            String packageName, boolean incoming) {
7915        enforceNotIsolatedCaller("getPersistedUriPermissions");
7916        Preconditions.checkNotNull(packageName, "packageName");
7917
7918        final int callingUid = Binder.getCallingUid();
7919        final IPackageManager pm = AppGlobals.getPackageManager();
7920        try {
7921            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7922            if (packageUid != callingUid) {
7923                throw new SecurityException(
7924                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7925            }
7926        } catch (RemoteException e) {
7927            throw new SecurityException("Failed to verify package name ownership");
7928        }
7929
7930        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7931        synchronized (this) {
7932            if (incoming) {
7933                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7934                        callingUid);
7935                if (perms == null) {
7936                    Slog.w(TAG, "No permission grants found for " + packageName);
7937                } else {
7938                    for (UriPermission perm : perms.values()) {
7939                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7940                            result.add(perm.buildPersistedPublicApiObject());
7941                        }
7942                    }
7943                }
7944            } else {
7945                final int size = mGrantedUriPermissions.size();
7946                for (int i = 0; i < size; i++) {
7947                    final ArrayMap<GrantUri, UriPermission> perms =
7948                            mGrantedUriPermissions.valueAt(i);
7949                    for (UriPermission perm : perms.values()) {
7950                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7951                            result.add(perm.buildPersistedPublicApiObject());
7952                        }
7953                    }
7954                }
7955            }
7956        }
7957        return new ParceledListSlice<android.content.UriPermission>(result);
7958    }
7959
7960    @Override
7961    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7962        synchronized (this) {
7963            ProcessRecord app =
7964                who != null ? getRecordForAppLocked(who) : null;
7965            if (app == null) return;
7966
7967            Message msg = Message.obtain();
7968            msg.what = WAIT_FOR_DEBUGGER_MSG;
7969            msg.obj = app;
7970            msg.arg1 = waiting ? 1 : 0;
7971            mHandler.sendMessage(msg);
7972        }
7973    }
7974
7975    @Override
7976    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7977        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7978        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7979        outInfo.availMem = Process.getFreeMemory();
7980        outInfo.totalMem = Process.getTotalMemory();
7981        outInfo.threshold = homeAppMem;
7982        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7983        outInfo.hiddenAppThreshold = cachedAppMem;
7984        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7985                ProcessList.SERVICE_ADJ);
7986        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7987                ProcessList.VISIBLE_APP_ADJ);
7988        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7989                ProcessList.FOREGROUND_APP_ADJ);
7990    }
7991
7992    // =========================================================
7993    // TASK MANAGEMENT
7994    // =========================================================
7995
7996    @Override
7997    public List<IAppTask> getAppTasks(String callingPackage) {
7998        int callingUid = Binder.getCallingUid();
7999        long ident = Binder.clearCallingIdentity();
8000
8001        synchronized(this) {
8002            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8003            try {
8004                if (localLOGV) Slog.v(TAG, "getAppTasks");
8005
8006                final int N = mRecentTasks.size();
8007                for (int i = 0; i < N; i++) {
8008                    TaskRecord tr = mRecentTasks.get(i);
8009                    // Skip tasks that do not match the caller.  We don't need to verify
8010                    // callingPackage, because we are also limiting to callingUid and know
8011                    // that will limit to the correct security sandbox.
8012                    if (tr.effectiveUid != callingUid) {
8013                        continue;
8014                    }
8015                    Intent intent = tr.getBaseIntent();
8016                    if (intent == null ||
8017                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8018                        continue;
8019                    }
8020                    ActivityManager.RecentTaskInfo taskInfo =
8021                            createRecentTaskInfoFromTaskRecord(tr);
8022                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8023                    list.add(taskImpl);
8024                }
8025            } finally {
8026                Binder.restoreCallingIdentity(ident);
8027            }
8028            return list;
8029        }
8030    }
8031
8032    @Override
8033    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8034        final int callingUid = Binder.getCallingUid();
8035        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8036
8037        synchronized(this) {
8038            if (localLOGV) Slog.v(
8039                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8040
8041            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8042                    callingUid);
8043
8044            // TODO: Improve with MRU list from all ActivityStacks.
8045            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8046        }
8047
8048        return list;
8049    }
8050
8051    TaskRecord getMostRecentTask() {
8052        return mRecentTasks.get(0);
8053    }
8054
8055    /**
8056     * Creates a new RecentTaskInfo from a TaskRecord.
8057     */
8058    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8059        // Update the task description to reflect any changes in the task stack
8060        tr.updateTaskDescription();
8061
8062        // Compose the recent task info
8063        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8064        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8065        rti.persistentId = tr.taskId;
8066        rti.baseIntent = new Intent(tr.getBaseIntent());
8067        rti.origActivity = tr.origActivity;
8068        rti.description = tr.lastDescription;
8069        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8070        rti.userId = tr.userId;
8071        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8072        rti.firstActiveTime = tr.firstActiveTime;
8073        rti.lastActiveTime = tr.lastActiveTime;
8074        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8075        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8076        return rti;
8077    }
8078
8079    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8080        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8081                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8082        if (!allowed) {
8083            if (checkPermission(android.Manifest.permission.GET_TASKS,
8084                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8085                // Temporary compatibility: some existing apps on the system image may
8086                // still be requesting the old permission and not switched to the new
8087                // one; if so, we'll still allow them full access.  This means we need
8088                // to see if they are holding the old permission and are a system app.
8089                try {
8090                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8091                        allowed = true;
8092                        Slog.w(TAG, caller + ": caller " + callingUid
8093                                + " is using old GET_TASKS but privileged; allowing");
8094                    }
8095                } catch (RemoteException e) {
8096                }
8097            }
8098        }
8099        if (!allowed) {
8100            Slog.w(TAG, caller + ": caller " + callingUid
8101                    + " does not hold GET_TASKS; limiting output");
8102        }
8103        return allowed;
8104    }
8105
8106    @Override
8107    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8108        final int callingUid = Binder.getCallingUid();
8109        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8110                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8111
8112        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8113        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8114        synchronized (this) {
8115            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8116                    callingUid);
8117            final boolean detailed = checkCallingPermission(
8118                    android.Manifest.permission.GET_DETAILED_TASKS)
8119                    == PackageManager.PERMISSION_GRANTED;
8120
8121            final int N = mRecentTasks.size();
8122            ArrayList<ActivityManager.RecentTaskInfo> res
8123                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8124                            maxNum < N ? maxNum : N);
8125
8126            final Set<Integer> includedUsers;
8127            if (includeProfiles) {
8128                includedUsers = getProfileIdsLocked(userId);
8129            } else {
8130                includedUsers = new HashSet<Integer>();
8131            }
8132            includedUsers.add(Integer.valueOf(userId));
8133
8134            for (int i=0; i<N && maxNum > 0; i++) {
8135                TaskRecord tr = mRecentTasks.get(i);
8136                // Only add calling user or related users recent tasks
8137                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8138                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8139                    continue;
8140                }
8141
8142                // Return the entry if desired by the caller.  We always return
8143                // the first entry, because callers always expect this to be the
8144                // foreground app.  We may filter others if the caller has
8145                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8146                // we should exclude the entry.
8147
8148                if (i == 0
8149                        || withExcluded
8150                        || (tr.intent == null)
8151                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8152                                == 0)) {
8153                    if (!allowed) {
8154                        // If the caller doesn't have the GET_TASKS permission, then only
8155                        // allow them to see a small subset of tasks -- their own and home.
8156                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8157                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8158                            continue;
8159                        }
8160                    }
8161                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8162                        if (tr.stack != null && tr.stack.isHomeStack()) {
8163                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8164                            continue;
8165                        }
8166                    }
8167                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8168                        // Don't include auto remove tasks that are finished or finishing.
8169                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8170                                + tr);
8171                        continue;
8172                    }
8173                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8174                            && !tr.isAvailable) {
8175                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8176                        continue;
8177                    }
8178
8179                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8180                    if (!detailed) {
8181                        rti.baseIntent.replaceExtras((Bundle)null);
8182                    }
8183
8184                    res.add(rti);
8185                    maxNum--;
8186                }
8187            }
8188            return res;
8189        }
8190    }
8191
8192    private TaskRecord taskForIdLocked(int id) {
8193        final TaskRecord task = recentTaskForIdLocked(id);
8194        if (task != null) {
8195            return task;
8196        }
8197
8198        // Don't give up. Sometimes it just hasn't made it to recents yet.
8199        return mStackSupervisor.anyTaskForIdLocked(id);
8200    }
8201
8202    private TaskRecord recentTaskForIdLocked(int id) {
8203        final int N = mRecentTasks.size();
8204            for (int i=0; i<N; i++) {
8205                TaskRecord tr = mRecentTasks.get(i);
8206                if (tr.taskId == id) {
8207                    return tr;
8208                }
8209            }
8210            return null;
8211    }
8212
8213    @Override
8214    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8215        synchronized (this) {
8216            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8217                    "getTaskThumbnail()");
8218            TaskRecord tr = recentTaskForIdLocked(id);
8219            if (tr != null) {
8220                return tr.getTaskThumbnailLocked();
8221            }
8222        }
8223        return null;
8224    }
8225
8226    @Override
8227    public int addAppTask(IBinder activityToken, Intent intent,
8228            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8229        final int callingUid = Binder.getCallingUid();
8230        final long callingIdent = Binder.clearCallingIdentity();
8231
8232        try {
8233            synchronized (this) {
8234                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8235                if (r == null) {
8236                    throw new IllegalArgumentException("Activity does not exist; token="
8237                            + activityToken);
8238                }
8239                ComponentName comp = intent.getComponent();
8240                if (comp == null) {
8241                    throw new IllegalArgumentException("Intent " + intent
8242                            + " must specify explicit component");
8243                }
8244                if (thumbnail.getWidth() != mThumbnailWidth
8245                        || thumbnail.getHeight() != mThumbnailHeight) {
8246                    throw new IllegalArgumentException("Bad thumbnail size: got "
8247                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8248                            + mThumbnailWidth + "x" + mThumbnailHeight);
8249                }
8250                if (intent.getSelector() != null) {
8251                    intent.setSelector(null);
8252                }
8253                if (intent.getSourceBounds() != null) {
8254                    intent.setSourceBounds(null);
8255                }
8256                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8257                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8258                        // The caller has added this as an auto-remove task...  that makes no
8259                        // sense, so turn off auto-remove.
8260                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8261                    }
8262                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8263                    // Must be a new task.
8264                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8265                }
8266                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8267                    mLastAddedTaskActivity = null;
8268                }
8269                ActivityInfo ainfo = mLastAddedTaskActivity;
8270                if (ainfo == null) {
8271                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8272                            comp, 0, UserHandle.getUserId(callingUid));
8273                    if (ainfo.applicationInfo.uid != callingUid) {
8274                        throw new SecurityException(
8275                                "Can't add task for another application: target uid="
8276                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8277                    }
8278                }
8279
8280                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8281                        intent, description);
8282
8283                int trimIdx = trimRecentsForTask(task, false);
8284                if (trimIdx >= 0) {
8285                    // If this would have caused a trim, then we'll abort because that
8286                    // means it would be added at the end of the list but then just removed.
8287                    return -1;
8288                }
8289
8290                final int N = mRecentTasks.size();
8291                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8292                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8293                    tr.removedFromRecents(mTaskPersister);
8294                }
8295
8296                task.inRecents = true;
8297                mRecentTasks.add(task);
8298                r.task.stack.addTask(task, false, false);
8299
8300                task.setLastThumbnail(thumbnail);
8301                task.freeLastThumbnail();
8302
8303                return task.taskId;
8304            }
8305        } finally {
8306            Binder.restoreCallingIdentity(callingIdent);
8307        }
8308    }
8309
8310    @Override
8311    public Point getAppTaskThumbnailSize() {
8312        synchronized (this) {
8313            return new Point(mThumbnailWidth,  mThumbnailHeight);
8314        }
8315    }
8316
8317    @Override
8318    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8319        synchronized (this) {
8320            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8321            if (r != null) {
8322                r.setTaskDescription(td);
8323                r.task.updateTaskDescription();
8324            }
8325        }
8326    }
8327
8328    @Override
8329    public Bitmap getTaskDescriptionIcon(String filename) {
8330        if (!FileUtils.isValidExtFilename(filename)
8331                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8332            throw new IllegalArgumentException("Bad filename: " + filename);
8333        }
8334        return mTaskPersister.getTaskDescriptionIcon(filename);
8335    }
8336
8337    @Override
8338    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8339            throws RemoteException {
8340        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8341                opts.getCustomInPlaceResId() == 0) {
8342            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8343                    "with valid animation");
8344        }
8345        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8346        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8347                opts.getCustomInPlaceResId());
8348        mWindowManager.executeAppTransition();
8349    }
8350
8351    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8352        mRecentTasks.remove(tr);
8353        tr.removedFromRecents(mTaskPersister);
8354        ComponentName component = tr.getBaseIntent().getComponent();
8355        if (component == null) {
8356            Slog.w(TAG, "No component for base intent of task: " + tr);
8357            return;
8358        }
8359
8360        if (!killProcess) {
8361            return;
8362        }
8363
8364        // Determine if the process(es) for this task should be killed.
8365        final String pkg = component.getPackageName();
8366        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8367        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8368        for (int i = 0; i < pmap.size(); i++) {
8369
8370            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8371            for (int j = 0; j < uids.size(); j++) {
8372                ProcessRecord proc = uids.valueAt(j);
8373                if (proc.userId != tr.userId) {
8374                    // Don't kill process for a different user.
8375                    continue;
8376                }
8377                if (proc == mHomeProcess) {
8378                    // Don't kill the home process along with tasks from the same package.
8379                    continue;
8380                }
8381                if (!proc.pkgList.containsKey(pkg)) {
8382                    // Don't kill process that is not associated with this task.
8383                    continue;
8384                }
8385
8386                for (int k = 0; k < proc.activities.size(); k++) {
8387                    TaskRecord otherTask = proc.activities.get(k).task;
8388                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8389                        // Don't kill process(es) that has an activity in a different task that is
8390                        // also in recents.
8391                        return;
8392                    }
8393                }
8394
8395                // Add process to kill list.
8396                procsToKill.add(proc);
8397            }
8398        }
8399
8400        // Find any running services associated with this app and stop if needed.
8401        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8402
8403        // Kill the running processes.
8404        for (int i = 0; i < procsToKill.size(); i++) {
8405            ProcessRecord pr = procsToKill.get(i);
8406            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8407                pr.kill("remove task", true);
8408            } else {
8409                pr.waitingToKill = "remove task";
8410            }
8411        }
8412    }
8413
8414    /**
8415     * Removes the task with the specified task id.
8416     *
8417     * @param taskId Identifier of the task to be removed.
8418     * @param killProcess Kill any process associated with the task if possible.
8419     * @return Returns true if the given task was found and removed.
8420     */
8421    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8422        TaskRecord tr = taskForIdLocked(taskId);
8423        if (tr != null) {
8424            tr.removeTaskActivitiesLocked();
8425            cleanUpRemovedTaskLocked(tr, killProcess);
8426            if (tr.isPersistable) {
8427                notifyTaskPersisterLocked(null, true);
8428            }
8429            return true;
8430        }
8431        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8432        return false;
8433    }
8434
8435    @Override
8436    public boolean removeTask(int taskId) {
8437        synchronized (this) {
8438            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8439                    "removeTask()");
8440            long ident = Binder.clearCallingIdentity();
8441            try {
8442                return removeTaskByIdLocked(taskId, true);
8443            } finally {
8444                Binder.restoreCallingIdentity(ident);
8445            }
8446        }
8447    }
8448
8449    /**
8450     * TODO: Add mController hook
8451     */
8452    @Override
8453    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8454        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8455                "moveTaskToFront()");
8456
8457        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8458        synchronized(this) {
8459            moveTaskToFrontLocked(taskId, flags, options);
8460        }
8461    }
8462
8463    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8464        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8465                Binder.getCallingUid(), -1, -1, "Task to front")) {
8466            ActivityOptions.abort(options);
8467            return;
8468        }
8469        final long origId = Binder.clearCallingIdentity();
8470        try {
8471            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8472            if (task == null) {
8473                Slog.d(TAG, "Could not find task for id: "+ taskId);
8474                return;
8475            }
8476            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8477                mStackSupervisor.showLockTaskToast();
8478                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8479                return;
8480            }
8481            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8482            if (prev != null && prev.isRecentsActivity()) {
8483                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8484            }
8485            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8486        } finally {
8487            Binder.restoreCallingIdentity(origId);
8488        }
8489        ActivityOptions.abort(options);
8490    }
8491
8492    @Override
8493    public void moveTaskToBack(int taskId) {
8494        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8495                "moveTaskToBack()");
8496
8497        synchronized(this) {
8498            TaskRecord tr = taskForIdLocked(taskId);
8499            if (tr != null) {
8500                if (tr == mStackSupervisor.mLockTaskModeTask) {
8501                    mStackSupervisor.showLockTaskToast();
8502                    return;
8503                }
8504                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8505                ActivityStack stack = tr.stack;
8506                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8507                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8508                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8509                        return;
8510                    }
8511                }
8512                final long origId = Binder.clearCallingIdentity();
8513                try {
8514                    stack.moveTaskToBackLocked(taskId, null);
8515                } finally {
8516                    Binder.restoreCallingIdentity(origId);
8517                }
8518            }
8519        }
8520    }
8521
8522    /**
8523     * Moves an activity, and all of the other activities within the same task, to the bottom
8524     * of the history stack.  The activity's order within the task is unchanged.
8525     *
8526     * @param token A reference to the activity we wish to move
8527     * @param nonRoot If false then this only works if the activity is the root
8528     *                of a task; if true it will work for any activity in a task.
8529     * @return Returns true if the move completed, false if not.
8530     */
8531    @Override
8532    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8533        enforceNotIsolatedCaller("moveActivityTaskToBack");
8534        synchronized(this) {
8535            final long origId = Binder.clearCallingIdentity();
8536            try {
8537                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8538                if (taskId >= 0) {
8539                    if ((mStackSupervisor.mLockTaskModeTask != null)
8540                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8541                        mStackSupervisor.showLockTaskToast();
8542                        return false;
8543                    }
8544                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8545                }
8546            } finally {
8547                Binder.restoreCallingIdentity(origId);
8548            }
8549        }
8550        return false;
8551    }
8552
8553    @Override
8554    public void moveTaskBackwards(int task) {
8555        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8556                "moveTaskBackwards()");
8557
8558        synchronized(this) {
8559            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8560                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8561                return;
8562            }
8563            final long origId = Binder.clearCallingIdentity();
8564            moveTaskBackwardsLocked(task);
8565            Binder.restoreCallingIdentity(origId);
8566        }
8567    }
8568
8569    private final void moveTaskBackwardsLocked(int task) {
8570        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8571    }
8572
8573    @Override
8574    public IBinder getHomeActivityToken() throws RemoteException {
8575        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8576                "getHomeActivityToken()");
8577        synchronized (this) {
8578            return mStackSupervisor.getHomeActivityToken();
8579        }
8580    }
8581
8582    @Override
8583    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8584            IActivityContainerCallback callback) throws RemoteException {
8585        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8586                "createActivityContainer()");
8587        synchronized (this) {
8588            if (parentActivityToken == null) {
8589                throw new IllegalArgumentException("parent token must not be null");
8590            }
8591            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8592            if (r == null) {
8593                return null;
8594            }
8595            if (callback == null) {
8596                throw new IllegalArgumentException("callback must not be null");
8597            }
8598            return mStackSupervisor.createActivityContainer(r, callback);
8599        }
8600    }
8601
8602    @Override
8603    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8604        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8605                "deleteActivityContainer()");
8606        synchronized (this) {
8607            mStackSupervisor.deleteActivityContainer(container);
8608        }
8609    }
8610
8611    @Override
8612    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8613            throws RemoteException {
8614        synchronized (this) {
8615            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8616            if (stack != null) {
8617                return stack.mActivityContainer;
8618            }
8619            return null;
8620        }
8621    }
8622
8623    @Override
8624    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8625        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8626                "moveTaskToStack()");
8627        if (stackId == HOME_STACK_ID) {
8628            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8629                    new RuntimeException("here").fillInStackTrace());
8630        }
8631        synchronized (this) {
8632            long ident = Binder.clearCallingIdentity();
8633            try {
8634                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8635                        + stackId + " toTop=" + toTop);
8636                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8637            } finally {
8638                Binder.restoreCallingIdentity(ident);
8639            }
8640        }
8641    }
8642
8643    @Override
8644    public void resizeStack(int stackBoxId, Rect bounds) {
8645        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8646                "resizeStackBox()");
8647        long ident = Binder.clearCallingIdentity();
8648        try {
8649            mWindowManager.resizeStack(stackBoxId, bounds);
8650        } finally {
8651            Binder.restoreCallingIdentity(ident);
8652        }
8653    }
8654
8655    @Override
8656    public List<StackInfo> getAllStackInfos() {
8657        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8658                "getAllStackInfos()");
8659        long ident = Binder.clearCallingIdentity();
8660        try {
8661            synchronized (this) {
8662                return mStackSupervisor.getAllStackInfosLocked();
8663            }
8664        } finally {
8665            Binder.restoreCallingIdentity(ident);
8666        }
8667    }
8668
8669    @Override
8670    public StackInfo getStackInfo(int stackId) {
8671        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8672                "getStackInfo()");
8673        long ident = Binder.clearCallingIdentity();
8674        try {
8675            synchronized (this) {
8676                return mStackSupervisor.getStackInfoLocked(stackId);
8677            }
8678        } finally {
8679            Binder.restoreCallingIdentity(ident);
8680        }
8681    }
8682
8683    @Override
8684    public boolean isInHomeStack(int taskId) {
8685        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8686                "getStackInfo()");
8687        long ident = Binder.clearCallingIdentity();
8688        try {
8689            synchronized (this) {
8690                TaskRecord tr = taskForIdLocked(taskId);
8691                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8692            }
8693        } finally {
8694            Binder.restoreCallingIdentity(ident);
8695        }
8696    }
8697
8698    @Override
8699    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8700        synchronized(this) {
8701            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8702        }
8703    }
8704
8705    private boolean isLockTaskAuthorized(String pkg) {
8706        final DevicePolicyManager dpm = (DevicePolicyManager)
8707                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8708        try {
8709            int uid = mContext.getPackageManager().getPackageUid(pkg,
8710                    Binder.getCallingUserHandle().getIdentifier());
8711            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8712        } catch (NameNotFoundException e) {
8713            return false;
8714        }
8715    }
8716
8717    void startLockTaskMode(TaskRecord task) {
8718        final String pkg;
8719        synchronized (this) {
8720            pkg = task.intent.getComponent().getPackageName();
8721        }
8722        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8723        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8724            StatusBarManagerInternal statusBarManager = LocalServices.getService(
8725                    StatusBarManagerInternal.class);
8726            if (statusBarManager != null) {
8727                statusBarManager.showScreenPinningRequest();
8728            }
8729            return;
8730        }
8731        long ident = Binder.clearCallingIdentity();
8732        try {
8733            synchronized (this) {
8734                // Since we lost lock on task, make sure it is still there.
8735                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8736                if (task != null) {
8737                    if (!isSystemInitiated
8738                            && ((mStackSupervisor.getFocusedStack() == null)
8739                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8740                        throw new IllegalArgumentException("Invalid task, not in foreground");
8741                    }
8742                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8743                }
8744            }
8745        } finally {
8746            Binder.restoreCallingIdentity(ident);
8747        }
8748    }
8749
8750    @Override
8751    public void startLockTaskMode(int taskId) {
8752        final TaskRecord task;
8753        long ident = Binder.clearCallingIdentity();
8754        try {
8755            synchronized (this) {
8756                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8757            }
8758        } finally {
8759            Binder.restoreCallingIdentity(ident);
8760        }
8761        if (task != null) {
8762            startLockTaskMode(task);
8763        }
8764    }
8765
8766    @Override
8767    public void startLockTaskMode(IBinder token) {
8768        final TaskRecord task;
8769        long ident = Binder.clearCallingIdentity();
8770        try {
8771            synchronized (this) {
8772                final ActivityRecord r = ActivityRecord.forToken(token);
8773                if (r == null) {
8774                    return;
8775                }
8776                task = r.task;
8777            }
8778        } finally {
8779            Binder.restoreCallingIdentity(ident);
8780        }
8781        if (task != null) {
8782            startLockTaskMode(task);
8783        }
8784    }
8785
8786    @Override
8787    public void startLockTaskModeOnCurrent() throws RemoteException {
8788        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8789                "startLockTaskModeOnCurrent");
8790        long ident = Binder.clearCallingIdentity();
8791        try {
8792            ActivityRecord r = null;
8793            synchronized (this) {
8794                r = mStackSupervisor.topRunningActivityLocked();
8795            }
8796            startLockTaskMode(r.task);
8797        } finally {
8798            Binder.restoreCallingIdentity(ident);
8799        }
8800    }
8801
8802    @Override
8803    public void stopLockTaskMode() {
8804        // Verify that the user matches the package of the intent for the TaskRecord
8805        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8806        // and stopLockTaskMode.
8807        final int callingUid = Binder.getCallingUid();
8808        if (callingUid != Process.SYSTEM_UID) {
8809            try {
8810                String pkg =
8811                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8812                int uid = mContext.getPackageManager().getPackageUid(pkg,
8813                        Binder.getCallingUserHandle().getIdentifier());
8814                if (uid != callingUid) {
8815                    throw new SecurityException("Invalid uid, expected " + uid);
8816                }
8817            } catch (NameNotFoundException e) {
8818                Log.d(TAG, "stopLockTaskMode " + e);
8819                return;
8820            }
8821        }
8822        long ident = Binder.clearCallingIdentity();
8823        try {
8824            Log.d(TAG, "stopLockTaskMode");
8825            // Stop lock task
8826            synchronized (this) {
8827                mStackSupervisor.setLockTaskModeLocked(null, false);
8828            }
8829        } finally {
8830            Binder.restoreCallingIdentity(ident);
8831        }
8832    }
8833
8834    @Override
8835    public void stopLockTaskModeOnCurrent() throws RemoteException {
8836        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8837                "stopLockTaskModeOnCurrent");
8838        long ident = Binder.clearCallingIdentity();
8839        try {
8840            stopLockTaskMode();
8841        } finally {
8842            Binder.restoreCallingIdentity(ident);
8843        }
8844    }
8845
8846    @Override
8847    public boolean isInLockTaskMode() {
8848        synchronized (this) {
8849            return mStackSupervisor.isInLockTaskMode();
8850        }
8851    }
8852
8853    // =========================================================
8854    // CONTENT PROVIDERS
8855    // =========================================================
8856
8857    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8858        List<ProviderInfo> providers = null;
8859        try {
8860            providers = AppGlobals.getPackageManager().
8861                queryContentProviders(app.processName, app.uid,
8862                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8863        } catch (RemoteException ex) {
8864        }
8865        if (DEBUG_MU)
8866            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8867        int userId = app.userId;
8868        if (providers != null) {
8869            int N = providers.size();
8870            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8871            for (int i=0; i<N; i++) {
8872                ProviderInfo cpi =
8873                    (ProviderInfo)providers.get(i);
8874                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8875                        cpi.name, cpi.flags);
8876                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8877                    // This is a singleton provider, but a user besides the
8878                    // default user is asking to initialize a process it runs
8879                    // in...  well, no, it doesn't actually run in this process,
8880                    // it runs in the process of the default user.  Get rid of it.
8881                    providers.remove(i);
8882                    N--;
8883                    i--;
8884                    continue;
8885                }
8886
8887                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8888                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8889                if (cpr == null) {
8890                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8891                    mProviderMap.putProviderByClass(comp, cpr);
8892                }
8893                if (DEBUG_MU)
8894                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8895                app.pubProviders.put(cpi.name, cpr);
8896                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8897                    // Don't add this if it is a platform component that is marked
8898                    // to run in multiple processes, because this is actually
8899                    // part of the framework so doesn't make sense to track as a
8900                    // separate apk in the process.
8901                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8902                            mProcessStats);
8903                }
8904                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8905            }
8906        }
8907        return providers;
8908    }
8909
8910    /**
8911     * Check if {@link ProcessRecord} has a possible chance at accessing the
8912     * given {@link ProviderInfo}. Final permission checking is always done
8913     * in {@link ContentProvider}.
8914     */
8915    private final String checkContentProviderPermissionLocked(
8916            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8917        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8918        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8919        boolean checkedGrants = false;
8920        if (checkUser) {
8921            // Looking for cross-user grants before enforcing the typical cross-users permissions
8922            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8923            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8924                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8925                    return null;
8926                }
8927                checkedGrants = true;
8928            }
8929            userId = handleIncomingUser(callingPid, callingUid, userId,
8930                    false, ALLOW_NON_FULL,
8931                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8932            if (userId != tmpTargetUserId) {
8933                // When we actually went to determine the final targer user ID, this ended
8934                // up different than our initial check for the authority.  This is because
8935                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8936                // SELF.  So we need to re-check the grants again.
8937                checkedGrants = false;
8938            }
8939        }
8940        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8941                cpi.applicationInfo.uid, cpi.exported)
8942                == PackageManager.PERMISSION_GRANTED) {
8943            return null;
8944        }
8945        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8946                cpi.applicationInfo.uid, cpi.exported)
8947                == PackageManager.PERMISSION_GRANTED) {
8948            return null;
8949        }
8950
8951        PathPermission[] pps = cpi.pathPermissions;
8952        if (pps != null) {
8953            int i = pps.length;
8954            while (i > 0) {
8955                i--;
8956                PathPermission pp = pps[i];
8957                String pprperm = pp.getReadPermission();
8958                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8959                        cpi.applicationInfo.uid, cpi.exported)
8960                        == PackageManager.PERMISSION_GRANTED) {
8961                    return null;
8962                }
8963                String ppwperm = pp.getWritePermission();
8964                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8965                        cpi.applicationInfo.uid, cpi.exported)
8966                        == PackageManager.PERMISSION_GRANTED) {
8967                    return null;
8968                }
8969            }
8970        }
8971        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8972            return null;
8973        }
8974
8975        String msg;
8976        if (!cpi.exported) {
8977            msg = "Permission Denial: opening provider " + cpi.name
8978                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8979                    + ", uid=" + callingUid + ") that is not exported from uid "
8980                    + cpi.applicationInfo.uid;
8981        } else {
8982            msg = "Permission Denial: opening provider " + cpi.name
8983                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8984                    + ", uid=" + callingUid + ") requires "
8985                    + cpi.readPermission + " or " + cpi.writePermission;
8986        }
8987        Slog.w(TAG, msg);
8988        return msg;
8989    }
8990
8991    /**
8992     * Returns if the ContentProvider has granted a uri to callingUid
8993     */
8994    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8995        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8996        if (perms != null) {
8997            for (int i=perms.size()-1; i>=0; i--) {
8998                GrantUri grantUri = perms.keyAt(i);
8999                if (grantUri.sourceUserId == userId || !checkUser) {
9000                    if (matchesProvider(grantUri.uri, cpi)) {
9001                        return true;
9002                    }
9003                }
9004            }
9005        }
9006        return false;
9007    }
9008
9009    /**
9010     * Returns true if the uri authority is one of the authorities specified in the provider.
9011     */
9012    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9013        String uriAuth = uri.getAuthority();
9014        String cpiAuth = cpi.authority;
9015        if (cpiAuth.indexOf(';') == -1) {
9016            return cpiAuth.equals(uriAuth);
9017        }
9018        String[] cpiAuths = cpiAuth.split(";");
9019        int length = cpiAuths.length;
9020        for (int i = 0; i < length; i++) {
9021            if (cpiAuths[i].equals(uriAuth)) return true;
9022        }
9023        return false;
9024    }
9025
9026    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9027            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9028        if (r != null) {
9029            for (int i=0; i<r.conProviders.size(); i++) {
9030                ContentProviderConnection conn = r.conProviders.get(i);
9031                if (conn.provider == cpr) {
9032                    if (DEBUG_PROVIDER) Slog.v(TAG,
9033                            "Adding provider requested by "
9034                            + r.processName + " from process "
9035                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9036                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9037                    if (stable) {
9038                        conn.stableCount++;
9039                        conn.numStableIncs++;
9040                    } else {
9041                        conn.unstableCount++;
9042                        conn.numUnstableIncs++;
9043                    }
9044                    return conn;
9045                }
9046            }
9047            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9048            if (stable) {
9049                conn.stableCount = 1;
9050                conn.numStableIncs = 1;
9051            } else {
9052                conn.unstableCount = 1;
9053                conn.numUnstableIncs = 1;
9054            }
9055            cpr.connections.add(conn);
9056            r.conProviders.add(conn);
9057            return conn;
9058        }
9059        cpr.addExternalProcessHandleLocked(externalProcessToken);
9060        return null;
9061    }
9062
9063    boolean decProviderCountLocked(ContentProviderConnection conn,
9064            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9065        if (conn != null) {
9066            cpr = conn.provider;
9067            if (DEBUG_PROVIDER) Slog.v(TAG,
9068                    "Removing provider requested by "
9069                    + conn.client.processName + " from process "
9070                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9071                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9072            if (stable) {
9073                conn.stableCount--;
9074            } else {
9075                conn.unstableCount--;
9076            }
9077            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9078                cpr.connections.remove(conn);
9079                conn.client.conProviders.remove(conn);
9080                return true;
9081            }
9082            return false;
9083        }
9084        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9085        return false;
9086    }
9087
9088    private void checkTime(long startTime, String where) {
9089        long now = SystemClock.elapsedRealtime();
9090        if ((now-startTime) > 1000) {
9091            // If we are taking more than a second, log about it.
9092            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9093        }
9094    }
9095
9096    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9097            String name, IBinder token, boolean stable, int userId) {
9098        ContentProviderRecord cpr;
9099        ContentProviderConnection conn = null;
9100        ProviderInfo cpi = null;
9101
9102        synchronized(this) {
9103            long startTime = SystemClock.elapsedRealtime();
9104
9105            ProcessRecord r = null;
9106            if (caller != null) {
9107                r = getRecordForAppLocked(caller);
9108                if (r == null) {
9109                    throw new SecurityException(
9110                            "Unable to find app for caller " + caller
9111                          + " (pid=" + Binder.getCallingPid()
9112                          + ") when getting content provider " + name);
9113                }
9114            }
9115
9116            boolean checkCrossUser = true;
9117
9118            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9119
9120            // First check if this content provider has been published...
9121            cpr = mProviderMap.getProviderByName(name, userId);
9122            // If that didn't work, check if it exists for user 0 and then
9123            // verify that it's a singleton provider before using it.
9124            if (cpr == null && userId != UserHandle.USER_OWNER) {
9125                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9126                if (cpr != null) {
9127                    cpi = cpr.info;
9128                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9129                            cpi.name, cpi.flags)
9130                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9131                        userId = UserHandle.USER_OWNER;
9132                        checkCrossUser = false;
9133                    } else {
9134                        cpr = null;
9135                        cpi = null;
9136                    }
9137                }
9138            }
9139
9140            boolean providerRunning = cpr != null;
9141            if (providerRunning) {
9142                cpi = cpr.info;
9143                String msg;
9144                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9145                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9146                        != null) {
9147                    throw new SecurityException(msg);
9148                }
9149                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9150
9151                if (r != null && cpr.canRunHere(r)) {
9152                    // This provider has been published or is in the process
9153                    // of being published...  but it is also allowed to run
9154                    // in the caller's process, so don't make a connection
9155                    // and just let the caller instantiate its own instance.
9156                    ContentProviderHolder holder = cpr.newHolder(null);
9157                    // don't give caller the provider object, it needs
9158                    // to make its own.
9159                    holder.provider = null;
9160                    return holder;
9161                }
9162
9163                final long origId = Binder.clearCallingIdentity();
9164
9165                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9166
9167                // In this case the provider instance already exists, so we can
9168                // return it right away.
9169                conn = incProviderCountLocked(r, cpr, token, stable);
9170                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9171                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9172                        // If this is a perceptible app accessing the provider,
9173                        // make sure to count it as being accessed and thus
9174                        // back up on the LRU list.  This is good because
9175                        // content providers are often expensive to start.
9176                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9177                        updateLruProcessLocked(cpr.proc, false, null);
9178                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9179                    }
9180                }
9181
9182                if (cpr.proc != null) {
9183                    if (false) {
9184                        if (cpr.name.flattenToShortString().equals(
9185                                "com.android.providers.calendar/.CalendarProvider2")) {
9186                            Slog.v(TAG, "****************** KILLING "
9187                                + cpr.name.flattenToShortString());
9188                            Process.killProcess(cpr.proc.pid);
9189                        }
9190                    }
9191                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9192                    boolean success = updateOomAdjLocked(cpr.proc);
9193                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9194                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9195                    // NOTE: there is still a race here where a signal could be
9196                    // pending on the process even though we managed to update its
9197                    // adj level.  Not sure what to do about this, but at least
9198                    // the race is now smaller.
9199                    if (!success) {
9200                        // Uh oh...  it looks like the provider's process
9201                        // has been killed on us.  We need to wait for a new
9202                        // process to be started, and make sure its death
9203                        // doesn't kill our process.
9204                        Slog.i(TAG,
9205                                "Existing provider " + cpr.name.flattenToShortString()
9206                                + " is crashing; detaching " + r);
9207                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9208                        checkTime(startTime, "getContentProviderImpl: before appDied");
9209                        appDiedLocked(cpr.proc);
9210                        checkTime(startTime, "getContentProviderImpl: after appDied");
9211                        if (!lastRef) {
9212                            // This wasn't the last ref our process had on
9213                            // the provider...  we have now been killed, bail.
9214                            return null;
9215                        }
9216                        providerRunning = false;
9217                        conn = null;
9218                    }
9219                }
9220
9221                Binder.restoreCallingIdentity(origId);
9222            }
9223
9224            boolean singleton;
9225            if (!providerRunning) {
9226                try {
9227                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9228                    cpi = AppGlobals.getPackageManager().
9229                        resolveContentProvider(name,
9230                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9231                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9232                } catch (RemoteException ex) {
9233                }
9234                if (cpi == null) {
9235                    return null;
9236                }
9237                // If the provider is a singleton AND
9238                // (it's a call within the same user || the provider is a
9239                // privileged app)
9240                // Then allow connecting to the singleton provider
9241                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9242                        cpi.name, cpi.flags)
9243                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9244                if (singleton) {
9245                    userId = UserHandle.USER_OWNER;
9246                }
9247                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9248                checkTime(startTime, "getContentProviderImpl: got app info for user");
9249
9250                String msg;
9251                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9252                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9253                        != null) {
9254                    throw new SecurityException(msg);
9255                }
9256                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9257
9258                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9259                        && !cpi.processName.equals("system")) {
9260                    // If this content provider does not run in the system
9261                    // process, and the system is not yet ready to run other
9262                    // processes, then fail fast instead of hanging.
9263                    throw new IllegalArgumentException(
9264                            "Attempt to launch content provider before system ready");
9265                }
9266
9267                // Make sure that the user who owns this provider is started.  If not,
9268                // we don't want to allow it to run.
9269                if (mStartedUsers.get(userId) == null) {
9270                    Slog.w(TAG, "Unable to launch app "
9271                            + cpi.applicationInfo.packageName + "/"
9272                            + cpi.applicationInfo.uid + " for provider "
9273                            + name + ": user " + userId + " is stopped");
9274                    return null;
9275                }
9276
9277                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9278                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9279                cpr = mProviderMap.getProviderByClass(comp, userId);
9280                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9281                final boolean firstClass = cpr == null;
9282                if (firstClass) {
9283                    final long ident = Binder.clearCallingIdentity();
9284                    try {
9285                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9286                        ApplicationInfo ai =
9287                            AppGlobals.getPackageManager().
9288                                getApplicationInfo(
9289                                        cpi.applicationInfo.packageName,
9290                                        STOCK_PM_FLAGS, userId);
9291                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9292                        if (ai == null) {
9293                            Slog.w(TAG, "No package info for content provider "
9294                                    + cpi.name);
9295                            return null;
9296                        }
9297                        ai = getAppInfoForUser(ai, userId);
9298                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9299                    } catch (RemoteException ex) {
9300                        // pm is in same process, this will never happen.
9301                    } finally {
9302                        Binder.restoreCallingIdentity(ident);
9303                    }
9304                }
9305
9306                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9307
9308                if (r != null && cpr.canRunHere(r)) {
9309                    // If this is a multiprocess provider, then just return its
9310                    // info and allow the caller to instantiate it.  Only do
9311                    // this if the provider is the same user as the caller's
9312                    // process, or can run as root (so can be in any process).
9313                    return cpr.newHolder(null);
9314                }
9315
9316                if (DEBUG_PROVIDER) {
9317                    RuntimeException e = new RuntimeException("here");
9318                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9319                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9320                }
9321
9322                // This is single process, and our app is now connecting to it.
9323                // See if we are already in the process of launching this
9324                // provider.
9325                final int N = mLaunchingProviders.size();
9326                int i;
9327                for (i=0; i<N; i++) {
9328                    if (mLaunchingProviders.get(i) == cpr) {
9329                        break;
9330                    }
9331                }
9332
9333                // If the provider is not already being launched, then get it
9334                // started.
9335                if (i >= N) {
9336                    final long origId = Binder.clearCallingIdentity();
9337
9338                    try {
9339                        // Content provider is now in use, its package can't be stopped.
9340                        try {
9341                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9342                            AppGlobals.getPackageManager().setPackageStoppedState(
9343                                    cpr.appInfo.packageName, false, userId);
9344                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9345                        } catch (RemoteException e) {
9346                        } catch (IllegalArgumentException e) {
9347                            Slog.w(TAG, "Failed trying to unstop package "
9348                                    + cpr.appInfo.packageName + ": " + e);
9349                        }
9350
9351                        // Use existing process if already started
9352                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9353                        ProcessRecord proc = getProcessRecordLocked(
9354                                cpi.processName, cpr.appInfo.uid, false);
9355                        if (proc != null && proc.thread != null) {
9356                            if (DEBUG_PROVIDER) {
9357                                Slog.d(TAG, "Installing in existing process " + proc);
9358                            }
9359                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9360                            proc.pubProviders.put(cpi.name, cpr);
9361                            try {
9362                                proc.thread.scheduleInstallProvider(cpi);
9363                            } catch (RemoteException e) {
9364                            }
9365                        } else {
9366                            checkTime(startTime, "getContentProviderImpl: before start process");
9367                            proc = startProcessLocked(cpi.processName,
9368                                    cpr.appInfo, false, 0, "content provider",
9369                                    new ComponentName(cpi.applicationInfo.packageName,
9370                                            cpi.name), false, false, false);
9371                            checkTime(startTime, "getContentProviderImpl: after start process");
9372                            if (proc == null) {
9373                                Slog.w(TAG, "Unable to launch app "
9374                                        + cpi.applicationInfo.packageName + "/"
9375                                        + cpi.applicationInfo.uid + " for provider "
9376                                        + name + ": process is bad");
9377                                return null;
9378                            }
9379                        }
9380                        cpr.launchingApp = proc;
9381                        mLaunchingProviders.add(cpr);
9382                    } finally {
9383                        Binder.restoreCallingIdentity(origId);
9384                    }
9385                }
9386
9387                checkTime(startTime, "getContentProviderImpl: updating data structures");
9388
9389                // Make sure the provider is published (the same provider class
9390                // may be published under multiple names).
9391                if (firstClass) {
9392                    mProviderMap.putProviderByClass(comp, cpr);
9393                }
9394
9395                mProviderMap.putProviderByName(name, cpr);
9396                conn = incProviderCountLocked(r, cpr, token, stable);
9397                if (conn != null) {
9398                    conn.waiting = true;
9399                }
9400            }
9401            checkTime(startTime, "getContentProviderImpl: done!");
9402        }
9403
9404        // Wait for the provider to be published...
9405        synchronized (cpr) {
9406            while (cpr.provider == null) {
9407                if (cpr.launchingApp == null) {
9408                    Slog.w(TAG, "Unable to launch app "
9409                            + cpi.applicationInfo.packageName + "/"
9410                            + cpi.applicationInfo.uid + " for provider "
9411                            + name + ": launching app became null");
9412                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9413                            UserHandle.getUserId(cpi.applicationInfo.uid),
9414                            cpi.applicationInfo.packageName,
9415                            cpi.applicationInfo.uid, name);
9416                    return null;
9417                }
9418                try {
9419                    if (DEBUG_MU) {
9420                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9421                                + cpr.launchingApp);
9422                    }
9423                    if (conn != null) {
9424                        conn.waiting = true;
9425                    }
9426                    cpr.wait();
9427                } catch (InterruptedException ex) {
9428                } finally {
9429                    if (conn != null) {
9430                        conn.waiting = false;
9431                    }
9432                }
9433            }
9434        }
9435        return cpr != null ? cpr.newHolder(conn) : null;
9436    }
9437
9438    @Override
9439    public final ContentProviderHolder getContentProvider(
9440            IApplicationThread caller, String name, int userId, boolean stable) {
9441        enforceNotIsolatedCaller("getContentProvider");
9442        if (caller == null) {
9443            String msg = "null IApplicationThread when getting content provider "
9444                    + name;
9445            Slog.w(TAG, msg);
9446            throw new SecurityException(msg);
9447        }
9448        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9449        // with cross-user grant.
9450        return getContentProviderImpl(caller, name, null, stable, userId);
9451    }
9452
9453    public ContentProviderHolder getContentProviderExternal(
9454            String name, int userId, IBinder token) {
9455        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9456            "Do not have permission in call getContentProviderExternal()");
9457        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9458                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9459        return getContentProviderExternalUnchecked(name, token, userId);
9460    }
9461
9462    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9463            IBinder token, int userId) {
9464        return getContentProviderImpl(null, name, token, true, userId);
9465    }
9466
9467    /**
9468     * Drop a content provider from a ProcessRecord's bookkeeping
9469     */
9470    public void removeContentProvider(IBinder connection, boolean stable) {
9471        enforceNotIsolatedCaller("removeContentProvider");
9472        long ident = Binder.clearCallingIdentity();
9473        try {
9474            synchronized (this) {
9475                ContentProviderConnection conn;
9476                try {
9477                    conn = (ContentProviderConnection)connection;
9478                } catch (ClassCastException e) {
9479                    String msg ="removeContentProvider: " + connection
9480                            + " not a ContentProviderConnection";
9481                    Slog.w(TAG, msg);
9482                    throw new IllegalArgumentException(msg);
9483                }
9484                if (conn == null) {
9485                    throw new NullPointerException("connection is null");
9486                }
9487                if (decProviderCountLocked(conn, null, null, stable)) {
9488                    updateOomAdjLocked();
9489                }
9490            }
9491        } finally {
9492            Binder.restoreCallingIdentity(ident);
9493        }
9494    }
9495
9496    public void removeContentProviderExternal(String name, IBinder token) {
9497        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9498            "Do not have permission in call removeContentProviderExternal()");
9499        int userId = UserHandle.getCallingUserId();
9500        long ident = Binder.clearCallingIdentity();
9501        try {
9502            removeContentProviderExternalUnchecked(name, token, userId);
9503        } finally {
9504            Binder.restoreCallingIdentity(ident);
9505        }
9506    }
9507
9508    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9509        synchronized (this) {
9510            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9511            if(cpr == null) {
9512                //remove from mProvidersByClass
9513                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9514                return;
9515            }
9516
9517            //update content provider record entry info
9518            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9519            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9520            if (localCpr.hasExternalProcessHandles()) {
9521                if (localCpr.removeExternalProcessHandleLocked(token)) {
9522                    updateOomAdjLocked();
9523                } else {
9524                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9525                            + " with no external reference for token: "
9526                            + token + ".");
9527                }
9528            } else {
9529                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9530                        + " with no external references.");
9531            }
9532        }
9533    }
9534
9535    public final void publishContentProviders(IApplicationThread caller,
9536            List<ContentProviderHolder> providers) {
9537        if (providers == null) {
9538            return;
9539        }
9540
9541        enforceNotIsolatedCaller("publishContentProviders");
9542        synchronized (this) {
9543            final ProcessRecord r = getRecordForAppLocked(caller);
9544            if (DEBUG_MU)
9545                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9546            if (r == null) {
9547                throw new SecurityException(
9548                        "Unable to find app for caller " + caller
9549                      + " (pid=" + Binder.getCallingPid()
9550                      + ") when publishing content providers");
9551            }
9552
9553            final long origId = Binder.clearCallingIdentity();
9554
9555            final int N = providers.size();
9556            for (int i=0; i<N; i++) {
9557                ContentProviderHolder src = providers.get(i);
9558                if (src == null || src.info == null || src.provider == null) {
9559                    continue;
9560                }
9561                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9562                if (DEBUG_MU)
9563                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9564                if (dst != null) {
9565                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9566                    mProviderMap.putProviderByClass(comp, dst);
9567                    String names[] = dst.info.authority.split(";");
9568                    for (int j = 0; j < names.length; j++) {
9569                        mProviderMap.putProviderByName(names[j], dst);
9570                    }
9571
9572                    int NL = mLaunchingProviders.size();
9573                    int j;
9574                    for (j=0; j<NL; j++) {
9575                        if (mLaunchingProviders.get(j) == dst) {
9576                            mLaunchingProviders.remove(j);
9577                            j--;
9578                            NL--;
9579                        }
9580                    }
9581                    synchronized (dst) {
9582                        dst.provider = src.provider;
9583                        dst.proc = r;
9584                        dst.notifyAll();
9585                    }
9586                    updateOomAdjLocked(r);
9587                }
9588            }
9589
9590            Binder.restoreCallingIdentity(origId);
9591        }
9592    }
9593
9594    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9595        ContentProviderConnection conn;
9596        try {
9597            conn = (ContentProviderConnection)connection;
9598        } catch (ClassCastException e) {
9599            String msg ="refContentProvider: " + connection
9600                    + " not a ContentProviderConnection";
9601            Slog.w(TAG, msg);
9602            throw new IllegalArgumentException(msg);
9603        }
9604        if (conn == null) {
9605            throw new NullPointerException("connection is null");
9606        }
9607
9608        synchronized (this) {
9609            if (stable > 0) {
9610                conn.numStableIncs += stable;
9611            }
9612            stable = conn.stableCount + stable;
9613            if (stable < 0) {
9614                throw new IllegalStateException("stableCount < 0: " + stable);
9615            }
9616
9617            if (unstable > 0) {
9618                conn.numUnstableIncs += unstable;
9619            }
9620            unstable = conn.unstableCount + unstable;
9621            if (unstable < 0) {
9622                throw new IllegalStateException("unstableCount < 0: " + unstable);
9623            }
9624
9625            if ((stable+unstable) <= 0) {
9626                throw new IllegalStateException("ref counts can't go to zero here: stable="
9627                        + stable + " unstable=" + unstable);
9628            }
9629            conn.stableCount = stable;
9630            conn.unstableCount = unstable;
9631            return !conn.dead;
9632        }
9633    }
9634
9635    public void unstableProviderDied(IBinder connection) {
9636        ContentProviderConnection conn;
9637        try {
9638            conn = (ContentProviderConnection)connection;
9639        } catch (ClassCastException e) {
9640            String msg ="refContentProvider: " + connection
9641                    + " not a ContentProviderConnection";
9642            Slog.w(TAG, msg);
9643            throw new IllegalArgumentException(msg);
9644        }
9645        if (conn == null) {
9646            throw new NullPointerException("connection is null");
9647        }
9648
9649        // Safely retrieve the content provider associated with the connection.
9650        IContentProvider provider;
9651        synchronized (this) {
9652            provider = conn.provider.provider;
9653        }
9654
9655        if (provider == null) {
9656            // Um, yeah, we're way ahead of you.
9657            return;
9658        }
9659
9660        // Make sure the caller is being honest with us.
9661        if (provider.asBinder().pingBinder()) {
9662            // Er, no, still looks good to us.
9663            synchronized (this) {
9664                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9665                        + " says " + conn + " died, but we don't agree");
9666                return;
9667            }
9668        }
9669
9670        // Well look at that!  It's dead!
9671        synchronized (this) {
9672            if (conn.provider.provider != provider) {
9673                // But something changed...  good enough.
9674                return;
9675            }
9676
9677            ProcessRecord proc = conn.provider.proc;
9678            if (proc == null || proc.thread == null) {
9679                // Seems like the process is already cleaned up.
9680                return;
9681            }
9682
9683            // As far as we're concerned, this is just like receiving a
9684            // death notification...  just a bit prematurely.
9685            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9686                    + ") early provider death");
9687            final long ident = Binder.clearCallingIdentity();
9688            try {
9689                appDiedLocked(proc);
9690            } finally {
9691                Binder.restoreCallingIdentity(ident);
9692            }
9693        }
9694    }
9695
9696    @Override
9697    public void appNotRespondingViaProvider(IBinder connection) {
9698        enforceCallingPermission(
9699                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9700
9701        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9702        if (conn == null) {
9703            Slog.w(TAG, "ContentProviderConnection is null");
9704            return;
9705        }
9706
9707        final ProcessRecord host = conn.provider.proc;
9708        if (host == null) {
9709            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9710            return;
9711        }
9712
9713        final long token = Binder.clearCallingIdentity();
9714        try {
9715            appNotResponding(host, null, null, false, "ContentProvider not responding");
9716        } finally {
9717            Binder.restoreCallingIdentity(token);
9718        }
9719    }
9720
9721    public final void installSystemProviders() {
9722        List<ProviderInfo> providers;
9723        synchronized (this) {
9724            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9725            providers = generateApplicationProvidersLocked(app);
9726            if (providers != null) {
9727                for (int i=providers.size()-1; i>=0; i--) {
9728                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9729                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9730                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9731                                + ": not system .apk");
9732                        providers.remove(i);
9733                    }
9734                }
9735            }
9736        }
9737        if (providers != null) {
9738            mSystemThread.installSystemProviders(providers);
9739        }
9740
9741        mCoreSettingsObserver = new CoreSettingsObserver(this);
9742
9743        //mUsageStatsService.monitorPackages();
9744    }
9745
9746    /**
9747     * Allows apps to retrieve the MIME type of a URI.
9748     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9749     * users, then it does not need permission to access the ContentProvider.
9750     * Either, it needs cross-user uri grants.
9751     *
9752     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9753     *
9754     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9755     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9756     */
9757    public String getProviderMimeType(Uri uri, int userId) {
9758        enforceNotIsolatedCaller("getProviderMimeType");
9759        final String name = uri.getAuthority();
9760        int callingUid = Binder.getCallingUid();
9761        int callingPid = Binder.getCallingPid();
9762        long ident = 0;
9763        boolean clearedIdentity = false;
9764        userId = unsafeConvertIncomingUser(userId);
9765        if (canClearIdentity(callingPid, callingUid, userId)) {
9766            clearedIdentity = true;
9767            ident = Binder.clearCallingIdentity();
9768        }
9769        ContentProviderHolder holder = null;
9770        try {
9771            holder = getContentProviderExternalUnchecked(name, null, userId);
9772            if (holder != null) {
9773                return holder.provider.getType(uri);
9774            }
9775        } catch (RemoteException e) {
9776            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9777            return null;
9778        } finally {
9779            // We need to clear the identity to call removeContentProviderExternalUnchecked
9780            if (!clearedIdentity) {
9781                ident = Binder.clearCallingIdentity();
9782            }
9783            try {
9784                if (holder != null) {
9785                    removeContentProviderExternalUnchecked(name, null, userId);
9786                }
9787            } finally {
9788                Binder.restoreCallingIdentity(ident);
9789            }
9790        }
9791
9792        return null;
9793    }
9794
9795    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9796        if (UserHandle.getUserId(callingUid) == userId) {
9797            return true;
9798        }
9799        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9800                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9801                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9802                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9803                return true;
9804        }
9805        return false;
9806    }
9807
9808    // =========================================================
9809    // GLOBAL MANAGEMENT
9810    // =========================================================
9811
9812    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9813            boolean isolated, int isolatedUid) {
9814        String proc = customProcess != null ? customProcess : info.processName;
9815        BatteryStatsImpl.Uid.Proc ps = null;
9816        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9817        int uid = info.uid;
9818        if (isolated) {
9819            if (isolatedUid == 0) {
9820                int userId = UserHandle.getUserId(uid);
9821                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9822                while (true) {
9823                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9824                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9825                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9826                    }
9827                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9828                    mNextIsolatedProcessUid++;
9829                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9830                        // No process for this uid, use it.
9831                        break;
9832                    }
9833                    stepsLeft--;
9834                    if (stepsLeft <= 0) {
9835                        return null;
9836                    }
9837                }
9838            } else {
9839                // Special case for startIsolatedProcess (internal only), where
9840                // the uid of the isolated process is specified by the caller.
9841                uid = isolatedUid;
9842            }
9843        }
9844        return new ProcessRecord(stats, info, proc, uid);
9845    }
9846
9847    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9848            String abiOverride) {
9849        ProcessRecord app;
9850        if (!isolated) {
9851            app = getProcessRecordLocked(info.processName, info.uid, true);
9852        } else {
9853            app = null;
9854        }
9855
9856        if (app == null) {
9857            app = newProcessRecordLocked(info, null, isolated, 0);
9858            mProcessNames.put(info.processName, app.uid, app);
9859            if (isolated) {
9860                mIsolatedProcesses.put(app.uid, app);
9861            }
9862            updateLruProcessLocked(app, false, null);
9863            updateOomAdjLocked();
9864        }
9865
9866        // This package really, really can not be stopped.
9867        try {
9868            AppGlobals.getPackageManager().setPackageStoppedState(
9869                    info.packageName, false, UserHandle.getUserId(app.uid));
9870        } catch (RemoteException e) {
9871        } catch (IllegalArgumentException e) {
9872            Slog.w(TAG, "Failed trying to unstop package "
9873                    + info.packageName + ": " + e);
9874        }
9875
9876        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9877                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9878            app.persistent = true;
9879            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9880        }
9881        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9882            mPersistentStartingProcesses.add(app);
9883            startProcessLocked(app, "added application", app.processName, abiOverride,
9884                    null /* entryPoint */, null /* entryPointArgs */);
9885        }
9886
9887        return app;
9888    }
9889
9890    public void unhandledBack() {
9891        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9892                "unhandledBack()");
9893
9894        synchronized(this) {
9895            final long origId = Binder.clearCallingIdentity();
9896            try {
9897                getFocusedStack().unhandledBackLocked();
9898            } finally {
9899                Binder.restoreCallingIdentity(origId);
9900            }
9901        }
9902    }
9903
9904    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9905        enforceNotIsolatedCaller("openContentUri");
9906        final int userId = UserHandle.getCallingUserId();
9907        String name = uri.getAuthority();
9908        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9909        ParcelFileDescriptor pfd = null;
9910        if (cph != null) {
9911            // We record the binder invoker's uid in thread-local storage before
9912            // going to the content provider to open the file.  Later, in the code
9913            // that handles all permissions checks, we look for this uid and use
9914            // that rather than the Activity Manager's own uid.  The effect is that
9915            // we do the check against the caller's permissions even though it looks
9916            // to the content provider like the Activity Manager itself is making
9917            // the request.
9918            sCallerIdentity.set(new Identity(
9919                    Binder.getCallingPid(), Binder.getCallingUid()));
9920            try {
9921                pfd = cph.provider.openFile(null, uri, "r", null);
9922            } catch (FileNotFoundException e) {
9923                // do nothing; pfd will be returned null
9924            } finally {
9925                // Ensure that whatever happens, we clean up the identity state
9926                sCallerIdentity.remove();
9927            }
9928
9929            // We've got the fd now, so we're done with the provider.
9930            removeContentProviderExternalUnchecked(name, null, userId);
9931        } else {
9932            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9933        }
9934        return pfd;
9935    }
9936
9937    // Actually is sleeping or shutting down or whatever else in the future
9938    // is an inactive state.
9939    public boolean isSleepingOrShuttingDown() {
9940        return isSleeping() || mShuttingDown;
9941    }
9942
9943    public boolean isSleeping() {
9944        return mSleeping;
9945    }
9946
9947    void goingToSleep() {
9948        synchronized(this) {
9949            mWentToSleep = true;
9950            goToSleepIfNeededLocked();
9951        }
9952    }
9953
9954    void finishRunningVoiceLocked() {
9955        if (mRunningVoice) {
9956            mRunningVoice = false;
9957            goToSleepIfNeededLocked();
9958        }
9959    }
9960
9961    void goToSleepIfNeededLocked() {
9962        if (mWentToSleep && !mRunningVoice) {
9963            if (!mSleeping) {
9964                mSleeping = true;
9965                mStackSupervisor.goingToSleepLocked();
9966
9967                // Initialize the wake times of all processes.
9968                checkExcessivePowerUsageLocked(false);
9969                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9970                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9971                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9972            }
9973        }
9974    }
9975
9976    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9977        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9978            // Never persist the home stack.
9979            return;
9980        }
9981        mTaskPersister.wakeup(task, flush);
9982    }
9983
9984    @Override
9985    public boolean shutdown(int timeout) {
9986        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9987                != PackageManager.PERMISSION_GRANTED) {
9988            throw new SecurityException("Requires permission "
9989                    + android.Manifest.permission.SHUTDOWN);
9990        }
9991
9992        boolean timedout = false;
9993
9994        synchronized(this) {
9995            mShuttingDown = true;
9996            updateEventDispatchingLocked();
9997            timedout = mStackSupervisor.shutdownLocked(timeout);
9998        }
9999
10000        mAppOpsService.shutdown();
10001        if (mUsageStatsService != null) {
10002            mUsageStatsService.prepareShutdown();
10003        }
10004        mBatteryStatsService.shutdown();
10005        synchronized (this) {
10006            mProcessStats.shutdownLocked();
10007        }
10008        notifyTaskPersisterLocked(null, true);
10009
10010        return timedout;
10011    }
10012
10013    public final void activitySlept(IBinder token) {
10014        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10015
10016        final long origId = Binder.clearCallingIdentity();
10017
10018        synchronized (this) {
10019            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10020            if (r != null) {
10021                mStackSupervisor.activitySleptLocked(r);
10022            }
10023        }
10024
10025        Binder.restoreCallingIdentity(origId);
10026    }
10027
10028    private String lockScreenShownToString() {
10029        switch (mLockScreenShown) {
10030            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10031            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10032            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10033            default: return "Unknown=" + mLockScreenShown;
10034        }
10035    }
10036
10037    void logLockScreen(String msg) {
10038        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10039                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10040                mWentToSleep + " mSleeping=" + mSleeping);
10041    }
10042
10043    void comeOutOfSleepIfNeededLocked() {
10044        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10045            if (mSleeping) {
10046                mSleeping = false;
10047                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10048            }
10049        }
10050    }
10051
10052    void wakingUp() {
10053        synchronized(this) {
10054            mWentToSleep = false;
10055            comeOutOfSleepIfNeededLocked();
10056        }
10057    }
10058
10059    void startRunningVoiceLocked() {
10060        if (!mRunningVoice) {
10061            mRunningVoice = true;
10062            comeOutOfSleepIfNeededLocked();
10063        }
10064    }
10065
10066    private void updateEventDispatchingLocked() {
10067        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10068    }
10069
10070    public void setLockScreenShown(boolean shown) {
10071        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10072                != PackageManager.PERMISSION_GRANTED) {
10073            throw new SecurityException("Requires permission "
10074                    + android.Manifest.permission.DEVICE_POWER);
10075        }
10076
10077        synchronized(this) {
10078            long ident = Binder.clearCallingIdentity();
10079            try {
10080                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10081                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10082                comeOutOfSleepIfNeededLocked();
10083            } finally {
10084                Binder.restoreCallingIdentity(ident);
10085            }
10086        }
10087    }
10088
10089    @Override
10090    public void stopAppSwitches() {
10091        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10092                != PackageManager.PERMISSION_GRANTED) {
10093            throw new SecurityException("Requires permission "
10094                    + android.Manifest.permission.STOP_APP_SWITCHES);
10095        }
10096
10097        synchronized(this) {
10098            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10099                    + APP_SWITCH_DELAY_TIME;
10100            mDidAppSwitch = false;
10101            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10102            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10103            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10104        }
10105    }
10106
10107    public void resumeAppSwitches() {
10108        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10109                != PackageManager.PERMISSION_GRANTED) {
10110            throw new SecurityException("Requires permission "
10111                    + android.Manifest.permission.STOP_APP_SWITCHES);
10112        }
10113
10114        synchronized(this) {
10115            // Note that we don't execute any pending app switches... we will
10116            // let those wait until either the timeout, or the next start
10117            // activity request.
10118            mAppSwitchesAllowedTime = 0;
10119        }
10120    }
10121
10122    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10123            int callingPid, int callingUid, String name) {
10124        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10125            return true;
10126        }
10127
10128        int perm = checkComponentPermission(
10129                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10130                sourceUid, -1, true);
10131        if (perm == PackageManager.PERMISSION_GRANTED) {
10132            return true;
10133        }
10134
10135        // If the actual IPC caller is different from the logical source, then
10136        // also see if they are allowed to control app switches.
10137        if (callingUid != -1 && callingUid != sourceUid) {
10138            perm = checkComponentPermission(
10139                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10140                    callingUid, -1, true);
10141            if (perm == PackageManager.PERMISSION_GRANTED) {
10142                return true;
10143            }
10144        }
10145
10146        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10147        return false;
10148    }
10149
10150    public void setDebugApp(String packageName, boolean waitForDebugger,
10151            boolean persistent) {
10152        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10153                "setDebugApp()");
10154
10155        long ident = Binder.clearCallingIdentity();
10156        try {
10157            // Note that this is not really thread safe if there are multiple
10158            // callers into it at the same time, but that's not a situation we
10159            // care about.
10160            if (persistent) {
10161                final ContentResolver resolver = mContext.getContentResolver();
10162                Settings.Global.putString(
10163                    resolver, Settings.Global.DEBUG_APP,
10164                    packageName);
10165                Settings.Global.putInt(
10166                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10167                    waitForDebugger ? 1 : 0);
10168            }
10169
10170            synchronized (this) {
10171                if (!persistent) {
10172                    mOrigDebugApp = mDebugApp;
10173                    mOrigWaitForDebugger = mWaitForDebugger;
10174                }
10175                mDebugApp = packageName;
10176                mWaitForDebugger = waitForDebugger;
10177                mDebugTransient = !persistent;
10178                if (packageName != null) {
10179                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10180                            false, UserHandle.USER_ALL, "set debug app");
10181                }
10182            }
10183        } finally {
10184            Binder.restoreCallingIdentity(ident);
10185        }
10186    }
10187
10188    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10189        synchronized (this) {
10190            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10191            if (!isDebuggable) {
10192                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10193                    throw new SecurityException("Process not debuggable: " + app.packageName);
10194                }
10195            }
10196
10197            mOpenGlTraceApp = processName;
10198        }
10199    }
10200
10201    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10202        synchronized (this) {
10203            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10204            if (!isDebuggable) {
10205                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10206                    throw new SecurityException("Process not debuggable: " + app.packageName);
10207                }
10208            }
10209            mProfileApp = processName;
10210            mProfileFile = profilerInfo.profileFile;
10211            if (mProfileFd != null) {
10212                try {
10213                    mProfileFd.close();
10214                } catch (IOException e) {
10215                }
10216                mProfileFd = null;
10217            }
10218            mProfileFd = profilerInfo.profileFd;
10219            mSamplingInterval = profilerInfo.samplingInterval;
10220            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10221            mProfileType = 0;
10222        }
10223    }
10224
10225    @Override
10226    public void setAlwaysFinish(boolean enabled) {
10227        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10228                "setAlwaysFinish()");
10229
10230        Settings.Global.putInt(
10231                mContext.getContentResolver(),
10232                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10233
10234        synchronized (this) {
10235            mAlwaysFinishActivities = enabled;
10236        }
10237    }
10238
10239    @Override
10240    public void setActivityController(IActivityController controller) {
10241        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10242                "setActivityController()");
10243        synchronized (this) {
10244            mController = controller;
10245            Watchdog.getInstance().setActivityController(controller);
10246        }
10247    }
10248
10249    @Override
10250    public void setUserIsMonkey(boolean userIsMonkey) {
10251        synchronized (this) {
10252            synchronized (mPidsSelfLocked) {
10253                final int callingPid = Binder.getCallingPid();
10254                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10255                if (precessRecord == null) {
10256                    throw new SecurityException("Unknown process: " + callingPid);
10257                }
10258                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10259                    throw new SecurityException("Only an instrumentation process "
10260                            + "with a UiAutomation can call setUserIsMonkey");
10261                }
10262            }
10263            mUserIsMonkey = userIsMonkey;
10264        }
10265    }
10266
10267    @Override
10268    public boolean isUserAMonkey() {
10269        synchronized (this) {
10270            // If there is a controller also implies the user is a monkey.
10271            return (mUserIsMonkey || mController != null);
10272        }
10273    }
10274
10275    public void requestBugReport() {
10276        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10277        SystemProperties.set("ctl.start", "bugreport");
10278    }
10279
10280    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10281        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10282    }
10283
10284    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10285        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10286            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10287        }
10288        return KEY_DISPATCHING_TIMEOUT;
10289    }
10290
10291    @Override
10292    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10293        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10294                != PackageManager.PERMISSION_GRANTED) {
10295            throw new SecurityException("Requires permission "
10296                    + android.Manifest.permission.FILTER_EVENTS);
10297        }
10298        ProcessRecord proc;
10299        long timeout;
10300        synchronized (this) {
10301            synchronized (mPidsSelfLocked) {
10302                proc = mPidsSelfLocked.get(pid);
10303            }
10304            timeout = getInputDispatchingTimeoutLocked(proc);
10305        }
10306
10307        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10308            return -1;
10309        }
10310
10311        return timeout;
10312    }
10313
10314    /**
10315     * Handle input dispatching timeouts.
10316     * Returns whether input dispatching should be aborted or not.
10317     */
10318    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10319            final ActivityRecord activity, final ActivityRecord parent,
10320            final boolean aboveSystem, String reason) {
10321        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10322                != PackageManager.PERMISSION_GRANTED) {
10323            throw new SecurityException("Requires permission "
10324                    + android.Manifest.permission.FILTER_EVENTS);
10325        }
10326
10327        final String annotation;
10328        if (reason == null) {
10329            annotation = "Input dispatching timed out";
10330        } else {
10331            annotation = "Input dispatching timed out (" + reason + ")";
10332        }
10333
10334        if (proc != null) {
10335            synchronized (this) {
10336                if (proc.debugging) {
10337                    return false;
10338                }
10339
10340                if (mDidDexOpt) {
10341                    // Give more time since we were dexopting.
10342                    mDidDexOpt = false;
10343                    return false;
10344                }
10345
10346                if (proc.instrumentationClass != null) {
10347                    Bundle info = new Bundle();
10348                    info.putString("shortMsg", "keyDispatchingTimedOut");
10349                    info.putString("longMsg", annotation);
10350                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10351                    return true;
10352                }
10353            }
10354            mHandler.post(new Runnable() {
10355                @Override
10356                public void run() {
10357                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10358                }
10359            });
10360        }
10361
10362        return true;
10363    }
10364
10365    public Bundle getAssistContextExtras(int requestType) {
10366        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10367                UserHandle.getCallingUserId());
10368        if (pae == null) {
10369            return null;
10370        }
10371        synchronized (pae) {
10372            while (!pae.haveResult) {
10373                try {
10374                    pae.wait();
10375                } catch (InterruptedException e) {
10376                }
10377            }
10378            if (pae.result != null) {
10379                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10380            }
10381        }
10382        synchronized (this) {
10383            mPendingAssistExtras.remove(pae);
10384            mHandler.removeCallbacks(pae);
10385        }
10386        return pae.extras;
10387    }
10388
10389    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10390            int userHandle) {
10391        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10392                "getAssistContextExtras()");
10393        PendingAssistExtras pae;
10394        Bundle extras = new Bundle();
10395        synchronized (this) {
10396            ActivityRecord activity = getFocusedStack().mResumedActivity;
10397            if (activity == null) {
10398                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10399                return null;
10400            }
10401            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10402            if (activity.app == null || activity.app.thread == null) {
10403                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10404                return null;
10405            }
10406            if (activity.app.pid == Binder.getCallingPid()) {
10407                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10408                return null;
10409            }
10410            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10411            try {
10412                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10413                        requestType);
10414                mPendingAssistExtras.add(pae);
10415                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10416            } catch (RemoteException e) {
10417                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10418                return null;
10419            }
10420            return pae;
10421        }
10422    }
10423
10424    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10425        PendingAssistExtras pae = (PendingAssistExtras)token;
10426        synchronized (pae) {
10427            pae.result = extras;
10428            pae.haveResult = true;
10429            pae.notifyAll();
10430            if (pae.intent == null) {
10431                // Caller is just waiting for the result.
10432                return;
10433            }
10434        }
10435
10436        // We are now ready to launch the assist activity.
10437        synchronized (this) {
10438            boolean exists = mPendingAssistExtras.remove(pae);
10439            mHandler.removeCallbacks(pae);
10440            if (!exists) {
10441                // Timed out.
10442                return;
10443            }
10444        }
10445        pae.intent.replaceExtras(extras);
10446        if (pae.hint != null) {
10447            pae.intent.putExtra(pae.hint, true);
10448        }
10449        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10450                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10451                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10452        closeSystemDialogs("assist");
10453        try {
10454            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10455        } catch (ActivityNotFoundException e) {
10456            Slog.w(TAG, "No activity to handle assist action.", e);
10457        }
10458    }
10459
10460    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10461        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10462    }
10463
10464    public void registerProcessObserver(IProcessObserver observer) {
10465        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10466                "registerProcessObserver()");
10467        synchronized (this) {
10468            mProcessObservers.register(observer);
10469        }
10470    }
10471
10472    @Override
10473    public void unregisterProcessObserver(IProcessObserver observer) {
10474        synchronized (this) {
10475            mProcessObservers.unregister(observer);
10476        }
10477    }
10478
10479    @Override
10480    public boolean convertFromTranslucent(IBinder token) {
10481        final long origId = Binder.clearCallingIdentity();
10482        try {
10483            synchronized (this) {
10484                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10485                if (r == null) {
10486                    return false;
10487                }
10488                final boolean translucentChanged = r.changeWindowTranslucency(true);
10489                if (translucentChanged) {
10490                    r.task.stack.releaseBackgroundResources();
10491                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10492                }
10493                mWindowManager.setAppFullscreen(token, true);
10494                return translucentChanged;
10495            }
10496        } finally {
10497            Binder.restoreCallingIdentity(origId);
10498        }
10499    }
10500
10501    @Override
10502    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10503        final long origId = Binder.clearCallingIdentity();
10504        try {
10505            synchronized (this) {
10506                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10507                if (r == null) {
10508                    return false;
10509                }
10510                int index = r.task.mActivities.lastIndexOf(r);
10511                if (index > 0) {
10512                    ActivityRecord under = r.task.mActivities.get(index - 1);
10513                    under.returningOptions = options;
10514                }
10515                final boolean translucentChanged = r.changeWindowTranslucency(false);
10516                if (translucentChanged) {
10517                    r.task.stack.convertToTranslucent(r);
10518                }
10519                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10520                mWindowManager.setAppFullscreen(token, false);
10521                return translucentChanged;
10522            }
10523        } finally {
10524            Binder.restoreCallingIdentity(origId);
10525        }
10526    }
10527
10528    @Override
10529    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10530        final long origId = Binder.clearCallingIdentity();
10531        try {
10532            synchronized (this) {
10533                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10534                if (r != null) {
10535                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10536                }
10537            }
10538            return false;
10539        } finally {
10540            Binder.restoreCallingIdentity(origId);
10541        }
10542    }
10543
10544    @Override
10545    public boolean isBackgroundVisibleBehind(IBinder token) {
10546        final long origId = Binder.clearCallingIdentity();
10547        try {
10548            synchronized (this) {
10549                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10550                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10551                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10552                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10553                return visible;
10554            }
10555        } finally {
10556            Binder.restoreCallingIdentity(origId);
10557        }
10558    }
10559
10560    @Override
10561    public ActivityOptions getActivityOptions(IBinder token) {
10562        final long origId = Binder.clearCallingIdentity();
10563        try {
10564            synchronized (this) {
10565                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10566                if (r != null) {
10567                    final ActivityOptions activityOptions = r.pendingOptions;
10568                    r.pendingOptions = null;
10569                    return activityOptions;
10570                }
10571                return null;
10572            }
10573        } finally {
10574            Binder.restoreCallingIdentity(origId);
10575        }
10576    }
10577
10578    @Override
10579    public void setImmersive(IBinder token, boolean immersive) {
10580        synchronized(this) {
10581            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10582            if (r == null) {
10583                throw new IllegalArgumentException();
10584            }
10585            r.immersive = immersive;
10586
10587            // update associated state if we're frontmost
10588            if (r == mFocusedActivity) {
10589                if (DEBUG_IMMERSIVE) {
10590                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10591                }
10592                applyUpdateLockStateLocked(r);
10593            }
10594        }
10595    }
10596
10597    @Override
10598    public boolean isImmersive(IBinder token) {
10599        synchronized (this) {
10600            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10601            if (r == null) {
10602                throw new IllegalArgumentException();
10603            }
10604            return r.immersive;
10605        }
10606    }
10607
10608    public boolean isTopActivityImmersive() {
10609        enforceNotIsolatedCaller("startActivity");
10610        synchronized (this) {
10611            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10612            return (r != null) ? r.immersive : false;
10613        }
10614    }
10615
10616    @Override
10617    public boolean isTopOfTask(IBinder token) {
10618        synchronized (this) {
10619            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10620            if (r == null) {
10621                throw new IllegalArgumentException();
10622            }
10623            return r.task.getTopActivity() == r;
10624        }
10625    }
10626
10627    public final void enterSafeMode() {
10628        synchronized(this) {
10629            // It only makes sense to do this before the system is ready
10630            // and started launching other packages.
10631            if (!mSystemReady) {
10632                try {
10633                    AppGlobals.getPackageManager().enterSafeMode();
10634                } catch (RemoteException e) {
10635                }
10636            }
10637
10638            mSafeMode = true;
10639        }
10640    }
10641
10642    public final void showSafeModeOverlay() {
10643        View v = LayoutInflater.from(mContext).inflate(
10644                com.android.internal.R.layout.safe_mode, null);
10645        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10646        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10647        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10648        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10649        lp.gravity = Gravity.BOTTOM | Gravity.START;
10650        lp.format = v.getBackground().getOpacity();
10651        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10652                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10653        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10654        ((WindowManager)mContext.getSystemService(
10655                Context.WINDOW_SERVICE)).addView(v, lp);
10656    }
10657
10658    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10659        if (!(sender instanceof PendingIntentRecord)) {
10660            return;
10661        }
10662        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10663        synchronized (stats) {
10664            if (mBatteryStatsService.isOnBattery()) {
10665                mBatteryStatsService.enforceCallingPermission();
10666                PendingIntentRecord rec = (PendingIntentRecord)sender;
10667                int MY_UID = Binder.getCallingUid();
10668                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10669                BatteryStatsImpl.Uid.Pkg pkg =
10670                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10671                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10672                pkg.incWakeupsLocked();
10673            }
10674        }
10675    }
10676
10677    public boolean killPids(int[] pids, String pReason, boolean secure) {
10678        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10679            throw new SecurityException("killPids only available to the system");
10680        }
10681        String reason = (pReason == null) ? "Unknown" : pReason;
10682        // XXX Note: don't acquire main activity lock here, because the window
10683        // manager calls in with its locks held.
10684
10685        boolean killed = false;
10686        synchronized (mPidsSelfLocked) {
10687            int[] types = new int[pids.length];
10688            int worstType = 0;
10689            for (int i=0; i<pids.length; i++) {
10690                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10691                if (proc != null) {
10692                    int type = proc.setAdj;
10693                    types[i] = type;
10694                    if (type > worstType) {
10695                        worstType = type;
10696                    }
10697                }
10698            }
10699
10700            // If the worst oom_adj is somewhere in the cached proc LRU range,
10701            // then constrain it so we will kill all cached procs.
10702            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10703                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10704                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10705            }
10706
10707            // If this is not a secure call, don't let it kill processes that
10708            // are important.
10709            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10710                worstType = ProcessList.SERVICE_ADJ;
10711            }
10712
10713            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10714            for (int i=0; i<pids.length; i++) {
10715                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10716                if (proc == null) {
10717                    continue;
10718                }
10719                int adj = proc.setAdj;
10720                if (adj >= worstType && !proc.killedByAm) {
10721                    proc.kill(reason, true);
10722                    killed = true;
10723                }
10724            }
10725        }
10726        return killed;
10727    }
10728
10729    @Override
10730    public void killUid(int uid, String reason) {
10731        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10732            throw new SecurityException("killUid only available to the system");
10733        }
10734        synchronized (this) {
10735            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10736                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10737                    reason != null ? reason : "kill uid");
10738        }
10739    }
10740
10741    @Override
10742    public boolean killProcessesBelowForeground(String reason) {
10743        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10744            throw new SecurityException("killProcessesBelowForeground() only available to system");
10745        }
10746
10747        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10748    }
10749
10750    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10751        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10752            throw new SecurityException("killProcessesBelowAdj() only available to system");
10753        }
10754
10755        boolean killed = false;
10756        synchronized (mPidsSelfLocked) {
10757            final int size = mPidsSelfLocked.size();
10758            for (int i = 0; i < size; i++) {
10759                final int pid = mPidsSelfLocked.keyAt(i);
10760                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10761                if (proc == null) continue;
10762
10763                final int adj = proc.setAdj;
10764                if (adj > belowAdj && !proc.killedByAm) {
10765                    proc.kill(reason, true);
10766                    killed = true;
10767                }
10768            }
10769        }
10770        return killed;
10771    }
10772
10773    @Override
10774    public void hang(final IBinder who, boolean allowRestart) {
10775        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10776                != PackageManager.PERMISSION_GRANTED) {
10777            throw new SecurityException("Requires permission "
10778                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10779        }
10780
10781        final IBinder.DeathRecipient death = new DeathRecipient() {
10782            @Override
10783            public void binderDied() {
10784                synchronized (this) {
10785                    notifyAll();
10786                }
10787            }
10788        };
10789
10790        try {
10791            who.linkToDeath(death, 0);
10792        } catch (RemoteException e) {
10793            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10794            return;
10795        }
10796
10797        synchronized (this) {
10798            Watchdog.getInstance().setAllowRestart(allowRestart);
10799            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10800            synchronized (death) {
10801                while (who.isBinderAlive()) {
10802                    try {
10803                        death.wait();
10804                    } catch (InterruptedException e) {
10805                    }
10806                }
10807            }
10808            Watchdog.getInstance().setAllowRestart(true);
10809        }
10810    }
10811
10812    @Override
10813    public void restart() {
10814        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10815                != PackageManager.PERMISSION_GRANTED) {
10816            throw new SecurityException("Requires permission "
10817                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10818        }
10819
10820        Log.i(TAG, "Sending shutdown broadcast...");
10821
10822        BroadcastReceiver br = new BroadcastReceiver() {
10823            @Override public void onReceive(Context context, Intent intent) {
10824                // Now the broadcast is done, finish up the low-level shutdown.
10825                Log.i(TAG, "Shutting down activity manager...");
10826                shutdown(10000);
10827                Log.i(TAG, "Shutdown complete, restarting!");
10828                Process.killProcess(Process.myPid());
10829                System.exit(10);
10830            }
10831        };
10832
10833        // First send the high-level shut down broadcast.
10834        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10835        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10836        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10837        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10838        mContext.sendOrderedBroadcastAsUser(intent,
10839                UserHandle.ALL, null, br, mHandler, 0, null, null);
10840        */
10841        br.onReceive(mContext, intent);
10842    }
10843
10844    private long getLowRamTimeSinceIdle(long now) {
10845        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10846    }
10847
10848    @Override
10849    public void performIdleMaintenance() {
10850        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10851                != PackageManager.PERMISSION_GRANTED) {
10852            throw new SecurityException("Requires permission "
10853                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10854        }
10855
10856        synchronized (this) {
10857            final long now = SystemClock.uptimeMillis();
10858            final long timeSinceLastIdle = now - mLastIdleTime;
10859            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10860            mLastIdleTime = now;
10861            mLowRamTimeSinceLastIdle = 0;
10862            if (mLowRamStartTime != 0) {
10863                mLowRamStartTime = now;
10864            }
10865
10866            StringBuilder sb = new StringBuilder(128);
10867            sb.append("Idle maintenance over ");
10868            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10869            sb.append(" low RAM for ");
10870            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10871            Slog.i(TAG, sb.toString());
10872
10873            // If at least 1/3 of our time since the last idle period has been spent
10874            // with RAM low, then we want to kill processes.
10875            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10876
10877            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10878                ProcessRecord proc = mLruProcesses.get(i);
10879                if (proc.notCachedSinceIdle) {
10880                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10881                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10882                        if (doKilling && proc.initialIdlePss != 0
10883                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10884                            proc.kill("idle maint (pss " + proc.lastPss
10885                                    + " from " + proc.initialIdlePss + ")", true);
10886                        }
10887                    }
10888                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10889                    proc.notCachedSinceIdle = true;
10890                    proc.initialIdlePss = 0;
10891                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10892                            isSleeping(), now);
10893                }
10894            }
10895
10896            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10897            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10898        }
10899    }
10900
10901    private void retrieveSettings() {
10902        final ContentResolver resolver = mContext.getContentResolver();
10903        String debugApp = Settings.Global.getString(
10904            resolver, Settings.Global.DEBUG_APP);
10905        boolean waitForDebugger = Settings.Global.getInt(
10906            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10907        boolean alwaysFinishActivities = Settings.Global.getInt(
10908            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10909        boolean forceRtl = Settings.Global.getInt(
10910                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10911        // Transfer any global setting for forcing RTL layout, into a System Property
10912        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10913
10914        Configuration configuration = new Configuration();
10915        Settings.System.getConfiguration(resolver, configuration);
10916        if (forceRtl) {
10917            // This will take care of setting the correct layout direction flags
10918            configuration.setLayoutDirection(configuration.locale);
10919        }
10920
10921        synchronized (this) {
10922            mDebugApp = mOrigDebugApp = debugApp;
10923            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10924            mAlwaysFinishActivities = alwaysFinishActivities;
10925            // This happens before any activities are started, so we can
10926            // change mConfiguration in-place.
10927            updateConfigurationLocked(configuration, null, false, true);
10928            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10929        }
10930    }
10931
10932    /** Loads resources after the current configuration has been set. */
10933    private void loadResourcesOnSystemReady() {
10934        final Resources res = mContext.getResources();
10935        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10936        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10937        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10938    }
10939
10940    public boolean testIsSystemReady() {
10941        // no need to synchronize(this) just to read & return the value
10942        return mSystemReady;
10943    }
10944
10945    private static File getCalledPreBootReceiversFile() {
10946        File dataDir = Environment.getDataDirectory();
10947        File systemDir = new File(dataDir, "system");
10948        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10949        return fname;
10950    }
10951
10952    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10953        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10954        File file = getCalledPreBootReceiversFile();
10955        FileInputStream fis = null;
10956        try {
10957            fis = new FileInputStream(file);
10958            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10959            int fvers = dis.readInt();
10960            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10961                String vers = dis.readUTF();
10962                String codename = dis.readUTF();
10963                String build = dis.readUTF();
10964                if (android.os.Build.VERSION.RELEASE.equals(vers)
10965                        && android.os.Build.VERSION.CODENAME.equals(codename)
10966                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10967                    int num = dis.readInt();
10968                    while (num > 0) {
10969                        num--;
10970                        String pkg = dis.readUTF();
10971                        String cls = dis.readUTF();
10972                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10973                    }
10974                }
10975            }
10976        } catch (FileNotFoundException e) {
10977        } catch (IOException e) {
10978            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10979        } finally {
10980            if (fis != null) {
10981                try {
10982                    fis.close();
10983                } catch (IOException e) {
10984                }
10985            }
10986        }
10987        return lastDoneReceivers;
10988    }
10989
10990    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10991        File file = getCalledPreBootReceiversFile();
10992        FileOutputStream fos = null;
10993        DataOutputStream dos = null;
10994        try {
10995            fos = new FileOutputStream(file);
10996            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10997            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10998            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10999            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11000            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11001            dos.writeInt(list.size());
11002            for (int i=0; i<list.size(); i++) {
11003                dos.writeUTF(list.get(i).getPackageName());
11004                dos.writeUTF(list.get(i).getClassName());
11005            }
11006        } catch (IOException e) {
11007            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11008            file.delete();
11009        } finally {
11010            FileUtils.sync(fos);
11011            if (dos != null) {
11012                try {
11013                    dos.close();
11014                } catch (IOException e) {
11015                    // TODO Auto-generated catch block
11016                    e.printStackTrace();
11017                }
11018            }
11019        }
11020    }
11021
11022    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11023            ArrayList<ComponentName> doneReceivers, int userId) {
11024        boolean waitingUpdate = false;
11025        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11026        List<ResolveInfo> ris = null;
11027        try {
11028            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11029                    intent, null, 0, userId);
11030        } catch (RemoteException e) {
11031        }
11032        if (ris != null) {
11033            for (int i=ris.size()-1; i>=0; i--) {
11034                if ((ris.get(i).activityInfo.applicationInfo.flags
11035                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11036                    ris.remove(i);
11037                }
11038            }
11039            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11040
11041            // For User 0, load the version number. When delivering to a new user, deliver
11042            // to all receivers.
11043            if (userId == UserHandle.USER_OWNER) {
11044                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11045                for (int i=0; i<ris.size(); i++) {
11046                    ActivityInfo ai = ris.get(i).activityInfo;
11047                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11048                    if (lastDoneReceivers.contains(comp)) {
11049                        // We already did the pre boot receiver for this app with the current
11050                        // platform version, so don't do it again...
11051                        ris.remove(i);
11052                        i--;
11053                        // ...however, do keep it as one that has been done, so we don't
11054                        // forget about it when rewriting the file of last done receivers.
11055                        doneReceivers.add(comp);
11056                    }
11057                }
11058            }
11059
11060            // If primary user, send broadcast to all available users, else just to userId
11061            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11062                    : new int[] { userId };
11063            for (int i = 0; i < ris.size(); i++) {
11064                ActivityInfo ai = ris.get(i).activityInfo;
11065                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11066                doneReceivers.add(comp);
11067                intent.setComponent(comp);
11068                for (int j=0; j<users.length; j++) {
11069                    IIntentReceiver finisher = null;
11070                    // On last receiver and user, set up a completion callback
11071                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11072                        finisher = new IIntentReceiver.Stub() {
11073                            public void performReceive(Intent intent, int resultCode,
11074                                    String data, Bundle extras, boolean ordered,
11075                                    boolean sticky, int sendingUser) {
11076                                // The raw IIntentReceiver interface is called
11077                                // with the AM lock held, so redispatch to
11078                                // execute our code without the lock.
11079                                mHandler.post(onFinishCallback);
11080                            }
11081                        };
11082                    }
11083                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11084                            + " for user " + users[j]);
11085                    broadcastIntentLocked(null, null, intent, null, finisher,
11086                            0, null, null, null, AppOpsManager.OP_NONE,
11087                            true, false, MY_PID, Process.SYSTEM_UID,
11088                            users[j]);
11089                    if (finisher != null) {
11090                        waitingUpdate = true;
11091                    }
11092                }
11093            }
11094        }
11095
11096        return waitingUpdate;
11097    }
11098
11099    public void systemReady(final Runnable goingCallback) {
11100        synchronized(this) {
11101            if (mSystemReady) {
11102                // If we're done calling all the receivers, run the next "boot phase" passed in
11103                // by the SystemServer
11104                if (goingCallback != null) {
11105                    goingCallback.run();
11106                }
11107                return;
11108            }
11109
11110            // Make sure we have the current profile info, since it is needed for
11111            // security checks.
11112            updateCurrentProfileIdsLocked();
11113
11114            if (mRecentTasks == null) {
11115                mRecentTasks = mTaskPersister.restoreTasksLocked();
11116                if (!mRecentTasks.isEmpty()) {
11117                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11118                }
11119                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11120                mTaskPersister.startPersisting();
11121            }
11122
11123            // Check to see if there are any update receivers to run.
11124            if (!mDidUpdate) {
11125                if (mWaitingUpdate) {
11126                    return;
11127                }
11128                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11129                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11130                    public void run() {
11131                        synchronized (ActivityManagerService.this) {
11132                            mDidUpdate = true;
11133                        }
11134                        writeLastDonePreBootReceivers(doneReceivers);
11135                        showBootMessage(mContext.getText(
11136                                R.string.android_upgrading_complete),
11137                                false);
11138                        systemReady(goingCallback);
11139                    }
11140                }, doneReceivers, UserHandle.USER_OWNER);
11141
11142                if (mWaitingUpdate) {
11143                    return;
11144                }
11145                mDidUpdate = true;
11146            }
11147
11148            mAppOpsService.systemReady();
11149            mSystemReady = true;
11150        }
11151
11152        ArrayList<ProcessRecord> procsToKill = null;
11153        synchronized(mPidsSelfLocked) {
11154            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11155                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11156                if (!isAllowedWhileBooting(proc.info)){
11157                    if (procsToKill == null) {
11158                        procsToKill = new ArrayList<ProcessRecord>();
11159                    }
11160                    procsToKill.add(proc);
11161                }
11162            }
11163        }
11164
11165        synchronized(this) {
11166            if (procsToKill != null) {
11167                for (int i=procsToKill.size()-1; i>=0; i--) {
11168                    ProcessRecord proc = procsToKill.get(i);
11169                    Slog.i(TAG, "Removing system update proc: " + proc);
11170                    removeProcessLocked(proc, true, false, "system update done");
11171                }
11172            }
11173
11174            // Now that we have cleaned up any update processes, we
11175            // are ready to start launching real processes and know that
11176            // we won't trample on them any more.
11177            mProcessesReady = true;
11178        }
11179
11180        Slog.i(TAG, "System now ready");
11181        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11182            SystemClock.uptimeMillis());
11183
11184        synchronized(this) {
11185            // Make sure we have no pre-ready processes sitting around.
11186
11187            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11188                ResolveInfo ri = mContext.getPackageManager()
11189                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11190                                STOCK_PM_FLAGS);
11191                CharSequence errorMsg = null;
11192                if (ri != null) {
11193                    ActivityInfo ai = ri.activityInfo;
11194                    ApplicationInfo app = ai.applicationInfo;
11195                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11196                        mTopAction = Intent.ACTION_FACTORY_TEST;
11197                        mTopData = null;
11198                        mTopComponent = new ComponentName(app.packageName,
11199                                ai.name);
11200                    } else {
11201                        errorMsg = mContext.getResources().getText(
11202                                com.android.internal.R.string.factorytest_not_system);
11203                    }
11204                } else {
11205                    errorMsg = mContext.getResources().getText(
11206                            com.android.internal.R.string.factorytest_no_action);
11207                }
11208                if (errorMsg != null) {
11209                    mTopAction = null;
11210                    mTopData = null;
11211                    mTopComponent = null;
11212                    Message msg = Message.obtain();
11213                    msg.what = SHOW_FACTORY_ERROR_MSG;
11214                    msg.getData().putCharSequence("msg", errorMsg);
11215                    mHandler.sendMessage(msg);
11216                }
11217            }
11218        }
11219
11220        retrieveSettings();
11221        loadResourcesOnSystemReady();
11222
11223        synchronized (this) {
11224            readGrantedUriPermissionsLocked();
11225        }
11226
11227        if (goingCallback != null) goingCallback.run();
11228
11229        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11230                Integer.toString(mCurrentUserId), mCurrentUserId);
11231        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11232                Integer.toString(mCurrentUserId), mCurrentUserId);
11233        mSystemServiceManager.startUser(mCurrentUserId);
11234
11235        synchronized (this) {
11236            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11237                try {
11238                    List apps = AppGlobals.getPackageManager().
11239                        getPersistentApplications(STOCK_PM_FLAGS);
11240                    if (apps != null) {
11241                        int N = apps.size();
11242                        int i;
11243                        for (i=0; i<N; i++) {
11244                            ApplicationInfo info
11245                                = (ApplicationInfo)apps.get(i);
11246                            if (info != null &&
11247                                    !info.packageName.equals("android")) {
11248                                addAppLocked(info, false, null /* ABI override */);
11249                            }
11250                        }
11251                    }
11252                } catch (RemoteException ex) {
11253                    // pm is in same process, this will never happen.
11254                }
11255            }
11256
11257            // Start up initial activity.
11258            mBooting = true;
11259            startHomeActivityLocked(mCurrentUserId);
11260
11261            try {
11262                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11263                    Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11264                            + " data partition or your device will be unstable.");
11265                    mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11266                }
11267            } catch (RemoteException e) {
11268            }
11269
11270            if (!Build.isFingerprintConsistent()) {
11271                Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11272                mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11273            }
11274
11275            long ident = Binder.clearCallingIdentity();
11276            try {
11277                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11278                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11279                        | Intent.FLAG_RECEIVER_FOREGROUND);
11280                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11281                broadcastIntentLocked(null, null, intent,
11282                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11283                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11284                intent = new Intent(Intent.ACTION_USER_STARTING);
11285                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11286                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11287                broadcastIntentLocked(null, null, intent,
11288                        null, new IIntentReceiver.Stub() {
11289                            @Override
11290                            public void performReceive(Intent intent, int resultCode, String data,
11291                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11292                                    throws RemoteException {
11293                            }
11294                        }, 0, null, null,
11295                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11296                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11297            } catch (Throwable t) {
11298                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11299            } finally {
11300                Binder.restoreCallingIdentity(ident);
11301            }
11302            mStackSupervisor.resumeTopActivitiesLocked();
11303            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11304        }
11305    }
11306
11307    private boolean makeAppCrashingLocked(ProcessRecord app,
11308            String shortMsg, String longMsg, String stackTrace) {
11309        app.crashing = true;
11310        app.crashingReport = generateProcessError(app,
11311                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11312        startAppProblemLocked(app);
11313        app.stopFreezingAllLocked();
11314        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11315    }
11316
11317    private void makeAppNotRespondingLocked(ProcessRecord app,
11318            String activity, String shortMsg, String longMsg) {
11319        app.notResponding = true;
11320        app.notRespondingReport = generateProcessError(app,
11321                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11322                activity, shortMsg, longMsg, null);
11323        startAppProblemLocked(app);
11324        app.stopFreezingAllLocked();
11325    }
11326
11327    /**
11328     * Generate a process error record, suitable for attachment to a ProcessRecord.
11329     *
11330     * @param app The ProcessRecord in which the error occurred.
11331     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11332     *                      ActivityManager.AppErrorStateInfo
11333     * @param activity The activity associated with the crash, if known.
11334     * @param shortMsg Short message describing the crash.
11335     * @param longMsg Long message describing the crash.
11336     * @param stackTrace Full crash stack trace, may be null.
11337     *
11338     * @return Returns a fully-formed AppErrorStateInfo record.
11339     */
11340    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11341            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11342        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11343
11344        report.condition = condition;
11345        report.processName = app.processName;
11346        report.pid = app.pid;
11347        report.uid = app.info.uid;
11348        report.tag = activity;
11349        report.shortMsg = shortMsg;
11350        report.longMsg = longMsg;
11351        report.stackTrace = stackTrace;
11352
11353        return report;
11354    }
11355
11356    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11357        synchronized (this) {
11358            app.crashing = false;
11359            app.crashingReport = null;
11360            app.notResponding = false;
11361            app.notRespondingReport = null;
11362            if (app.anrDialog == fromDialog) {
11363                app.anrDialog = null;
11364            }
11365            if (app.waitDialog == fromDialog) {
11366                app.waitDialog = null;
11367            }
11368            if (app.pid > 0 && app.pid != MY_PID) {
11369                handleAppCrashLocked(app, null, null, null);
11370                app.kill("user request after error", true);
11371            }
11372        }
11373    }
11374
11375    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11376            String stackTrace) {
11377        long now = SystemClock.uptimeMillis();
11378
11379        Long crashTime;
11380        if (!app.isolated) {
11381            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11382        } else {
11383            crashTime = null;
11384        }
11385        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11386            // This process loses!
11387            Slog.w(TAG, "Process " + app.info.processName
11388                    + " has crashed too many times: killing!");
11389            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11390                    app.userId, app.info.processName, app.uid);
11391            mStackSupervisor.handleAppCrashLocked(app);
11392            if (!app.persistent) {
11393                // We don't want to start this process again until the user
11394                // explicitly does so...  but for persistent process, we really
11395                // need to keep it running.  If a persistent process is actually
11396                // repeatedly crashing, then badness for everyone.
11397                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11398                        app.info.processName);
11399                if (!app.isolated) {
11400                    // XXX We don't have a way to mark isolated processes
11401                    // as bad, since they don't have a peristent identity.
11402                    mBadProcesses.put(app.info.processName, app.uid,
11403                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11404                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11405                }
11406                app.bad = true;
11407                app.removed = true;
11408                // Don't let services in this process be restarted and potentially
11409                // annoy the user repeatedly.  Unless it is persistent, since those
11410                // processes run critical code.
11411                removeProcessLocked(app, false, false, "crash");
11412                mStackSupervisor.resumeTopActivitiesLocked();
11413                return false;
11414            }
11415            mStackSupervisor.resumeTopActivitiesLocked();
11416        } else {
11417            mStackSupervisor.finishTopRunningActivityLocked(app);
11418        }
11419
11420        // Bump up the crash count of any services currently running in the proc.
11421        for (int i=app.services.size()-1; i>=0; i--) {
11422            // Any services running in the application need to be placed
11423            // back in the pending list.
11424            ServiceRecord sr = app.services.valueAt(i);
11425            sr.crashCount++;
11426        }
11427
11428        // If the crashing process is what we consider to be the "home process" and it has been
11429        // replaced by a third-party app, clear the package preferred activities from packages
11430        // with a home activity running in the process to prevent a repeatedly crashing app
11431        // from blocking the user to manually clear the list.
11432        final ArrayList<ActivityRecord> activities = app.activities;
11433        if (app == mHomeProcess && activities.size() > 0
11434                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11435            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11436                final ActivityRecord r = activities.get(activityNdx);
11437                if (r.isHomeActivity()) {
11438                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11439                    try {
11440                        ActivityThread.getPackageManager()
11441                                .clearPackagePreferredActivities(r.packageName);
11442                    } catch (RemoteException c) {
11443                        // pm is in same process, this will never happen.
11444                    }
11445                }
11446            }
11447        }
11448
11449        if (!app.isolated) {
11450            // XXX Can't keep track of crash times for isolated processes,
11451            // because they don't have a perisistent identity.
11452            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11453        }
11454
11455        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11456        return true;
11457    }
11458
11459    void startAppProblemLocked(ProcessRecord app) {
11460        // If this app is not running under the current user, then we
11461        // can't give it a report button because that would require
11462        // launching the report UI under a different user.
11463        app.errorReportReceiver = null;
11464
11465        for (int userId : mCurrentProfileIds) {
11466            if (app.userId == userId) {
11467                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11468                        mContext, app.info.packageName, app.info.flags);
11469            }
11470        }
11471        skipCurrentReceiverLocked(app);
11472    }
11473
11474    void skipCurrentReceiverLocked(ProcessRecord app) {
11475        for (BroadcastQueue queue : mBroadcastQueues) {
11476            queue.skipCurrentReceiverLocked(app);
11477        }
11478    }
11479
11480    /**
11481     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11482     * The application process will exit immediately after this call returns.
11483     * @param app object of the crashing app, null for the system server
11484     * @param crashInfo describing the exception
11485     */
11486    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11487        ProcessRecord r = findAppProcess(app, "Crash");
11488        final String processName = app == null ? "system_server"
11489                : (r == null ? "unknown" : r.processName);
11490
11491        handleApplicationCrashInner("crash", r, processName, crashInfo);
11492    }
11493
11494    /* Native crash reporting uses this inner version because it needs to be somewhat
11495     * decoupled from the AM-managed cleanup lifecycle
11496     */
11497    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11498            ApplicationErrorReport.CrashInfo crashInfo) {
11499        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11500                UserHandle.getUserId(Binder.getCallingUid()), processName,
11501                r == null ? -1 : r.info.flags,
11502                crashInfo.exceptionClassName,
11503                crashInfo.exceptionMessage,
11504                crashInfo.throwFileName,
11505                crashInfo.throwLineNumber);
11506
11507        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11508
11509        crashApplication(r, crashInfo);
11510    }
11511
11512    public void handleApplicationStrictModeViolation(
11513            IBinder app,
11514            int violationMask,
11515            StrictMode.ViolationInfo info) {
11516        ProcessRecord r = findAppProcess(app, "StrictMode");
11517        if (r == null) {
11518            return;
11519        }
11520
11521        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11522            Integer stackFingerprint = info.hashCode();
11523            boolean logIt = true;
11524            synchronized (mAlreadyLoggedViolatedStacks) {
11525                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11526                    logIt = false;
11527                    // TODO: sub-sample into EventLog for these, with
11528                    // the info.durationMillis?  Then we'd get
11529                    // the relative pain numbers, without logging all
11530                    // the stack traces repeatedly.  We'd want to do
11531                    // likewise in the client code, which also does
11532                    // dup suppression, before the Binder call.
11533                } else {
11534                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11535                        mAlreadyLoggedViolatedStacks.clear();
11536                    }
11537                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11538                }
11539            }
11540            if (logIt) {
11541                logStrictModeViolationToDropBox(r, info);
11542            }
11543        }
11544
11545        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11546            AppErrorResult result = new AppErrorResult();
11547            synchronized (this) {
11548                final long origId = Binder.clearCallingIdentity();
11549
11550                Message msg = Message.obtain();
11551                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11552                HashMap<String, Object> data = new HashMap<String, Object>();
11553                data.put("result", result);
11554                data.put("app", r);
11555                data.put("violationMask", violationMask);
11556                data.put("info", info);
11557                msg.obj = data;
11558                mHandler.sendMessage(msg);
11559
11560                Binder.restoreCallingIdentity(origId);
11561            }
11562            int res = result.get();
11563            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11564        }
11565    }
11566
11567    // Depending on the policy in effect, there could be a bunch of
11568    // these in quick succession so we try to batch these together to
11569    // minimize disk writes, number of dropbox entries, and maximize
11570    // compression, by having more fewer, larger records.
11571    private void logStrictModeViolationToDropBox(
11572            ProcessRecord process,
11573            StrictMode.ViolationInfo info) {
11574        if (info == null) {
11575            return;
11576        }
11577        final boolean isSystemApp = process == null ||
11578                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11579                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11580        final String processName = process == null ? "unknown" : process.processName;
11581        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11582        final DropBoxManager dbox = (DropBoxManager)
11583                mContext.getSystemService(Context.DROPBOX_SERVICE);
11584
11585        // Exit early if the dropbox isn't configured to accept this report type.
11586        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11587
11588        boolean bufferWasEmpty;
11589        boolean needsFlush;
11590        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11591        synchronized (sb) {
11592            bufferWasEmpty = sb.length() == 0;
11593            appendDropBoxProcessHeaders(process, processName, sb);
11594            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11595            sb.append("System-App: ").append(isSystemApp).append("\n");
11596            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11597            if (info.violationNumThisLoop != 0) {
11598                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11599            }
11600            if (info.numAnimationsRunning != 0) {
11601                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11602            }
11603            if (info.broadcastIntentAction != null) {
11604                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11605            }
11606            if (info.durationMillis != -1) {
11607                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11608            }
11609            if (info.numInstances != -1) {
11610                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11611            }
11612            if (info.tags != null) {
11613                for (String tag : info.tags) {
11614                    sb.append("Span-Tag: ").append(tag).append("\n");
11615                }
11616            }
11617            sb.append("\n");
11618            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11619                sb.append(info.crashInfo.stackTrace);
11620            }
11621            sb.append("\n");
11622
11623            // Only buffer up to ~64k.  Various logging bits truncate
11624            // things at 128k.
11625            needsFlush = (sb.length() > 64 * 1024);
11626        }
11627
11628        // Flush immediately if the buffer's grown too large, or this
11629        // is a non-system app.  Non-system apps are isolated with a
11630        // different tag & policy and not batched.
11631        //
11632        // Batching is useful during internal testing with
11633        // StrictMode settings turned up high.  Without batching,
11634        // thousands of separate files could be created on boot.
11635        if (!isSystemApp || needsFlush) {
11636            new Thread("Error dump: " + dropboxTag) {
11637                @Override
11638                public void run() {
11639                    String report;
11640                    synchronized (sb) {
11641                        report = sb.toString();
11642                        sb.delete(0, sb.length());
11643                        sb.trimToSize();
11644                    }
11645                    if (report.length() != 0) {
11646                        dbox.addText(dropboxTag, report);
11647                    }
11648                }
11649            }.start();
11650            return;
11651        }
11652
11653        // System app batching:
11654        if (!bufferWasEmpty) {
11655            // An existing dropbox-writing thread is outstanding, so
11656            // we don't need to start it up.  The existing thread will
11657            // catch the buffer appends we just did.
11658            return;
11659        }
11660
11661        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11662        // (After this point, we shouldn't access AMS internal data structures.)
11663        new Thread("Error dump: " + dropboxTag) {
11664            @Override
11665            public void run() {
11666                // 5 second sleep to let stacks arrive and be batched together
11667                try {
11668                    Thread.sleep(5000);  // 5 seconds
11669                } catch (InterruptedException e) {}
11670
11671                String errorReport;
11672                synchronized (mStrictModeBuffer) {
11673                    errorReport = mStrictModeBuffer.toString();
11674                    if (errorReport.length() == 0) {
11675                        return;
11676                    }
11677                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11678                    mStrictModeBuffer.trimToSize();
11679                }
11680                dbox.addText(dropboxTag, errorReport);
11681            }
11682        }.start();
11683    }
11684
11685    /**
11686     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11687     * @param app object of the crashing app, null for the system server
11688     * @param tag reported by the caller
11689     * @param system whether this wtf is coming from the system
11690     * @param crashInfo describing the context of the error
11691     * @return true if the process should exit immediately (WTF is fatal)
11692     */
11693    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11694            final ApplicationErrorReport.CrashInfo crashInfo) {
11695        final int callingUid = Binder.getCallingUid();
11696        final int callingPid = Binder.getCallingPid();
11697
11698        if (system) {
11699            // If this is coming from the system, we could very well have low-level
11700            // system locks held, so we want to do this all asynchronously.  And we
11701            // never want this to become fatal, so there is that too.
11702            mHandler.post(new Runnable() {
11703                @Override public void run() {
11704                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11705                }
11706            });
11707            return false;
11708        }
11709
11710        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11711                crashInfo);
11712
11713        if (r != null && r.pid != Process.myPid() &&
11714                Settings.Global.getInt(mContext.getContentResolver(),
11715                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11716            crashApplication(r, crashInfo);
11717            return true;
11718        } else {
11719            return false;
11720        }
11721    }
11722
11723    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11724            final ApplicationErrorReport.CrashInfo crashInfo) {
11725        final ProcessRecord r = findAppProcess(app, "WTF");
11726        final String processName = app == null ? "system_server"
11727                : (r == null ? "unknown" : r.processName);
11728
11729        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11730                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11731
11732        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11733
11734        return r;
11735    }
11736
11737    /**
11738     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11739     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11740     */
11741    private ProcessRecord findAppProcess(IBinder app, String reason) {
11742        if (app == null) {
11743            return null;
11744        }
11745
11746        synchronized (this) {
11747            final int NP = mProcessNames.getMap().size();
11748            for (int ip=0; ip<NP; ip++) {
11749                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11750                final int NA = apps.size();
11751                for (int ia=0; ia<NA; ia++) {
11752                    ProcessRecord p = apps.valueAt(ia);
11753                    if (p.thread != null && p.thread.asBinder() == app) {
11754                        return p;
11755                    }
11756                }
11757            }
11758
11759            Slog.w(TAG, "Can't find mystery application for " + reason
11760                    + " from pid=" + Binder.getCallingPid()
11761                    + " uid=" + Binder.getCallingUid() + ": " + app);
11762            return null;
11763        }
11764    }
11765
11766    /**
11767     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11768     * to append various headers to the dropbox log text.
11769     */
11770    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11771            StringBuilder sb) {
11772        // Watchdog thread ends up invoking this function (with
11773        // a null ProcessRecord) to add the stack file to dropbox.
11774        // Do not acquire a lock on this (am) in such cases, as it
11775        // could cause a potential deadlock, if and when watchdog
11776        // is invoked due to unavailability of lock on am and it
11777        // would prevent watchdog from killing system_server.
11778        if (process == null) {
11779            sb.append("Process: ").append(processName).append("\n");
11780            return;
11781        }
11782        // Note: ProcessRecord 'process' is guarded by the service
11783        // instance.  (notably process.pkgList, which could otherwise change
11784        // concurrently during execution of this method)
11785        synchronized (this) {
11786            sb.append("Process: ").append(processName).append("\n");
11787            int flags = process.info.flags;
11788            IPackageManager pm = AppGlobals.getPackageManager();
11789            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11790            for (int ip=0; ip<process.pkgList.size(); ip++) {
11791                String pkg = process.pkgList.keyAt(ip);
11792                sb.append("Package: ").append(pkg);
11793                try {
11794                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11795                    if (pi != null) {
11796                        sb.append(" v").append(pi.versionCode);
11797                        if (pi.versionName != null) {
11798                            sb.append(" (").append(pi.versionName).append(")");
11799                        }
11800                    }
11801                } catch (RemoteException e) {
11802                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11803                }
11804                sb.append("\n");
11805            }
11806        }
11807    }
11808
11809    private static String processClass(ProcessRecord process) {
11810        if (process == null || process.pid == MY_PID) {
11811            return "system_server";
11812        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11813            return "system_app";
11814        } else {
11815            return "data_app";
11816        }
11817    }
11818
11819    /**
11820     * Write a description of an error (crash, WTF, ANR) to the drop box.
11821     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11822     * @param process which caused the error, null means the system server
11823     * @param activity which triggered the error, null if unknown
11824     * @param parent activity related to the error, null if unknown
11825     * @param subject line related to the error, null if absent
11826     * @param report in long form describing the error, null if absent
11827     * @param logFile to include in the report, null if none
11828     * @param crashInfo giving an application stack trace, null if absent
11829     */
11830    public void addErrorToDropBox(String eventType,
11831            ProcessRecord process, String processName, ActivityRecord activity,
11832            ActivityRecord parent, String subject,
11833            final String report, final File logFile,
11834            final ApplicationErrorReport.CrashInfo crashInfo) {
11835        // NOTE -- this must never acquire the ActivityManagerService lock,
11836        // otherwise the watchdog may be prevented from resetting the system.
11837
11838        final String dropboxTag = processClass(process) + "_" + eventType;
11839        final DropBoxManager dbox = (DropBoxManager)
11840                mContext.getSystemService(Context.DROPBOX_SERVICE);
11841
11842        // Exit early if the dropbox isn't configured to accept this report type.
11843        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11844
11845        final StringBuilder sb = new StringBuilder(1024);
11846        appendDropBoxProcessHeaders(process, processName, sb);
11847        if (activity != null) {
11848            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11849        }
11850        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11851            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11852        }
11853        if (parent != null && parent != activity) {
11854            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11855        }
11856        if (subject != null) {
11857            sb.append("Subject: ").append(subject).append("\n");
11858        }
11859        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11860        if (Debug.isDebuggerConnected()) {
11861            sb.append("Debugger: Connected\n");
11862        }
11863        sb.append("\n");
11864
11865        // Do the rest in a worker thread to avoid blocking the caller on I/O
11866        // (After this point, we shouldn't access AMS internal data structures.)
11867        Thread worker = new Thread("Error dump: " + dropboxTag) {
11868            @Override
11869            public void run() {
11870                if (report != null) {
11871                    sb.append(report);
11872                }
11873                if (logFile != null) {
11874                    try {
11875                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11876                                    "\n\n[[TRUNCATED]]"));
11877                    } catch (IOException e) {
11878                        Slog.e(TAG, "Error reading " + logFile, e);
11879                    }
11880                }
11881                if (crashInfo != null && crashInfo.stackTrace != null) {
11882                    sb.append(crashInfo.stackTrace);
11883                }
11884
11885                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11886                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11887                if (lines > 0) {
11888                    sb.append("\n");
11889
11890                    // Merge several logcat streams, and take the last N lines
11891                    InputStreamReader input = null;
11892                    try {
11893                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11894                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11895                                "-b", "crash",
11896                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11897
11898                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11899                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11900                        input = new InputStreamReader(logcat.getInputStream());
11901
11902                        int num;
11903                        char[] buf = new char[8192];
11904                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11905                    } catch (IOException e) {
11906                        Slog.e(TAG, "Error running logcat", e);
11907                    } finally {
11908                        if (input != null) try { input.close(); } catch (IOException e) {}
11909                    }
11910                }
11911
11912                dbox.addText(dropboxTag, sb.toString());
11913            }
11914        };
11915
11916        if (process == null) {
11917            // If process is null, we are being called from some internal code
11918            // and may be about to die -- run this synchronously.
11919            worker.run();
11920        } else {
11921            worker.start();
11922        }
11923    }
11924
11925    /**
11926     * Bring up the "unexpected error" dialog box for a crashing app.
11927     * Deal with edge cases (intercepts from instrumented applications,
11928     * ActivityController, error intent receivers, that sort of thing).
11929     * @param r the application crashing
11930     * @param crashInfo describing the failure
11931     */
11932    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11933        long timeMillis = System.currentTimeMillis();
11934        String shortMsg = crashInfo.exceptionClassName;
11935        String longMsg = crashInfo.exceptionMessage;
11936        String stackTrace = crashInfo.stackTrace;
11937        if (shortMsg != null && longMsg != null) {
11938            longMsg = shortMsg + ": " + longMsg;
11939        } else if (shortMsg != null) {
11940            longMsg = shortMsg;
11941        }
11942
11943        AppErrorResult result = new AppErrorResult();
11944        synchronized (this) {
11945            if (mController != null) {
11946                try {
11947                    String name = r != null ? r.processName : null;
11948                    int pid = r != null ? r.pid : Binder.getCallingPid();
11949                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11950                    if (!mController.appCrashed(name, pid,
11951                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11952                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11953                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11954                            Slog.w(TAG, "Skip killing native crashed app " + name
11955                                    + "(" + pid + ") during testing");
11956                        } else {
11957                            Slog.w(TAG, "Force-killing crashed app " + name
11958                                    + " at watcher's request");
11959                            if (r != null) {
11960                                r.kill("crash", true);
11961                            } else {
11962                                // Huh.
11963                                Process.killProcess(pid);
11964                                Process.killProcessGroup(uid, pid);
11965                            }
11966                        }
11967                        return;
11968                    }
11969                } catch (RemoteException e) {
11970                    mController = null;
11971                    Watchdog.getInstance().setActivityController(null);
11972                }
11973            }
11974
11975            final long origId = Binder.clearCallingIdentity();
11976
11977            // If this process is running instrumentation, finish it.
11978            if (r != null && r.instrumentationClass != null) {
11979                Slog.w(TAG, "Error in app " + r.processName
11980                      + " running instrumentation " + r.instrumentationClass + ":");
11981                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11982                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11983                Bundle info = new Bundle();
11984                info.putString("shortMsg", shortMsg);
11985                info.putString("longMsg", longMsg);
11986                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11987                Binder.restoreCallingIdentity(origId);
11988                return;
11989            }
11990
11991            // If we can't identify the process or it's already exceeded its crash quota,
11992            // quit right away without showing a crash dialog.
11993            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11994                Binder.restoreCallingIdentity(origId);
11995                return;
11996            }
11997
11998            Message msg = Message.obtain();
11999            msg.what = SHOW_ERROR_MSG;
12000            HashMap data = new HashMap();
12001            data.put("result", result);
12002            data.put("app", r);
12003            msg.obj = data;
12004            mHandler.sendMessage(msg);
12005
12006            Binder.restoreCallingIdentity(origId);
12007        }
12008
12009        int res = result.get();
12010
12011        Intent appErrorIntent = null;
12012        synchronized (this) {
12013            if (r != null && !r.isolated) {
12014                // XXX Can't keep track of crash time for isolated processes,
12015                // since they don't have a persistent identity.
12016                mProcessCrashTimes.put(r.info.processName, r.uid,
12017                        SystemClock.uptimeMillis());
12018            }
12019            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12020                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12021            }
12022        }
12023
12024        if (appErrorIntent != null) {
12025            try {
12026                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12027            } catch (ActivityNotFoundException e) {
12028                Slog.w(TAG, "bug report receiver dissappeared", e);
12029            }
12030        }
12031    }
12032
12033    Intent createAppErrorIntentLocked(ProcessRecord r,
12034            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12035        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12036        if (report == null) {
12037            return null;
12038        }
12039        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12040        result.setComponent(r.errorReportReceiver);
12041        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12042        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12043        return result;
12044    }
12045
12046    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12047            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12048        if (r.errorReportReceiver == null) {
12049            return null;
12050        }
12051
12052        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12053            return null;
12054        }
12055
12056        ApplicationErrorReport report = new ApplicationErrorReport();
12057        report.packageName = r.info.packageName;
12058        report.installerPackageName = r.errorReportReceiver.getPackageName();
12059        report.processName = r.processName;
12060        report.time = timeMillis;
12061        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12062
12063        if (r.crashing || r.forceCrashReport) {
12064            report.type = ApplicationErrorReport.TYPE_CRASH;
12065            report.crashInfo = crashInfo;
12066        } else if (r.notResponding) {
12067            report.type = ApplicationErrorReport.TYPE_ANR;
12068            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12069
12070            report.anrInfo.activity = r.notRespondingReport.tag;
12071            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12072            report.anrInfo.info = r.notRespondingReport.longMsg;
12073        }
12074
12075        return report;
12076    }
12077
12078    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12079        enforceNotIsolatedCaller("getProcessesInErrorState");
12080        // assume our apps are happy - lazy create the list
12081        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12082
12083        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12084                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12085        int userId = UserHandle.getUserId(Binder.getCallingUid());
12086
12087        synchronized (this) {
12088
12089            // iterate across all processes
12090            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12091                ProcessRecord app = mLruProcesses.get(i);
12092                if (!allUsers && app.userId != userId) {
12093                    continue;
12094                }
12095                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12096                    // This one's in trouble, so we'll generate a report for it
12097                    // crashes are higher priority (in case there's a crash *and* an anr)
12098                    ActivityManager.ProcessErrorStateInfo report = null;
12099                    if (app.crashing) {
12100                        report = app.crashingReport;
12101                    } else if (app.notResponding) {
12102                        report = app.notRespondingReport;
12103                    }
12104
12105                    if (report != null) {
12106                        if (errList == null) {
12107                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12108                        }
12109                        errList.add(report);
12110                    } else {
12111                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12112                                " crashing = " + app.crashing +
12113                                " notResponding = " + app.notResponding);
12114                    }
12115                }
12116            }
12117        }
12118
12119        return errList;
12120    }
12121
12122    static int procStateToImportance(int procState, int memAdj,
12123            ActivityManager.RunningAppProcessInfo currApp) {
12124        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12125        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12126            currApp.lru = memAdj;
12127        } else {
12128            currApp.lru = 0;
12129        }
12130        return imp;
12131    }
12132
12133    private void fillInProcMemInfo(ProcessRecord app,
12134            ActivityManager.RunningAppProcessInfo outInfo) {
12135        outInfo.pid = app.pid;
12136        outInfo.uid = app.info.uid;
12137        if (mHeavyWeightProcess == app) {
12138            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12139        }
12140        if (app.persistent) {
12141            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12142        }
12143        if (app.activities.size() > 0) {
12144            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12145        }
12146        outInfo.lastTrimLevel = app.trimMemoryLevel;
12147        int adj = app.curAdj;
12148        int procState = app.curProcState;
12149        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12150        outInfo.importanceReasonCode = app.adjTypeCode;
12151        outInfo.processState = app.curProcState;
12152    }
12153
12154    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12155        enforceNotIsolatedCaller("getRunningAppProcesses");
12156        // Lazy instantiation of list
12157        List<ActivityManager.RunningAppProcessInfo> runList = null;
12158        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12159                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12160        int userId = UserHandle.getUserId(Binder.getCallingUid());
12161        synchronized (this) {
12162            // Iterate across all processes
12163            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12164                ProcessRecord app = mLruProcesses.get(i);
12165                if (!allUsers && app.userId != userId) {
12166                    continue;
12167                }
12168                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12169                    // Generate process state info for running application
12170                    ActivityManager.RunningAppProcessInfo currApp =
12171                        new ActivityManager.RunningAppProcessInfo(app.processName,
12172                                app.pid, app.getPackageList());
12173                    fillInProcMemInfo(app, currApp);
12174                    if (app.adjSource instanceof ProcessRecord) {
12175                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12176                        currApp.importanceReasonImportance =
12177                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12178                                        app.adjSourceProcState);
12179                    } else if (app.adjSource instanceof ActivityRecord) {
12180                        ActivityRecord r = (ActivityRecord)app.adjSource;
12181                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12182                    }
12183                    if (app.adjTarget instanceof ComponentName) {
12184                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12185                    }
12186                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12187                    //        + " lru=" + currApp.lru);
12188                    if (runList == null) {
12189                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12190                    }
12191                    runList.add(currApp);
12192                }
12193            }
12194        }
12195        return runList;
12196    }
12197
12198    public List<ApplicationInfo> getRunningExternalApplications() {
12199        enforceNotIsolatedCaller("getRunningExternalApplications");
12200        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12201        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12202        if (runningApps != null && runningApps.size() > 0) {
12203            Set<String> extList = new HashSet<String>();
12204            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12205                if (app.pkgList != null) {
12206                    for (String pkg : app.pkgList) {
12207                        extList.add(pkg);
12208                    }
12209                }
12210            }
12211            IPackageManager pm = AppGlobals.getPackageManager();
12212            for (String pkg : extList) {
12213                try {
12214                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12215                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12216                        retList.add(info);
12217                    }
12218                } catch (RemoteException e) {
12219                }
12220            }
12221        }
12222        return retList;
12223    }
12224
12225    @Override
12226    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12227        enforceNotIsolatedCaller("getMyMemoryState");
12228        synchronized (this) {
12229            ProcessRecord proc;
12230            synchronized (mPidsSelfLocked) {
12231                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12232            }
12233            fillInProcMemInfo(proc, outInfo);
12234        }
12235    }
12236
12237    @Override
12238    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12239        if (checkCallingPermission(android.Manifest.permission.DUMP)
12240                != PackageManager.PERMISSION_GRANTED) {
12241            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12242                    + Binder.getCallingPid()
12243                    + ", uid=" + Binder.getCallingUid()
12244                    + " without permission "
12245                    + android.Manifest.permission.DUMP);
12246            return;
12247        }
12248
12249        boolean dumpAll = false;
12250        boolean dumpClient = false;
12251        String dumpPackage = null;
12252
12253        int opti = 0;
12254        while (opti < args.length) {
12255            String opt = args[opti];
12256            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12257                break;
12258            }
12259            opti++;
12260            if ("-a".equals(opt)) {
12261                dumpAll = true;
12262            } else if ("-c".equals(opt)) {
12263                dumpClient = true;
12264            } else if ("-h".equals(opt)) {
12265                pw.println("Activity manager dump options:");
12266                pw.println("  [-a] [-c] [-h] [cmd] ...");
12267                pw.println("  cmd may be one of:");
12268                pw.println("    a[ctivities]: activity stack state");
12269                pw.println("    r[recents]: recent activities state");
12270                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12271                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12272                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12273                pw.println("    o[om]: out of memory management");
12274                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12275                pw.println("    provider [COMP_SPEC]: provider client-side state");
12276                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12277                pw.println("    service [COMP_SPEC]: service client-side state");
12278                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12279                pw.println("    all: dump all activities");
12280                pw.println("    top: dump the top activity");
12281                pw.println("    write: write all pending state to storage");
12282                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12283                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12284                pw.println("    a partial substring in a component name, a");
12285                pw.println("    hex object identifier.");
12286                pw.println("  -a: include all available server state.");
12287                pw.println("  -c: include client state.");
12288                return;
12289            } else {
12290                pw.println("Unknown argument: " + opt + "; use -h for help");
12291            }
12292        }
12293
12294        long origId = Binder.clearCallingIdentity();
12295        boolean more = false;
12296        // Is the caller requesting to dump a particular piece of data?
12297        if (opti < args.length) {
12298            String cmd = args[opti];
12299            opti++;
12300            if ("activities".equals(cmd) || "a".equals(cmd)) {
12301                synchronized (this) {
12302                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12303                }
12304            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12305                synchronized (this) {
12306                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12307                }
12308            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12309                String[] newArgs;
12310                String name;
12311                if (opti >= args.length) {
12312                    name = null;
12313                    newArgs = EMPTY_STRING_ARRAY;
12314                } else {
12315                    name = args[opti];
12316                    opti++;
12317                    newArgs = new String[args.length - opti];
12318                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12319                            args.length - opti);
12320                }
12321                synchronized (this) {
12322                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12323                }
12324            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12325                String[] newArgs;
12326                String name;
12327                if (opti >= args.length) {
12328                    name = null;
12329                    newArgs = EMPTY_STRING_ARRAY;
12330                } else {
12331                    name = args[opti];
12332                    opti++;
12333                    newArgs = new String[args.length - opti];
12334                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12335                            args.length - opti);
12336                }
12337                synchronized (this) {
12338                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12339                }
12340            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12341                String[] newArgs;
12342                String name;
12343                if (opti >= args.length) {
12344                    name = null;
12345                    newArgs = EMPTY_STRING_ARRAY;
12346                } else {
12347                    name = args[opti];
12348                    opti++;
12349                    newArgs = new String[args.length - opti];
12350                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12351                            args.length - opti);
12352                }
12353                synchronized (this) {
12354                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12355                }
12356            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12357                synchronized (this) {
12358                    dumpOomLocked(fd, pw, args, opti, true);
12359                }
12360            } else if ("provider".equals(cmd)) {
12361                String[] newArgs;
12362                String name;
12363                if (opti >= args.length) {
12364                    name = null;
12365                    newArgs = EMPTY_STRING_ARRAY;
12366                } else {
12367                    name = args[opti];
12368                    opti++;
12369                    newArgs = new String[args.length - opti];
12370                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12371                }
12372                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12373                    pw.println("No providers match: " + name);
12374                    pw.println("Use -h for help.");
12375                }
12376            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12377                synchronized (this) {
12378                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12379                }
12380            } else if ("service".equals(cmd)) {
12381                String[] newArgs;
12382                String name;
12383                if (opti >= args.length) {
12384                    name = null;
12385                    newArgs = EMPTY_STRING_ARRAY;
12386                } else {
12387                    name = args[opti];
12388                    opti++;
12389                    newArgs = new String[args.length - opti];
12390                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12391                            args.length - opti);
12392                }
12393                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12394                    pw.println("No services match: " + name);
12395                    pw.println("Use -h for help.");
12396                }
12397            } else if ("package".equals(cmd)) {
12398                String[] newArgs;
12399                if (opti >= args.length) {
12400                    pw.println("package: no package name specified");
12401                    pw.println("Use -h for help.");
12402                } else {
12403                    dumpPackage = args[opti];
12404                    opti++;
12405                    newArgs = new String[args.length - opti];
12406                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12407                            args.length - opti);
12408                    args = newArgs;
12409                    opti = 0;
12410                    more = true;
12411                }
12412            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12413                synchronized (this) {
12414                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12415                }
12416            } else if ("write".equals(cmd)) {
12417                mTaskPersister.flush();
12418                pw.println("All tasks persisted.");
12419                return;
12420            } else {
12421                // Dumping a single activity?
12422                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12423                    pw.println("Bad activity command, or no activities match: " + cmd);
12424                    pw.println("Use -h for help.");
12425                }
12426            }
12427            if (!more) {
12428                Binder.restoreCallingIdentity(origId);
12429                return;
12430            }
12431        }
12432
12433        // No piece of data specified, dump everything.
12434        synchronized (this) {
12435            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12436            pw.println();
12437            if (dumpAll) {
12438                pw.println("-------------------------------------------------------------------------------");
12439            }
12440            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12441            pw.println();
12442            if (dumpAll) {
12443                pw.println("-------------------------------------------------------------------------------");
12444            }
12445            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12446            pw.println();
12447            if (dumpAll) {
12448                pw.println("-------------------------------------------------------------------------------");
12449            }
12450            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12451            pw.println();
12452            if (dumpAll) {
12453                pw.println("-------------------------------------------------------------------------------");
12454            }
12455            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12456            pw.println();
12457            if (dumpAll) {
12458                pw.println("-------------------------------------------------------------------------------");
12459            }
12460            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12461            pw.println();
12462            if (dumpAll) {
12463                pw.println("-------------------------------------------------------------------------------");
12464            }
12465            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12466        }
12467        Binder.restoreCallingIdentity(origId);
12468    }
12469
12470    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12471            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12472        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12473
12474        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12475                dumpPackage);
12476        boolean needSep = printedAnything;
12477
12478        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12479                dumpPackage, needSep, "  mFocusedActivity: ");
12480        if (printed) {
12481            printedAnything = true;
12482            needSep = false;
12483        }
12484
12485        if (dumpPackage == null) {
12486            if (needSep) {
12487                pw.println();
12488            }
12489            needSep = true;
12490            printedAnything = true;
12491            mStackSupervisor.dump(pw, "  ");
12492        }
12493
12494        if (!printedAnything) {
12495            pw.println("  (nothing)");
12496        }
12497    }
12498
12499    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12500            int opti, boolean dumpAll, String dumpPackage) {
12501        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12502
12503        boolean printedAnything = false;
12504
12505        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12506            boolean printedHeader = false;
12507
12508            final int N = mRecentTasks.size();
12509            for (int i=0; i<N; i++) {
12510                TaskRecord tr = mRecentTasks.get(i);
12511                if (dumpPackage != null) {
12512                    if (tr.realActivity == null ||
12513                            !dumpPackage.equals(tr.realActivity)) {
12514                        continue;
12515                    }
12516                }
12517                if (!printedHeader) {
12518                    pw.println("  Recent tasks:");
12519                    printedHeader = true;
12520                    printedAnything = true;
12521                }
12522                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12523                        pw.println(tr);
12524                if (dumpAll) {
12525                    mRecentTasks.get(i).dump(pw, "    ");
12526                }
12527            }
12528        }
12529
12530        if (!printedAnything) {
12531            pw.println("  (nothing)");
12532        }
12533    }
12534
12535    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12536            int opti, boolean dumpAll, String dumpPackage) {
12537        boolean needSep = false;
12538        boolean printedAnything = false;
12539        int numPers = 0;
12540
12541        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12542
12543        if (dumpAll) {
12544            final int NP = mProcessNames.getMap().size();
12545            for (int ip=0; ip<NP; ip++) {
12546                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12547                final int NA = procs.size();
12548                for (int ia=0; ia<NA; ia++) {
12549                    ProcessRecord r = procs.valueAt(ia);
12550                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12551                        continue;
12552                    }
12553                    if (!needSep) {
12554                        pw.println("  All known processes:");
12555                        needSep = true;
12556                        printedAnything = true;
12557                    }
12558                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12559                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12560                        pw.print(" "); pw.println(r);
12561                    r.dump(pw, "    ");
12562                    if (r.persistent) {
12563                        numPers++;
12564                    }
12565                }
12566            }
12567        }
12568
12569        if (mIsolatedProcesses.size() > 0) {
12570            boolean printed = false;
12571            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12572                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12573                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12574                    continue;
12575                }
12576                if (!printed) {
12577                    if (needSep) {
12578                        pw.println();
12579                    }
12580                    pw.println("  Isolated process list (sorted by uid):");
12581                    printedAnything = true;
12582                    printed = true;
12583                    needSep = true;
12584                }
12585                pw.println(String.format("%sIsolated #%2d: %s",
12586                        "    ", i, r.toString()));
12587            }
12588        }
12589
12590        if (mLruProcesses.size() > 0) {
12591            if (needSep) {
12592                pw.println();
12593            }
12594            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12595                    pw.print(" total, non-act at ");
12596                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12597                    pw.print(", non-svc at ");
12598                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12599                    pw.println("):");
12600            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12601            needSep = true;
12602            printedAnything = true;
12603        }
12604
12605        if (dumpAll || dumpPackage != null) {
12606            synchronized (mPidsSelfLocked) {
12607                boolean printed = false;
12608                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12609                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12610                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12611                        continue;
12612                    }
12613                    if (!printed) {
12614                        if (needSep) pw.println();
12615                        needSep = true;
12616                        pw.println("  PID mappings:");
12617                        printed = true;
12618                        printedAnything = true;
12619                    }
12620                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12621                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12622                }
12623            }
12624        }
12625
12626        if (mForegroundProcesses.size() > 0) {
12627            synchronized (mPidsSelfLocked) {
12628                boolean printed = false;
12629                for (int i=0; i<mForegroundProcesses.size(); i++) {
12630                    ProcessRecord r = mPidsSelfLocked.get(
12631                            mForegroundProcesses.valueAt(i).pid);
12632                    if (dumpPackage != null && (r == null
12633                            || !r.pkgList.containsKey(dumpPackage))) {
12634                        continue;
12635                    }
12636                    if (!printed) {
12637                        if (needSep) pw.println();
12638                        needSep = true;
12639                        pw.println("  Foreground Processes:");
12640                        printed = true;
12641                        printedAnything = true;
12642                    }
12643                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12644                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12645                }
12646            }
12647        }
12648
12649        if (mPersistentStartingProcesses.size() > 0) {
12650            if (needSep) pw.println();
12651            needSep = true;
12652            printedAnything = true;
12653            pw.println("  Persisent processes that are starting:");
12654            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12655                    "Starting Norm", "Restarting PERS", dumpPackage);
12656        }
12657
12658        if (mRemovedProcesses.size() > 0) {
12659            if (needSep) pw.println();
12660            needSep = true;
12661            printedAnything = true;
12662            pw.println("  Processes that are being removed:");
12663            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12664                    "Removed Norm", "Removed PERS", dumpPackage);
12665        }
12666
12667        if (mProcessesOnHold.size() > 0) {
12668            if (needSep) pw.println();
12669            needSep = true;
12670            printedAnything = true;
12671            pw.println("  Processes that are on old until the system is ready:");
12672            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12673                    "OnHold Norm", "OnHold PERS", dumpPackage);
12674        }
12675
12676        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12677
12678        if (mProcessCrashTimes.getMap().size() > 0) {
12679            boolean printed = false;
12680            long now = SystemClock.uptimeMillis();
12681            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12682            final int NP = pmap.size();
12683            for (int ip=0; ip<NP; ip++) {
12684                String pname = pmap.keyAt(ip);
12685                SparseArray<Long> uids = pmap.valueAt(ip);
12686                final int N = uids.size();
12687                for (int i=0; i<N; i++) {
12688                    int puid = uids.keyAt(i);
12689                    ProcessRecord r = mProcessNames.get(pname, puid);
12690                    if (dumpPackage != null && (r == null
12691                            || !r.pkgList.containsKey(dumpPackage))) {
12692                        continue;
12693                    }
12694                    if (!printed) {
12695                        if (needSep) pw.println();
12696                        needSep = true;
12697                        pw.println("  Time since processes crashed:");
12698                        printed = true;
12699                        printedAnything = true;
12700                    }
12701                    pw.print("    Process "); pw.print(pname);
12702                            pw.print(" uid "); pw.print(puid);
12703                            pw.print(": last crashed ");
12704                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12705                            pw.println(" ago");
12706                }
12707            }
12708        }
12709
12710        if (mBadProcesses.getMap().size() > 0) {
12711            boolean printed = false;
12712            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12713            final int NP = pmap.size();
12714            for (int ip=0; ip<NP; ip++) {
12715                String pname = pmap.keyAt(ip);
12716                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12717                final int N = uids.size();
12718                for (int i=0; i<N; i++) {
12719                    int puid = uids.keyAt(i);
12720                    ProcessRecord r = mProcessNames.get(pname, puid);
12721                    if (dumpPackage != null && (r == null
12722                            || !r.pkgList.containsKey(dumpPackage))) {
12723                        continue;
12724                    }
12725                    if (!printed) {
12726                        if (needSep) pw.println();
12727                        needSep = true;
12728                        pw.println("  Bad processes:");
12729                        printedAnything = true;
12730                    }
12731                    BadProcessInfo info = uids.valueAt(i);
12732                    pw.print("    Bad process "); pw.print(pname);
12733                            pw.print(" uid "); pw.print(puid);
12734                            pw.print(": crashed at time "); pw.println(info.time);
12735                    if (info.shortMsg != null) {
12736                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12737                    }
12738                    if (info.longMsg != null) {
12739                        pw.print("      Long msg: "); pw.println(info.longMsg);
12740                    }
12741                    if (info.stack != null) {
12742                        pw.println("      Stack:");
12743                        int lastPos = 0;
12744                        for (int pos=0; pos<info.stack.length(); pos++) {
12745                            if (info.stack.charAt(pos) == '\n') {
12746                                pw.print("        ");
12747                                pw.write(info.stack, lastPos, pos-lastPos);
12748                                pw.println();
12749                                lastPos = pos+1;
12750                            }
12751                        }
12752                        if (lastPos < info.stack.length()) {
12753                            pw.print("        ");
12754                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12755                            pw.println();
12756                        }
12757                    }
12758                }
12759            }
12760        }
12761
12762        if (dumpPackage == null) {
12763            pw.println();
12764            needSep = false;
12765            pw.println("  mStartedUsers:");
12766            for (int i=0; i<mStartedUsers.size(); i++) {
12767                UserStartedState uss = mStartedUsers.valueAt(i);
12768                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12769                        pw.print(": "); uss.dump("", pw);
12770            }
12771            pw.print("  mStartedUserArray: [");
12772            for (int i=0; i<mStartedUserArray.length; i++) {
12773                if (i > 0) pw.print(", ");
12774                pw.print(mStartedUserArray[i]);
12775            }
12776            pw.println("]");
12777            pw.print("  mUserLru: [");
12778            for (int i=0; i<mUserLru.size(); i++) {
12779                if (i > 0) pw.print(", ");
12780                pw.print(mUserLru.get(i));
12781            }
12782            pw.println("]");
12783            if (dumpAll) {
12784                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12785            }
12786            synchronized (mUserProfileGroupIdsSelfLocked) {
12787                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12788                    pw.println("  mUserProfileGroupIds:");
12789                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12790                        pw.print("    User #");
12791                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12792                        pw.print(" -> profile #");
12793                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12794                    }
12795                }
12796            }
12797        }
12798        if (mHomeProcess != null && (dumpPackage == null
12799                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12800            if (needSep) {
12801                pw.println();
12802                needSep = false;
12803            }
12804            pw.println("  mHomeProcess: " + mHomeProcess);
12805        }
12806        if (mPreviousProcess != null && (dumpPackage == null
12807                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12808            if (needSep) {
12809                pw.println();
12810                needSep = false;
12811            }
12812            pw.println("  mPreviousProcess: " + mPreviousProcess);
12813        }
12814        if (dumpAll) {
12815            StringBuilder sb = new StringBuilder(128);
12816            sb.append("  mPreviousProcessVisibleTime: ");
12817            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12818            pw.println(sb);
12819        }
12820        if (mHeavyWeightProcess != null && (dumpPackage == null
12821                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12822            if (needSep) {
12823                pw.println();
12824                needSep = false;
12825            }
12826            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12827        }
12828        if (dumpPackage == null) {
12829            pw.println("  mConfiguration: " + mConfiguration);
12830        }
12831        if (dumpAll) {
12832            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12833            if (mCompatModePackages.getPackages().size() > 0) {
12834                boolean printed = false;
12835                for (Map.Entry<String, Integer> entry
12836                        : mCompatModePackages.getPackages().entrySet()) {
12837                    String pkg = entry.getKey();
12838                    int mode = entry.getValue();
12839                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12840                        continue;
12841                    }
12842                    if (!printed) {
12843                        pw.println("  mScreenCompatPackages:");
12844                        printed = true;
12845                    }
12846                    pw.print("    "); pw.print(pkg); pw.print(": ");
12847                            pw.print(mode); pw.println();
12848                }
12849            }
12850        }
12851        if (dumpPackage == null) {
12852            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12853                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12854                        + " mLockScreenShown " + lockScreenShownToString());
12855            }
12856            if (mShuttingDown || mRunningVoice) {
12857                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12858            }
12859        }
12860        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12861                || mOrigWaitForDebugger) {
12862            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12863                    || dumpPackage.equals(mOrigDebugApp)) {
12864                if (needSep) {
12865                    pw.println();
12866                    needSep = false;
12867                }
12868                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12869                        + " mDebugTransient=" + mDebugTransient
12870                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12871            }
12872        }
12873        if (mOpenGlTraceApp != null) {
12874            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12875                if (needSep) {
12876                    pw.println();
12877                    needSep = false;
12878                }
12879                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12880            }
12881        }
12882        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12883                || mProfileFd != null) {
12884            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12885                if (needSep) {
12886                    pw.println();
12887                    needSep = false;
12888                }
12889                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12890                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12891                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12892                        + mAutoStopProfiler);
12893                pw.println("  mProfileType=" + mProfileType);
12894            }
12895        }
12896        if (dumpPackage == null) {
12897            if (mAlwaysFinishActivities || mController != null) {
12898                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12899                        + " mController=" + mController);
12900            }
12901            if (dumpAll) {
12902                pw.println("  Total persistent processes: " + numPers);
12903                pw.println("  mProcessesReady=" + mProcessesReady
12904                        + " mSystemReady=" + mSystemReady
12905                        + " mBooted=" + mBooted
12906                        + " mFactoryTest=" + mFactoryTest);
12907                pw.println("  mBooting=" + mBooting
12908                        + " mCallFinishBooting=" + mCallFinishBooting
12909                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12910                pw.print("  mLastPowerCheckRealtime=");
12911                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12912                        pw.println("");
12913                pw.print("  mLastPowerCheckUptime=");
12914                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12915                        pw.println("");
12916                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12917                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12918                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12919                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12920                        + " (" + mLruProcesses.size() + " total)"
12921                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12922                        + " mNumServiceProcs=" + mNumServiceProcs
12923                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12924                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12925                        + " mLastMemoryLevel" + mLastMemoryLevel
12926                        + " mLastNumProcesses" + mLastNumProcesses);
12927                long now = SystemClock.uptimeMillis();
12928                pw.print("  mLastIdleTime=");
12929                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12930                        pw.print(" mLowRamSinceLastIdle=");
12931                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12932                        pw.println();
12933            }
12934        }
12935
12936        if (!printedAnything) {
12937            pw.println("  (nothing)");
12938        }
12939    }
12940
12941    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12942            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12943        if (mProcessesToGc.size() > 0) {
12944            boolean printed = false;
12945            long now = SystemClock.uptimeMillis();
12946            for (int i=0; i<mProcessesToGc.size(); i++) {
12947                ProcessRecord proc = mProcessesToGc.get(i);
12948                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12949                    continue;
12950                }
12951                if (!printed) {
12952                    if (needSep) pw.println();
12953                    needSep = true;
12954                    pw.println("  Processes that are waiting to GC:");
12955                    printed = true;
12956                }
12957                pw.print("    Process "); pw.println(proc);
12958                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12959                        pw.print(", last gced=");
12960                        pw.print(now-proc.lastRequestedGc);
12961                        pw.print(" ms ago, last lowMem=");
12962                        pw.print(now-proc.lastLowMemory);
12963                        pw.println(" ms ago");
12964
12965            }
12966        }
12967        return needSep;
12968    }
12969
12970    void printOomLevel(PrintWriter pw, String name, int adj) {
12971        pw.print("    ");
12972        if (adj >= 0) {
12973            pw.print(' ');
12974            if (adj < 10) pw.print(' ');
12975        } else {
12976            if (adj > -10) pw.print(' ');
12977        }
12978        pw.print(adj);
12979        pw.print(": ");
12980        pw.print(name);
12981        pw.print(" (");
12982        pw.print(mProcessList.getMemLevel(adj)/1024);
12983        pw.println(" kB)");
12984    }
12985
12986    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12987            int opti, boolean dumpAll) {
12988        boolean needSep = false;
12989
12990        if (mLruProcesses.size() > 0) {
12991            if (needSep) pw.println();
12992            needSep = true;
12993            pw.println("  OOM levels:");
12994            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12995            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12996            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12997            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12998            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12999            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13000            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13001            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13002            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13003            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13004            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13005            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13006            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13007            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13008
13009            if (needSep) pw.println();
13010            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13011                    pw.print(" total, non-act at ");
13012                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13013                    pw.print(", non-svc at ");
13014                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13015                    pw.println("):");
13016            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13017            needSep = true;
13018        }
13019
13020        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13021
13022        pw.println();
13023        pw.println("  mHomeProcess: " + mHomeProcess);
13024        pw.println("  mPreviousProcess: " + mPreviousProcess);
13025        if (mHeavyWeightProcess != null) {
13026            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13027        }
13028
13029        return true;
13030    }
13031
13032    /**
13033     * There are three ways to call this:
13034     *  - no provider specified: dump all the providers
13035     *  - a flattened component name that matched an existing provider was specified as the
13036     *    first arg: dump that one provider
13037     *  - the first arg isn't the flattened component name of an existing provider:
13038     *    dump all providers whose component contains the first arg as a substring
13039     */
13040    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13041            int opti, boolean dumpAll) {
13042        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13043    }
13044
13045    static class ItemMatcher {
13046        ArrayList<ComponentName> components;
13047        ArrayList<String> strings;
13048        ArrayList<Integer> objects;
13049        boolean all;
13050
13051        ItemMatcher() {
13052            all = true;
13053        }
13054
13055        void build(String name) {
13056            ComponentName componentName = ComponentName.unflattenFromString(name);
13057            if (componentName != null) {
13058                if (components == null) {
13059                    components = new ArrayList<ComponentName>();
13060                }
13061                components.add(componentName);
13062                all = false;
13063            } else {
13064                int objectId = 0;
13065                // Not a '/' separated full component name; maybe an object ID?
13066                try {
13067                    objectId = Integer.parseInt(name, 16);
13068                    if (objects == null) {
13069                        objects = new ArrayList<Integer>();
13070                    }
13071                    objects.add(objectId);
13072                    all = false;
13073                } catch (RuntimeException e) {
13074                    // Not an integer; just do string match.
13075                    if (strings == null) {
13076                        strings = new ArrayList<String>();
13077                    }
13078                    strings.add(name);
13079                    all = false;
13080                }
13081            }
13082        }
13083
13084        int build(String[] args, int opti) {
13085            for (; opti<args.length; opti++) {
13086                String name = args[opti];
13087                if ("--".equals(name)) {
13088                    return opti+1;
13089                }
13090                build(name);
13091            }
13092            return opti;
13093        }
13094
13095        boolean match(Object object, ComponentName comp) {
13096            if (all) {
13097                return true;
13098            }
13099            if (components != null) {
13100                for (int i=0; i<components.size(); i++) {
13101                    if (components.get(i).equals(comp)) {
13102                        return true;
13103                    }
13104                }
13105            }
13106            if (objects != null) {
13107                for (int i=0; i<objects.size(); i++) {
13108                    if (System.identityHashCode(object) == objects.get(i)) {
13109                        return true;
13110                    }
13111                }
13112            }
13113            if (strings != null) {
13114                String flat = comp.flattenToString();
13115                for (int i=0; i<strings.size(); i++) {
13116                    if (flat.contains(strings.get(i))) {
13117                        return true;
13118                    }
13119                }
13120            }
13121            return false;
13122        }
13123    }
13124
13125    /**
13126     * There are three things that cmd can be:
13127     *  - a flattened component name that matches an existing activity
13128     *  - the cmd arg isn't the flattened component name of an existing activity:
13129     *    dump all activity whose component contains the cmd as a substring
13130     *  - A hex number of the ActivityRecord object instance.
13131     */
13132    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13133            int opti, boolean dumpAll) {
13134        ArrayList<ActivityRecord> activities;
13135
13136        synchronized (this) {
13137            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13138        }
13139
13140        if (activities.size() <= 0) {
13141            return false;
13142        }
13143
13144        String[] newArgs = new String[args.length - opti];
13145        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13146
13147        TaskRecord lastTask = null;
13148        boolean needSep = false;
13149        for (int i=activities.size()-1; i>=0; i--) {
13150            ActivityRecord r = activities.get(i);
13151            if (needSep) {
13152                pw.println();
13153            }
13154            needSep = true;
13155            synchronized (this) {
13156                if (lastTask != r.task) {
13157                    lastTask = r.task;
13158                    pw.print("TASK "); pw.print(lastTask.affinity);
13159                            pw.print(" id="); pw.println(lastTask.taskId);
13160                    if (dumpAll) {
13161                        lastTask.dump(pw, "  ");
13162                    }
13163                }
13164            }
13165            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13166        }
13167        return true;
13168    }
13169
13170    /**
13171     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13172     * there is a thread associated with the activity.
13173     */
13174    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13175            final ActivityRecord r, String[] args, boolean dumpAll) {
13176        String innerPrefix = prefix + "  ";
13177        synchronized (this) {
13178            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13179                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13180                    pw.print(" pid=");
13181                    if (r.app != null) pw.println(r.app.pid);
13182                    else pw.println("(not running)");
13183            if (dumpAll) {
13184                r.dump(pw, innerPrefix);
13185            }
13186        }
13187        if (r.app != null && r.app.thread != null) {
13188            // flush anything that is already in the PrintWriter since the thread is going
13189            // to write to the file descriptor directly
13190            pw.flush();
13191            try {
13192                TransferPipe tp = new TransferPipe();
13193                try {
13194                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13195                            r.appToken, innerPrefix, args);
13196                    tp.go(fd);
13197                } finally {
13198                    tp.kill();
13199                }
13200            } catch (IOException e) {
13201                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13202            } catch (RemoteException e) {
13203                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13204            }
13205        }
13206    }
13207
13208    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13209            int opti, boolean dumpAll, String dumpPackage) {
13210        boolean needSep = false;
13211        boolean onlyHistory = false;
13212        boolean printedAnything = false;
13213
13214        if ("history".equals(dumpPackage)) {
13215            if (opti < args.length && "-s".equals(args[opti])) {
13216                dumpAll = false;
13217            }
13218            onlyHistory = true;
13219            dumpPackage = null;
13220        }
13221
13222        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13223        if (!onlyHistory && dumpAll) {
13224            if (mRegisteredReceivers.size() > 0) {
13225                boolean printed = false;
13226                Iterator it = mRegisteredReceivers.values().iterator();
13227                while (it.hasNext()) {
13228                    ReceiverList r = (ReceiverList)it.next();
13229                    if (dumpPackage != null && (r.app == null ||
13230                            !dumpPackage.equals(r.app.info.packageName))) {
13231                        continue;
13232                    }
13233                    if (!printed) {
13234                        pw.println("  Registered Receivers:");
13235                        needSep = true;
13236                        printed = true;
13237                        printedAnything = true;
13238                    }
13239                    pw.print("  * "); pw.println(r);
13240                    r.dump(pw, "    ");
13241                }
13242            }
13243
13244            if (mReceiverResolver.dump(pw, needSep ?
13245                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13246                    "    ", dumpPackage, false)) {
13247                needSep = true;
13248                printedAnything = true;
13249            }
13250        }
13251
13252        for (BroadcastQueue q : mBroadcastQueues) {
13253            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13254            printedAnything |= needSep;
13255        }
13256
13257        needSep = true;
13258
13259        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13260            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13261                if (needSep) {
13262                    pw.println();
13263                }
13264                needSep = true;
13265                printedAnything = true;
13266                pw.print("  Sticky broadcasts for user ");
13267                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13268                StringBuilder sb = new StringBuilder(128);
13269                for (Map.Entry<String, ArrayList<Intent>> ent
13270                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13271                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13272                    if (dumpAll) {
13273                        pw.println(":");
13274                        ArrayList<Intent> intents = ent.getValue();
13275                        final int N = intents.size();
13276                        for (int i=0; i<N; i++) {
13277                            sb.setLength(0);
13278                            sb.append("    Intent: ");
13279                            intents.get(i).toShortString(sb, false, true, false, false);
13280                            pw.println(sb.toString());
13281                            Bundle bundle = intents.get(i).getExtras();
13282                            if (bundle != null) {
13283                                pw.print("      ");
13284                                pw.println(bundle.toString());
13285                            }
13286                        }
13287                    } else {
13288                        pw.println("");
13289                    }
13290                }
13291            }
13292        }
13293
13294        if (!onlyHistory && dumpAll) {
13295            pw.println();
13296            for (BroadcastQueue queue : mBroadcastQueues) {
13297                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13298                        + queue.mBroadcastsScheduled);
13299            }
13300            pw.println("  mHandler:");
13301            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13302            needSep = true;
13303            printedAnything = true;
13304        }
13305
13306        if (!printedAnything) {
13307            pw.println("  (nothing)");
13308        }
13309    }
13310
13311    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13312            int opti, boolean dumpAll, String dumpPackage) {
13313        boolean needSep;
13314        boolean printedAnything = false;
13315
13316        ItemMatcher matcher = new ItemMatcher();
13317        matcher.build(args, opti);
13318
13319        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13320
13321        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13322        printedAnything |= needSep;
13323
13324        if (mLaunchingProviders.size() > 0) {
13325            boolean printed = false;
13326            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13327                ContentProviderRecord r = mLaunchingProviders.get(i);
13328                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13329                    continue;
13330                }
13331                if (!printed) {
13332                    if (needSep) pw.println();
13333                    needSep = true;
13334                    pw.println("  Launching content providers:");
13335                    printed = true;
13336                    printedAnything = true;
13337                }
13338                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13339                        pw.println(r);
13340            }
13341        }
13342
13343        if (mGrantedUriPermissions.size() > 0) {
13344            boolean printed = false;
13345            int dumpUid = -2;
13346            if (dumpPackage != null) {
13347                try {
13348                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13349                } catch (NameNotFoundException e) {
13350                    dumpUid = -1;
13351                }
13352            }
13353            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13354                int uid = mGrantedUriPermissions.keyAt(i);
13355                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13356                    continue;
13357                }
13358                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13359                if (!printed) {
13360                    if (needSep) pw.println();
13361                    needSep = true;
13362                    pw.println("  Granted Uri Permissions:");
13363                    printed = true;
13364                    printedAnything = true;
13365                }
13366                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13367                for (UriPermission perm : perms.values()) {
13368                    pw.print("    "); pw.println(perm);
13369                    if (dumpAll) {
13370                        perm.dump(pw, "      ");
13371                    }
13372                }
13373            }
13374        }
13375
13376        if (!printedAnything) {
13377            pw.println("  (nothing)");
13378        }
13379    }
13380
13381    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13382            int opti, boolean dumpAll, String dumpPackage) {
13383        boolean printed = false;
13384
13385        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13386
13387        if (mIntentSenderRecords.size() > 0) {
13388            Iterator<WeakReference<PendingIntentRecord>> it
13389                    = mIntentSenderRecords.values().iterator();
13390            while (it.hasNext()) {
13391                WeakReference<PendingIntentRecord> ref = it.next();
13392                PendingIntentRecord rec = ref != null ? ref.get(): null;
13393                if (dumpPackage != null && (rec == null
13394                        || !dumpPackage.equals(rec.key.packageName))) {
13395                    continue;
13396                }
13397                printed = true;
13398                if (rec != null) {
13399                    pw.print("  * "); pw.println(rec);
13400                    if (dumpAll) {
13401                        rec.dump(pw, "    ");
13402                    }
13403                } else {
13404                    pw.print("  * "); pw.println(ref);
13405                }
13406            }
13407        }
13408
13409        if (!printed) {
13410            pw.println("  (nothing)");
13411        }
13412    }
13413
13414    private static final int dumpProcessList(PrintWriter pw,
13415            ActivityManagerService service, List list,
13416            String prefix, String normalLabel, String persistentLabel,
13417            String dumpPackage) {
13418        int numPers = 0;
13419        final int N = list.size()-1;
13420        for (int i=N; i>=0; i--) {
13421            ProcessRecord r = (ProcessRecord)list.get(i);
13422            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13423                continue;
13424            }
13425            pw.println(String.format("%s%s #%2d: %s",
13426                    prefix, (r.persistent ? persistentLabel : normalLabel),
13427                    i, r.toString()));
13428            if (r.persistent) {
13429                numPers++;
13430            }
13431        }
13432        return numPers;
13433    }
13434
13435    private static final boolean dumpProcessOomList(PrintWriter pw,
13436            ActivityManagerService service, List<ProcessRecord> origList,
13437            String prefix, String normalLabel, String persistentLabel,
13438            boolean inclDetails, String dumpPackage) {
13439
13440        ArrayList<Pair<ProcessRecord, Integer>> list
13441                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13442        for (int i=0; i<origList.size(); i++) {
13443            ProcessRecord r = origList.get(i);
13444            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13445                continue;
13446            }
13447            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13448        }
13449
13450        if (list.size() <= 0) {
13451            return false;
13452        }
13453
13454        Comparator<Pair<ProcessRecord, Integer>> comparator
13455                = new Comparator<Pair<ProcessRecord, Integer>>() {
13456            @Override
13457            public int compare(Pair<ProcessRecord, Integer> object1,
13458                    Pair<ProcessRecord, Integer> object2) {
13459                if (object1.first.setAdj != object2.first.setAdj) {
13460                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13461                }
13462                if (object1.second.intValue() != object2.second.intValue()) {
13463                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13464                }
13465                return 0;
13466            }
13467        };
13468
13469        Collections.sort(list, comparator);
13470
13471        final long curRealtime = SystemClock.elapsedRealtime();
13472        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13473        final long curUptime = SystemClock.uptimeMillis();
13474        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13475
13476        for (int i=list.size()-1; i>=0; i--) {
13477            ProcessRecord r = list.get(i).first;
13478            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13479            char schedGroup;
13480            switch (r.setSchedGroup) {
13481                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13482                    schedGroup = 'B';
13483                    break;
13484                case Process.THREAD_GROUP_DEFAULT:
13485                    schedGroup = 'F';
13486                    break;
13487                default:
13488                    schedGroup = '?';
13489                    break;
13490            }
13491            char foreground;
13492            if (r.foregroundActivities) {
13493                foreground = 'A';
13494            } else if (r.foregroundServices) {
13495                foreground = 'S';
13496            } else {
13497                foreground = ' ';
13498            }
13499            String procState = ProcessList.makeProcStateString(r.curProcState);
13500            pw.print(prefix);
13501            pw.print(r.persistent ? persistentLabel : normalLabel);
13502            pw.print(" #");
13503            int num = (origList.size()-1)-list.get(i).second;
13504            if (num < 10) pw.print(' ');
13505            pw.print(num);
13506            pw.print(": ");
13507            pw.print(oomAdj);
13508            pw.print(' ');
13509            pw.print(schedGroup);
13510            pw.print('/');
13511            pw.print(foreground);
13512            pw.print('/');
13513            pw.print(procState);
13514            pw.print(" trm:");
13515            if (r.trimMemoryLevel < 10) pw.print(' ');
13516            pw.print(r.trimMemoryLevel);
13517            pw.print(' ');
13518            pw.print(r.toShortString());
13519            pw.print(" (");
13520            pw.print(r.adjType);
13521            pw.println(')');
13522            if (r.adjSource != null || r.adjTarget != null) {
13523                pw.print(prefix);
13524                pw.print("    ");
13525                if (r.adjTarget instanceof ComponentName) {
13526                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13527                } else if (r.adjTarget != null) {
13528                    pw.print(r.adjTarget.toString());
13529                } else {
13530                    pw.print("{null}");
13531                }
13532                pw.print("<=");
13533                if (r.adjSource instanceof ProcessRecord) {
13534                    pw.print("Proc{");
13535                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13536                    pw.println("}");
13537                } else if (r.adjSource != null) {
13538                    pw.println(r.adjSource.toString());
13539                } else {
13540                    pw.println("{null}");
13541                }
13542            }
13543            if (inclDetails) {
13544                pw.print(prefix);
13545                pw.print("    ");
13546                pw.print("oom: max="); pw.print(r.maxAdj);
13547                pw.print(" curRaw="); pw.print(r.curRawAdj);
13548                pw.print(" setRaw="); pw.print(r.setRawAdj);
13549                pw.print(" cur="); pw.print(r.curAdj);
13550                pw.print(" set="); pw.println(r.setAdj);
13551                pw.print(prefix);
13552                pw.print("    ");
13553                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13554                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13555                pw.print(" lastPss="); pw.print(r.lastPss);
13556                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13557                pw.print(prefix);
13558                pw.print("    ");
13559                pw.print("cached="); pw.print(r.cached);
13560                pw.print(" empty="); pw.print(r.empty);
13561                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13562
13563                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13564                    if (r.lastWakeTime != 0) {
13565                        long wtime;
13566                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13567                        synchronized (stats) {
13568                            wtime = stats.getProcessWakeTime(r.info.uid,
13569                                    r.pid, curRealtime);
13570                        }
13571                        long timeUsed = wtime - r.lastWakeTime;
13572                        pw.print(prefix);
13573                        pw.print("    ");
13574                        pw.print("keep awake over ");
13575                        TimeUtils.formatDuration(realtimeSince, pw);
13576                        pw.print(" used ");
13577                        TimeUtils.formatDuration(timeUsed, pw);
13578                        pw.print(" (");
13579                        pw.print((timeUsed*100)/realtimeSince);
13580                        pw.println("%)");
13581                    }
13582                    if (r.lastCpuTime != 0) {
13583                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13584                        pw.print(prefix);
13585                        pw.print("    ");
13586                        pw.print("run cpu over ");
13587                        TimeUtils.formatDuration(uptimeSince, pw);
13588                        pw.print(" used ");
13589                        TimeUtils.formatDuration(timeUsed, pw);
13590                        pw.print(" (");
13591                        pw.print((timeUsed*100)/uptimeSince);
13592                        pw.println("%)");
13593                    }
13594                }
13595            }
13596        }
13597        return true;
13598    }
13599
13600    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13601            String[] args) {
13602        ArrayList<ProcessRecord> procs;
13603        synchronized (this) {
13604            if (args != null && args.length > start
13605                    && args[start].charAt(0) != '-') {
13606                procs = new ArrayList<ProcessRecord>();
13607                int pid = -1;
13608                try {
13609                    pid = Integer.parseInt(args[start]);
13610                } catch (NumberFormatException e) {
13611                }
13612                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13613                    ProcessRecord proc = mLruProcesses.get(i);
13614                    if (proc.pid == pid) {
13615                        procs.add(proc);
13616                    } else if (allPkgs && proc.pkgList != null
13617                            && proc.pkgList.containsKey(args[start])) {
13618                        procs.add(proc);
13619                    } else if (proc.processName.equals(args[start])) {
13620                        procs.add(proc);
13621                    }
13622                }
13623                if (procs.size() <= 0) {
13624                    return null;
13625                }
13626            } else {
13627                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13628            }
13629        }
13630        return procs;
13631    }
13632
13633    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13634            PrintWriter pw, String[] args) {
13635        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13636        if (procs == null) {
13637            pw.println("No process found for: " + args[0]);
13638            return;
13639        }
13640
13641        long uptime = SystemClock.uptimeMillis();
13642        long realtime = SystemClock.elapsedRealtime();
13643        pw.println("Applications Graphics Acceleration Info:");
13644        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13645
13646        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13647            ProcessRecord r = procs.get(i);
13648            if (r.thread != null) {
13649                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13650                pw.flush();
13651                try {
13652                    TransferPipe tp = new TransferPipe();
13653                    try {
13654                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13655                        tp.go(fd);
13656                    } finally {
13657                        tp.kill();
13658                    }
13659                } catch (IOException e) {
13660                    pw.println("Failure while dumping the app: " + r);
13661                    pw.flush();
13662                } catch (RemoteException e) {
13663                    pw.println("Got a RemoteException while dumping the app " + r);
13664                    pw.flush();
13665                }
13666            }
13667        }
13668    }
13669
13670    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13671        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13672        if (procs == null) {
13673            pw.println("No process found for: " + args[0]);
13674            return;
13675        }
13676
13677        pw.println("Applications Database Info:");
13678
13679        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13680            ProcessRecord r = procs.get(i);
13681            if (r.thread != null) {
13682                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13683                pw.flush();
13684                try {
13685                    TransferPipe tp = new TransferPipe();
13686                    try {
13687                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13688                        tp.go(fd);
13689                    } finally {
13690                        tp.kill();
13691                    }
13692                } catch (IOException e) {
13693                    pw.println("Failure while dumping the app: " + r);
13694                    pw.flush();
13695                } catch (RemoteException e) {
13696                    pw.println("Got a RemoteException while dumping the app " + r);
13697                    pw.flush();
13698                }
13699            }
13700        }
13701    }
13702
13703    final static class MemItem {
13704        final boolean isProc;
13705        final String label;
13706        final String shortLabel;
13707        final long pss;
13708        final int id;
13709        final boolean hasActivities;
13710        ArrayList<MemItem> subitems;
13711
13712        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13713                boolean _hasActivities) {
13714            isProc = true;
13715            label = _label;
13716            shortLabel = _shortLabel;
13717            pss = _pss;
13718            id = _id;
13719            hasActivities = _hasActivities;
13720        }
13721
13722        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13723            isProc = false;
13724            label = _label;
13725            shortLabel = _shortLabel;
13726            pss = _pss;
13727            id = _id;
13728            hasActivities = false;
13729        }
13730    }
13731
13732    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13733            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13734        if (sort && !isCompact) {
13735            Collections.sort(items, new Comparator<MemItem>() {
13736                @Override
13737                public int compare(MemItem lhs, MemItem rhs) {
13738                    if (lhs.pss < rhs.pss) {
13739                        return 1;
13740                    } else if (lhs.pss > rhs.pss) {
13741                        return -1;
13742                    }
13743                    return 0;
13744                }
13745            });
13746        }
13747
13748        for (int i=0; i<items.size(); i++) {
13749            MemItem mi = items.get(i);
13750            if (!isCompact) {
13751                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13752            } else if (mi.isProc) {
13753                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13754                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13755                pw.println(mi.hasActivities ? ",a" : ",e");
13756            } else {
13757                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13758                pw.println(mi.pss);
13759            }
13760            if (mi.subitems != null) {
13761                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13762                        true, isCompact);
13763            }
13764        }
13765    }
13766
13767    // These are in KB.
13768    static final long[] DUMP_MEM_BUCKETS = new long[] {
13769        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13770        120*1024, 160*1024, 200*1024,
13771        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13772        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13773    };
13774
13775    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13776            boolean stackLike) {
13777        int start = label.lastIndexOf('.');
13778        if (start >= 0) start++;
13779        else start = 0;
13780        int end = label.length();
13781        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13782            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13783                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13784                out.append(bucket);
13785                out.append(stackLike ? "MB." : "MB ");
13786                out.append(label, start, end);
13787                return;
13788            }
13789        }
13790        out.append(memKB/1024);
13791        out.append(stackLike ? "MB." : "MB ");
13792        out.append(label, start, end);
13793    }
13794
13795    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13796            ProcessList.NATIVE_ADJ,
13797            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13798            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13799            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13800            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13801            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13802            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13803    };
13804    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13805            "Native",
13806            "System", "Persistent", "Persistent Service", "Foreground",
13807            "Visible", "Perceptible",
13808            "Heavy Weight", "Backup",
13809            "A Services", "Home",
13810            "Previous", "B Services", "Cached"
13811    };
13812    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13813            "native",
13814            "sys", "pers", "persvc", "fore",
13815            "vis", "percept",
13816            "heavy", "backup",
13817            "servicea", "home",
13818            "prev", "serviceb", "cached"
13819    };
13820
13821    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13822            long realtime, boolean isCheckinRequest, boolean isCompact) {
13823        if (isCheckinRequest || isCompact) {
13824            // short checkin version
13825            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13826        } else {
13827            pw.println("Applications Memory Usage (kB):");
13828            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13829        }
13830    }
13831
13832    private static final int KSM_SHARED = 0;
13833    private static final int KSM_SHARING = 1;
13834    private static final int KSM_UNSHARED = 2;
13835    private static final int KSM_VOLATILE = 3;
13836
13837    private final long[] getKsmInfo() {
13838        long[] longOut = new long[4];
13839        final int[] SINGLE_LONG_FORMAT = new int[] {
13840            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13841        };
13842        long[] longTmp = new long[1];
13843        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13844                SINGLE_LONG_FORMAT, null, longTmp, null);
13845        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13846        longTmp[0] = 0;
13847        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13848                SINGLE_LONG_FORMAT, null, longTmp, null);
13849        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13850        longTmp[0] = 0;
13851        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13852                SINGLE_LONG_FORMAT, null, longTmp, null);
13853        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13854        longTmp[0] = 0;
13855        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13856                SINGLE_LONG_FORMAT, null, longTmp, null);
13857        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13858        return longOut;
13859    }
13860
13861    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13862            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13863        boolean dumpDetails = false;
13864        boolean dumpFullDetails = false;
13865        boolean dumpDalvik = false;
13866        boolean oomOnly = false;
13867        boolean isCompact = false;
13868        boolean localOnly = false;
13869        boolean packages = false;
13870
13871        int opti = 0;
13872        while (opti < args.length) {
13873            String opt = args[opti];
13874            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13875                break;
13876            }
13877            opti++;
13878            if ("-a".equals(opt)) {
13879                dumpDetails = true;
13880                dumpFullDetails = true;
13881                dumpDalvik = true;
13882            } else if ("-d".equals(opt)) {
13883                dumpDalvik = true;
13884            } else if ("-c".equals(opt)) {
13885                isCompact = true;
13886            } else if ("--oom".equals(opt)) {
13887                oomOnly = true;
13888            } else if ("--local".equals(opt)) {
13889                localOnly = true;
13890            } else if ("--package".equals(opt)) {
13891                packages = true;
13892            } else if ("-h".equals(opt)) {
13893                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13894                pw.println("  -a: include all available information for each process.");
13895                pw.println("  -d: include dalvik details when dumping process details.");
13896                pw.println("  -c: dump in a compact machine-parseable representation.");
13897                pw.println("  --oom: only show processes organized by oom adj.");
13898                pw.println("  --local: only collect details locally, don't call process.");
13899                pw.println("  --package: interpret process arg as package, dumping all");
13900                pw.println("             processes that have loaded that package.");
13901                pw.println("If [process] is specified it can be the name or ");
13902                pw.println("pid of a specific process to dump.");
13903                return;
13904            } else {
13905                pw.println("Unknown argument: " + opt + "; use -h for help");
13906            }
13907        }
13908
13909        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13910        long uptime = SystemClock.uptimeMillis();
13911        long realtime = SystemClock.elapsedRealtime();
13912        final long[] tmpLong = new long[1];
13913
13914        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13915        if (procs == null) {
13916            // No Java processes.  Maybe they want to print a native process.
13917            if (args != null && args.length > opti
13918                    && args[opti].charAt(0) != '-') {
13919                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13920                        = new ArrayList<ProcessCpuTracker.Stats>();
13921                updateCpuStatsNow();
13922                int findPid = -1;
13923                try {
13924                    findPid = Integer.parseInt(args[opti]);
13925                } catch (NumberFormatException e) {
13926                }
13927                synchronized (mProcessCpuTracker) {
13928                    final int N = mProcessCpuTracker.countStats();
13929                    for (int i=0; i<N; i++) {
13930                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13931                        if (st.pid == findPid || (st.baseName != null
13932                                && st.baseName.equals(args[opti]))) {
13933                            nativeProcs.add(st);
13934                        }
13935                    }
13936                }
13937                if (nativeProcs.size() > 0) {
13938                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13939                            isCompact);
13940                    Debug.MemoryInfo mi = null;
13941                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13942                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13943                        final int pid = r.pid;
13944                        if (!isCheckinRequest && dumpDetails) {
13945                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13946                        }
13947                        if (mi == null) {
13948                            mi = new Debug.MemoryInfo();
13949                        }
13950                        if (dumpDetails || (!brief && !oomOnly)) {
13951                            Debug.getMemoryInfo(pid, mi);
13952                        } else {
13953                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13954                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13955                        }
13956                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13957                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13958                        if (isCheckinRequest) {
13959                            pw.println();
13960                        }
13961                    }
13962                    return;
13963                }
13964            }
13965            pw.println("No process found for: " + args[opti]);
13966            return;
13967        }
13968
13969        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13970            dumpDetails = true;
13971        }
13972
13973        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13974
13975        String[] innerArgs = new String[args.length-opti];
13976        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13977
13978        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13979        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13980        long nativePss = 0;
13981        long dalvikPss = 0;
13982        long otherPss = 0;
13983        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13984
13985        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13986        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13987                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13988
13989        long totalPss = 0;
13990        long cachedPss = 0;
13991
13992        Debug.MemoryInfo mi = null;
13993        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13994            final ProcessRecord r = procs.get(i);
13995            final IApplicationThread thread;
13996            final int pid;
13997            final int oomAdj;
13998            final boolean hasActivities;
13999            synchronized (this) {
14000                thread = r.thread;
14001                pid = r.pid;
14002                oomAdj = r.getSetAdjWithServices();
14003                hasActivities = r.activities.size() > 0;
14004            }
14005            if (thread != null) {
14006                if (!isCheckinRequest && dumpDetails) {
14007                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14008                }
14009                if (mi == null) {
14010                    mi = new Debug.MemoryInfo();
14011                }
14012                if (dumpDetails || (!brief && !oomOnly)) {
14013                    Debug.getMemoryInfo(pid, mi);
14014                } else {
14015                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14016                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14017                }
14018                if (dumpDetails) {
14019                    if (localOnly) {
14020                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14021                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14022                        if (isCheckinRequest) {
14023                            pw.println();
14024                        }
14025                    } else {
14026                        try {
14027                            pw.flush();
14028                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14029                                    dumpDalvik, innerArgs);
14030                        } catch (RemoteException e) {
14031                            if (!isCheckinRequest) {
14032                                pw.println("Got RemoteException!");
14033                                pw.flush();
14034                            }
14035                        }
14036                    }
14037                }
14038
14039                final long myTotalPss = mi.getTotalPss();
14040                final long myTotalUss = mi.getTotalUss();
14041
14042                synchronized (this) {
14043                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14044                        // Record this for posterity if the process has been stable.
14045                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14046                    }
14047                }
14048
14049                if (!isCheckinRequest && mi != null) {
14050                    totalPss += myTotalPss;
14051                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14052                            (hasActivities ? " / activities)" : ")"),
14053                            r.processName, myTotalPss, pid, hasActivities);
14054                    procMems.add(pssItem);
14055                    procMemsMap.put(pid, pssItem);
14056
14057                    nativePss += mi.nativePss;
14058                    dalvikPss += mi.dalvikPss;
14059                    otherPss += mi.otherPss;
14060                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14061                        long mem = mi.getOtherPss(j);
14062                        miscPss[j] += mem;
14063                        otherPss -= mem;
14064                    }
14065
14066                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14067                        cachedPss += myTotalPss;
14068                    }
14069
14070                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14071                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14072                                || oomIndex == (oomPss.length-1)) {
14073                            oomPss[oomIndex] += myTotalPss;
14074                            if (oomProcs[oomIndex] == null) {
14075                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14076                            }
14077                            oomProcs[oomIndex].add(pssItem);
14078                            break;
14079                        }
14080                    }
14081                }
14082            }
14083        }
14084
14085        long nativeProcTotalPss = 0;
14086
14087        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14088            // If we are showing aggregations, also look for native processes to
14089            // include so that our aggregations are more accurate.
14090            updateCpuStatsNow();
14091            synchronized (mProcessCpuTracker) {
14092                final int N = mProcessCpuTracker.countStats();
14093                for (int i=0; i<N; i++) {
14094                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14095                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14096                        if (mi == null) {
14097                            mi = new Debug.MemoryInfo();
14098                        }
14099                        if (!brief && !oomOnly) {
14100                            Debug.getMemoryInfo(st.pid, mi);
14101                        } else {
14102                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14103                            mi.nativePrivateDirty = (int)tmpLong[0];
14104                        }
14105
14106                        final long myTotalPss = mi.getTotalPss();
14107                        totalPss += myTotalPss;
14108                        nativeProcTotalPss += myTotalPss;
14109
14110                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14111                                st.name, myTotalPss, st.pid, false);
14112                        procMems.add(pssItem);
14113
14114                        nativePss += mi.nativePss;
14115                        dalvikPss += mi.dalvikPss;
14116                        otherPss += mi.otherPss;
14117                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14118                            long mem = mi.getOtherPss(j);
14119                            miscPss[j] += mem;
14120                            otherPss -= mem;
14121                        }
14122                        oomPss[0] += myTotalPss;
14123                        if (oomProcs[0] == null) {
14124                            oomProcs[0] = new ArrayList<MemItem>();
14125                        }
14126                        oomProcs[0].add(pssItem);
14127                    }
14128                }
14129            }
14130
14131            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14132
14133            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14134            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14135            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14136            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14137                String label = Debug.MemoryInfo.getOtherLabel(j);
14138                catMems.add(new MemItem(label, label, miscPss[j], j));
14139            }
14140
14141            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14142            for (int j=0; j<oomPss.length; j++) {
14143                if (oomPss[j] != 0) {
14144                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14145                            : DUMP_MEM_OOM_LABEL[j];
14146                    MemItem item = new MemItem(label, label, oomPss[j],
14147                            DUMP_MEM_OOM_ADJ[j]);
14148                    item.subitems = oomProcs[j];
14149                    oomMems.add(item);
14150                }
14151            }
14152
14153            if (!brief && !oomOnly && !isCompact) {
14154                pw.println();
14155                pw.println("Total PSS by process:");
14156                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14157                pw.println();
14158            }
14159            if (!isCompact) {
14160                pw.println("Total PSS by OOM adjustment:");
14161            }
14162            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14163            if (!brief && !oomOnly) {
14164                PrintWriter out = categoryPw != null ? categoryPw : pw;
14165                if (!isCompact) {
14166                    out.println();
14167                    out.println("Total PSS by category:");
14168                }
14169                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14170            }
14171            if (!isCompact) {
14172                pw.println();
14173            }
14174            MemInfoReader memInfo = new MemInfoReader();
14175            memInfo.readMemInfo();
14176            if (nativeProcTotalPss > 0) {
14177                synchronized (this) {
14178                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14179                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14180                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14181                }
14182            }
14183            if (!brief) {
14184                if (!isCompact) {
14185                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14186                    pw.print(" kB (status ");
14187                    switch (mLastMemoryLevel) {
14188                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14189                            pw.println("normal)");
14190                            break;
14191                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14192                            pw.println("moderate)");
14193                            break;
14194                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14195                            pw.println("low)");
14196                            break;
14197                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14198                            pw.println("critical)");
14199                            break;
14200                        default:
14201                            pw.print(mLastMemoryLevel);
14202                            pw.println(")");
14203                            break;
14204                    }
14205                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14206                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14207                            pw.print(cachedPss); pw.print(" cached pss + ");
14208                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14209                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14210                } else {
14211                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14212                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14213                            + memInfo.getFreeSizeKb()); pw.print(",");
14214                    pw.println(totalPss - cachedPss);
14215                }
14216            }
14217            if (!isCompact) {
14218                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14219                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14220                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14221                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14222                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14223                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14224                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14225            }
14226            if (!brief) {
14227                if (memInfo.getZramTotalSizeKb() != 0) {
14228                    if (!isCompact) {
14229                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14230                                pw.print(" kB physical used for ");
14231                                pw.print(memInfo.getSwapTotalSizeKb()
14232                                        - memInfo.getSwapFreeSizeKb());
14233                                pw.print(" kB in swap (");
14234                                pw.print(memInfo.getSwapTotalSizeKb());
14235                                pw.println(" kB total swap)");
14236                    } else {
14237                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14238                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14239                                pw.println(memInfo.getSwapFreeSizeKb());
14240                    }
14241                }
14242                final long[] ksm = getKsmInfo();
14243                if (!isCompact) {
14244                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14245                            || ksm[KSM_VOLATILE] != 0) {
14246                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14247                                pw.print(" kB saved from shared ");
14248                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14249                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14250                                pw.print(" kB unshared; ");
14251                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14252                    }
14253                    pw.print("   Tuning: ");
14254                    pw.print(ActivityManager.staticGetMemoryClass());
14255                    pw.print(" (large ");
14256                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14257                    pw.print("), oom ");
14258                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14259                    pw.print(" kB");
14260                    pw.print(", restore limit ");
14261                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14262                    pw.print(" kB");
14263                    if (ActivityManager.isLowRamDeviceStatic()) {
14264                        pw.print(" (low-ram)");
14265                    }
14266                    if (ActivityManager.isHighEndGfx()) {
14267                        pw.print(" (high-end-gfx)");
14268                    }
14269                    pw.println();
14270                } else {
14271                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14272                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14273                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14274                    pw.print("tuning,");
14275                    pw.print(ActivityManager.staticGetMemoryClass());
14276                    pw.print(',');
14277                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14278                    pw.print(',');
14279                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14280                    if (ActivityManager.isLowRamDeviceStatic()) {
14281                        pw.print(",low-ram");
14282                    }
14283                    if (ActivityManager.isHighEndGfx()) {
14284                        pw.print(",high-end-gfx");
14285                    }
14286                    pw.println();
14287                }
14288            }
14289        }
14290    }
14291
14292    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14293            String name) {
14294        sb.append("  ");
14295        sb.append(ProcessList.makeOomAdjString(oomAdj));
14296        sb.append(' ');
14297        sb.append(ProcessList.makeProcStateString(procState));
14298        sb.append(' ');
14299        ProcessList.appendRamKb(sb, pss);
14300        sb.append(" kB: ");
14301        sb.append(name);
14302    }
14303
14304    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14305        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14306        sb.append(" (");
14307        sb.append(mi.pid);
14308        sb.append(") ");
14309        sb.append(mi.adjType);
14310        sb.append('\n');
14311        if (mi.adjReason != null) {
14312            sb.append("                      ");
14313            sb.append(mi.adjReason);
14314            sb.append('\n');
14315        }
14316    }
14317
14318    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14319        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14320        for (int i=0, N=memInfos.size(); i<N; i++) {
14321            ProcessMemInfo mi = memInfos.get(i);
14322            infoMap.put(mi.pid, mi);
14323        }
14324        updateCpuStatsNow();
14325        synchronized (mProcessCpuTracker) {
14326            final int N = mProcessCpuTracker.countStats();
14327            for (int i=0; i<N; i++) {
14328                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14329                if (st.vsize > 0) {
14330                    long pss = Debug.getPss(st.pid, null);
14331                    if (pss > 0) {
14332                        if (infoMap.indexOfKey(st.pid) < 0) {
14333                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14334                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14335                            mi.pss = pss;
14336                            memInfos.add(mi);
14337                        }
14338                    }
14339                }
14340            }
14341        }
14342
14343        long totalPss = 0;
14344        for (int i=0, N=memInfos.size(); i<N; i++) {
14345            ProcessMemInfo mi = memInfos.get(i);
14346            if (mi.pss == 0) {
14347                mi.pss = Debug.getPss(mi.pid, null);
14348            }
14349            totalPss += mi.pss;
14350        }
14351        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14352            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14353                if (lhs.oomAdj != rhs.oomAdj) {
14354                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14355                }
14356                if (lhs.pss != rhs.pss) {
14357                    return lhs.pss < rhs.pss ? 1 : -1;
14358                }
14359                return 0;
14360            }
14361        });
14362
14363        StringBuilder tag = new StringBuilder(128);
14364        StringBuilder stack = new StringBuilder(128);
14365        tag.append("Low on memory -- ");
14366        appendMemBucket(tag, totalPss, "total", false);
14367        appendMemBucket(stack, totalPss, "total", true);
14368
14369        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14370        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14371        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14372
14373        boolean firstLine = true;
14374        int lastOomAdj = Integer.MIN_VALUE;
14375        long extraNativeRam = 0;
14376        long cachedPss = 0;
14377        for (int i=0, N=memInfos.size(); i<N; i++) {
14378            ProcessMemInfo mi = memInfos.get(i);
14379
14380            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14381                cachedPss += mi.pss;
14382            }
14383
14384            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14385                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14386                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14387                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14388                if (lastOomAdj != mi.oomAdj) {
14389                    lastOomAdj = mi.oomAdj;
14390                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14391                        tag.append(" / ");
14392                    }
14393                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14394                        if (firstLine) {
14395                            stack.append(":");
14396                            firstLine = false;
14397                        }
14398                        stack.append("\n\t at ");
14399                    } else {
14400                        stack.append("$");
14401                    }
14402                } else {
14403                    tag.append(" ");
14404                    stack.append("$");
14405                }
14406                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14407                    appendMemBucket(tag, mi.pss, mi.name, false);
14408                }
14409                appendMemBucket(stack, mi.pss, mi.name, true);
14410                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14411                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14412                    stack.append("(");
14413                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14414                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14415                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14416                            stack.append(":");
14417                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14418                        }
14419                    }
14420                    stack.append(")");
14421                }
14422            }
14423
14424            appendMemInfo(fullNativeBuilder, mi);
14425            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14426                // The short form only has native processes that are >= 1MB.
14427                if (mi.pss >= 1000) {
14428                    appendMemInfo(shortNativeBuilder, mi);
14429                } else {
14430                    extraNativeRam += mi.pss;
14431                }
14432            } else {
14433                // Short form has all other details, but if we have collected RAM
14434                // from smaller native processes let's dump a summary of that.
14435                if (extraNativeRam > 0) {
14436                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14437                            -1, extraNativeRam, "(Other native)");
14438                    shortNativeBuilder.append('\n');
14439                    extraNativeRam = 0;
14440                }
14441                appendMemInfo(fullJavaBuilder, mi);
14442            }
14443        }
14444
14445        fullJavaBuilder.append("           ");
14446        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14447        fullJavaBuilder.append(" kB: TOTAL\n");
14448
14449        MemInfoReader memInfo = new MemInfoReader();
14450        memInfo.readMemInfo();
14451        final long[] infos = memInfo.getRawInfo();
14452
14453        StringBuilder memInfoBuilder = new StringBuilder(1024);
14454        Debug.getMemInfo(infos);
14455        memInfoBuilder.append("  MemInfo: ");
14456        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14457        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14458        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14459        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14460        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14461        memInfoBuilder.append("           ");
14462        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14463        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14464        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14465        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14466        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14467            memInfoBuilder.append("  ZRAM: ");
14468            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14469            memInfoBuilder.append(" kB RAM, ");
14470            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14471            memInfoBuilder.append(" kB swap total, ");
14472            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14473            memInfoBuilder.append(" kB swap free\n");
14474        }
14475        final long[] ksm = getKsmInfo();
14476        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14477                || ksm[KSM_VOLATILE] != 0) {
14478            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14479            memInfoBuilder.append(" kB saved from shared ");
14480            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14481            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14482            memInfoBuilder.append(" kB unshared; ");
14483            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14484        }
14485        memInfoBuilder.append("  Free RAM: ");
14486        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14487                + memInfo.getFreeSizeKb());
14488        memInfoBuilder.append(" kB\n");
14489        memInfoBuilder.append("  Used RAM: ");
14490        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14491        memInfoBuilder.append(" kB\n");
14492        memInfoBuilder.append("  Lost RAM: ");
14493        memInfoBuilder.append(memInfo.getTotalSizeKb()
14494                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14495                - memInfo.getKernelUsedSizeKb());
14496        memInfoBuilder.append(" kB\n");
14497        Slog.i(TAG, "Low on memory:");
14498        Slog.i(TAG, shortNativeBuilder.toString());
14499        Slog.i(TAG, fullJavaBuilder.toString());
14500        Slog.i(TAG, memInfoBuilder.toString());
14501
14502        StringBuilder dropBuilder = new StringBuilder(1024);
14503        /*
14504        StringWriter oomSw = new StringWriter();
14505        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14506        StringWriter catSw = new StringWriter();
14507        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14508        String[] emptyArgs = new String[] { };
14509        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14510        oomPw.flush();
14511        String oomString = oomSw.toString();
14512        */
14513        dropBuilder.append("Low on memory:");
14514        dropBuilder.append(stack);
14515        dropBuilder.append('\n');
14516        dropBuilder.append(fullNativeBuilder);
14517        dropBuilder.append(fullJavaBuilder);
14518        dropBuilder.append('\n');
14519        dropBuilder.append(memInfoBuilder);
14520        dropBuilder.append('\n');
14521        /*
14522        dropBuilder.append(oomString);
14523        dropBuilder.append('\n');
14524        */
14525        StringWriter catSw = new StringWriter();
14526        synchronized (ActivityManagerService.this) {
14527            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14528            String[] emptyArgs = new String[] { };
14529            catPw.println();
14530            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14531            catPw.println();
14532            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14533                    false, false, null);
14534            catPw.println();
14535            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14536            catPw.flush();
14537        }
14538        dropBuilder.append(catSw.toString());
14539        addErrorToDropBox("lowmem", null, "system_server", null,
14540                null, tag.toString(), dropBuilder.toString(), null, null);
14541        //Slog.i(TAG, "Sent to dropbox:");
14542        //Slog.i(TAG, dropBuilder.toString());
14543        synchronized (ActivityManagerService.this) {
14544            long now = SystemClock.uptimeMillis();
14545            if (mLastMemUsageReportTime < now) {
14546                mLastMemUsageReportTime = now;
14547            }
14548        }
14549    }
14550
14551    /**
14552     * Searches array of arguments for the specified string
14553     * @param args array of argument strings
14554     * @param value value to search for
14555     * @return true if the value is contained in the array
14556     */
14557    private static boolean scanArgs(String[] args, String value) {
14558        if (args != null) {
14559            for (String arg : args) {
14560                if (value.equals(arg)) {
14561                    return true;
14562                }
14563            }
14564        }
14565        return false;
14566    }
14567
14568    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14569            ContentProviderRecord cpr, boolean always) {
14570        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14571
14572        if (!inLaunching || always) {
14573            synchronized (cpr) {
14574                cpr.launchingApp = null;
14575                cpr.notifyAll();
14576            }
14577            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14578            String names[] = cpr.info.authority.split(";");
14579            for (int j = 0; j < names.length; j++) {
14580                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14581            }
14582        }
14583
14584        for (int i=0; i<cpr.connections.size(); i++) {
14585            ContentProviderConnection conn = cpr.connections.get(i);
14586            if (conn.waiting) {
14587                // If this connection is waiting for the provider, then we don't
14588                // need to mess with its process unless we are always removing
14589                // or for some reason the provider is not currently launching.
14590                if (inLaunching && !always) {
14591                    continue;
14592                }
14593            }
14594            ProcessRecord capp = conn.client;
14595            conn.dead = true;
14596            if (conn.stableCount > 0) {
14597                if (!capp.persistent && capp.thread != null
14598                        && capp.pid != 0
14599                        && capp.pid != MY_PID) {
14600                    capp.kill("depends on provider "
14601                            + cpr.name.flattenToShortString()
14602                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14603                }
14604            } else if (capp.thread != null && conn.provider.provider != null) {
14605                try {
14606                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14607                } catch (RemoteException e) {
14608                }
14609                // In the protocol here, we don't expect the client to correctly
14610                // clean up this connection, we'll just remove it.
14611                cpr.connections.remove(i);
14612                conn.client.conProviders.remove(conn);
14613            }
14614        }
14615
14616        if (inLaunching && always) {
14617            mLaunchingProviders.remove(cpr);
14618        }
14619        return inLaunching;
14620    }
14621
14622    /**
14623     * Main code for cleaning up a process when it has gone away.  This is
14624     * called both as a result of the process dying, or directly when stopping
14625     * a process when running in single process mode.
14626     *
14627     * @return Returns true if the given process has been restarted, so the
14628     * app that was passed in must remain on the process lists.
14629     */
14630    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14631            boolean restarting, boolean allowRestart, int index) {
14632        if (index >= 0) {
14633            removeLruProcessLocked(app);
14634            ProcessList.remove(app.pid);
14635        }
14636
14637        mProcessesToGc.remove(app);
14638        mPendingPssProcesses.remove(app);
14639
14640        // Dismiss any open dialogs.
14641        if (app.crashDialog != null && !app.forceCrashReport) {
14642            app.crashDialog.dismiss();
14643            app.crashDialog = null;
14644        }
14645        if (app.anrDialog != null) {
14646            app.anrDialog.dismiss();
14647            app.anrDialog = null;
14648        }
14649        if (app.waitDialog != null) {
14650            app.waitDialog.dismiss();
14651            app.waitDialog = null;
14652        }
14653
14654        app.crashing = false;
14655        app.notResponding = false;
14656
14657        app.resetPackageList(mProcessStats);
14658        app.unlinkDeathRecipient();
14659        app.makeInactive(mProcessStats);
14660        app.waitingToKill = null;
14661        app.forcingToForeground = null;
14662        updateProcessForegroundLocked(app, false, false);
14663        app.foregroundActivities = false;
14664        app.hasShownUi = false;
14665        app.treatLikeActivity = false;
14666        app.hasAboveClient = false;
14667        app.hasClientActivities = false;
14668
14669        mServices.killServicesLocked(app, allowRestart);
14670
14671        boolean restart = false;
14672
14673        // Remove published content providers.
14674        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14675            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14676            final boolean always = app.bad || !allowRestart;
14677            if (removeDyingProviderLocked(app, cpr, always) || always) {
14678                // We left the provider in the launching list, need to
14679                // restart it.
14680                restart = true;
14681            }
14682
14683            cpr.provider = null;
14684            cpr.proc = null;
14685        }
14686        app.pubProviders.clear();
14687
14688        // Take care of any launching providers waiting for this process.
14689        if (checkAppInLaunchingProvidersLocked(app, false)) {
14690            restart = true;
14691        }
14692
14693        // Unregister from connected content providers.
14694        if (!app.conProviders.isEmpty()) {
14695            for (int i=0; i<app.conProviders.size(); i++) {
14696                ContentProviderConnection conn = app.conProviders.get(i);
14697                conn.provider.connections.remove(conn);
14698            }
14699            app.conProviders.clear();
14700        }
14701
14702        // At this point there may be remaining entries in mLaunchingProviders
14703        // where we were the only one waiting, so they are no longer of use.
14704        // Look for these and clean up if found.
14705        // XXX Commented out for now.  Trying to figure out a way to reproduce
14706        // the actual situation to identify what is actually going on.
14707        if (false) {
14708            for (int i=0; i<mLaunchingProviders.size(); i++) {
14709                ContentProviderRecord cpr = (ContentProviderRecord)
14710                        mLaunchingProviders.get(i);
14711                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14712                    synchronized (cpr) {
14713                        cpr.launchingApp = null;
14714                        cpr.notifyAll();
14715                    }
14716                }
14717            }
14718        }
14719
14720        skipCurrentReceiverLocked(app);
14721
14722        // Unregister any receivers.
14723        for (int i=app.receivers.size()-1; i>=0; i--) {
14724            removeReceiverLocked(app.receivers.valueAt(i));
14725        }
14726        app.receivers.clear();
14727
14728        // If the app is undergoing backup, tell the backup manager about it
14729        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14730            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14731                    + mBackupTarget.appInfo + " died during backup");
14732            try {
14733                IBackupManager bm = IBackupManager.Stub.asInterface(
14734                        ServiceManager.getService(Context.BACKUP_SERVICE));
14735                bm.agentDisconnected(app.info.packageName);
14736            } catch (RemoteException e) {
14737                // can't happen; backup manager is local
14738            }
14739        }
14740
14741        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14742            ProcessChangeItem item = mPendingProcessChanges.get(i);
14743            if (item.pid == app.pid) {
14744                mPendingProcessChanges.remove(i);
14745                mAvailProcessChanges.add(item);
14746            }
14747        }
14748        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14749
14750        // If the caller is restarting this app, then leave it in its
14751        // current lists and let the caller take care of it.
14752        if (restarting) {
14753            return false;
14754        }
14755
14756        if (!app.persistent || app.isolated) {
14757            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14758                    "Removing non-persistent process during cleanup: " + app);
14759            mProcessNames.remove(app.processName, app.uid);
14760            mIsolatedProcesses.remove(app.uid);
14761            if (mHeavyWeightProcess == app) {
14762                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14763                        mHeavyWeightProcess.userId, 0));
14764                mHeavyWeightProcess = null;
14765            }
14766        } else if (!app.removed) {
14767            // This app is persistent, so we need to keep its record around.
14768            // If it is not already on the pending app list, add it there
14769            // and start a new process for it.
14770            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14771                mPersistentStartingProcesses.add(app);
14772                restart = true;
14773            }
14774        }
14775        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14776                "Clean-up removing on hold: " + app);
14777        mProcessesOnHold.remove(app);
14778
14779        if (app == mHomeProcess) {
14780            mHomeProcess = null;
14781        }
14782        if (app == mPreviousProcess) {
14783            mPreviousProcess = null;
14784        }
14785
14786        if (restart && !app.isolated) {
14787            // We have components that still need to be running in the
14788            // process, so re-launch it.
14789            if (index < 0) {
14790                ProcessList.remove(app.pid);
14791            }
14792            mProcessNames.put(app.processName, app.uid, app);
14793            startProcessLocked(app, "restart", app.processName);
14794            return true;
14795        } else if (app.pid > 0 && app.pid != MY_PID) {
14796            // Goodbye!
14797            boolean removed;
14798            synchronized (mPidsSelfLocked) {
14799                mPidsSelfLocked.remove(app.pid);
14800                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14801            }
14802            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14803            if (app.isolated) {
14804                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14805            }
14806            app.setPid(0);
14807        }
14808        return false;
14809    }
14810
14811    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14812        // Look through the content providers we are waiting to have launched,
14813        // and if any run in this process then either schedule a restart of
14814        // the process or kill the client waiting for it if this process has
14815        // gone bad.
14816        int NL = mLaunchingProviders.size();
14817        boolean restart = false;
14818        for (int i=0; i<NL; i++) {
14819            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14820            if (cpr.launchingApp == app) {
14821                if (!alwaysBad && !app.bad) {
14822                    restart = true;
14823                } else {
14824                    removeDyingProviderLocked(app, cpr, true);
14825                    // cpr should have been removed from mLaunchingProviders
14826                    NL = mLaunchingProviders.size();
14827                    i--;
14828                }
14829            }
14830        }
14831        return restart;
14832    }
14833
14834    // =========================================================
14835    // SERVICES
14836    // =========================================================
14837
14838    @Override
14839    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14840            int flags) {
14841        enforceNotIsolatedCaller("getServices");
14842        synchronized (this) {
14843            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14844        }
14845    }
14846
14847    @Override
14848    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14849        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14850        synchronized (this) {
14851            return mServices.getRunningServiceControlPanelLocked(name);
14852        }
14853    }
14854
14855    @Override
14856    public ComponentName startService(IApplicationThread caller, Intent service,
14857            String resolvedType, int userId) {
14858        enforceNotIsolatedCaller("startService");
14859        // Refuse possible leaked file descriptors
14860        if (service != null && service.hasFileDescriptors() == true) {
14861            throw new IllegalArgumentException("File descriptors passed in Intent");
14862        }
14863
14864        if (DEBUG_SERVICE)
14865            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14866        synchronized(this) {
14867            final int callingPid = Binder.getCallingPid();
14868            final int callingUid = Binder.getCallingUid();
14869            final long origId = Binder.clearCallingIdentity();
14870            ComponentName res = mServices.startServiceLocked(caller, service,
14871                    resolvedType, callingPid, callingUid, userId);
14872            Binder.restoreCallingIdentity(origId);
14873            return res;
14874        }
14875    }
14876
14877    ComponentName startServiceInPackage(int uid,
14878            Intent service, String resolvedType, int userId) {
14879        synchronized(this) {
14880            if (DEBUG_SERVICE)
14881                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14882            final long origId = Binder.clearCallingIdentity();
14883            ComponentName res = mServices.startServiceLocked(null, service,
14884                    resolvedType, -1, uid, userId);
14885            Binder.restoreCallingIdentity(origId);
14886            return res;
14887        }
14888    }
14889
14890    @Override
14891    public int stopService(IApplicationThread caller, Intent service,
14892            String resolvedType, int userId) {
14893        enforceNotIsolatedCaller("stopService");
14894        // Refuse possible leaked file descriptors
14895        if (service != null && service.hasFileDescriptors() == true) {
14896            throw new IllegalArgumentException("File descriptors passed in Intent");
14897        }
14898
14899        synchronized(this) {
14900            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14901        }
14902    }
14903
14904    @Override
14905    public IBinder peekService(Intent service, String resolvedType) {
14906        enforceNotIsolatedCaller("peekService");
14907        // Refuse possible leaked file descriptors
14908        if (service != null && service.hasFileDescriptors() == true) {
14909            throw new IllegalArgumentException("File descriptors passed in Intent");
14910        }
14911        synchronized(this) {
14912            return mServices.peekServiceLocked(service, resolvedType);
14913        }
14914    }
14915
14916    @Override
14917    public boolean stopServiceToken(ComponentName className, IBinder token,
14918            int startId) {
14919        synchronized(this) {
14920            return mServices.stopServiceTokenLocked(className, token, startId);
14921        }
14922    }
14923
14924    @Override
14925    public void setServiceForeground(ComponentName className, IBinder token,
14926            int id, Notification notification, boolean removeNotification) {
14927        synchronized(this) {
14928            mServices.setServiceForegroundLocked(className, token, id, notification,
14929                    removeNotification);
14930        }
14931    }
14932
14933    @Override
14934    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14935            boolean requireFull, String name, String callerPackage) {
14936        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14937                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14938    }
14939
14940    int unsafeConvertIncomingUser(int userId) {
14941        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14942                ? mCurrentUserId : userId;
14943    }
14944
14945    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14946            int allowMode, String name, String callerPackage) {
14947        final int callingUserId = UserHandle.getUserId(callingUid);
14948        if (callingUserId == userId) {
14949            return userId;
14950        }
14951
14952        // Note that we may be accessing mCurrentUserId outside of a lock...
14953        // shouldn't be a big deal, if this is being called outside
14954        // of a locked context there is intrinsically a race with
14955        // the value the caller will receive and someone else changing it.
14956        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14957        // we will switch to the calling user if access to the current user fails.
14958        int targetUserId = unsafeConvertIncomingUser(userId);
14959
14960        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14961            final boolean allow;
14962            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14963                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14964                // If the caller has this permission, they always pass go.  And collect $200.
14965                allow = true;
14966            } else if (allowMode == ALLOW_FULL_ONLY) {
14967                // We require full access, sucks to be you.
14968                allow = false;
14969            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14970                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14971                // If the caller does not have either permission, they are always doomed.
14972                allow = false;
14973            } else if (allowMode == ALLOW_NON_FULL) {
14974                // We are blanket allowing non-full access, you lucky caller!
14975                allow = true;
14976            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14977                // We may or may not allow this depending on whether the two users are
14978                // in the same profile.
14979                synchronized (mUserProfileGroupIdsSelfLocked) {
14980                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14981                            UserInfo.NO_PROFILE_GROUP_ID);
14982                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14983                            UserInfo.NO_PROFILE_GROUP_ID);
14984                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14985                            && callingProfile == targetProfile;
14986                }
14987            } else {
14988                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14989            }
14990            if (!allow) {
14991                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14992                    // In this case, they would like to just execute as their
14993                    // owner user instead of failing.
14994                    targetUserId = callingUserId;
14995                } else {
14996                    StringBuilder builder = new StringBuilder(128);
14997                    builder.append("Permission Denial: ");
14998                    builder.append(name);
14999                    if (callerPackage != null) {
15000                        builder.append(" from ");
15001                        builder.append(callerPackage);
15002                    }
15003                    builder.append(" asks to run as user ");
15004                    builder.append(userId);
15005                    builder.append(" but is calling from user ");
15006                    builder.append(UserHandle.getUserId(callingUid));
15007                    builder.append("; this requires ");
15008                    builder.append(INTERACT_ACROSS_USERS_FULL);
15009                    if (allowMode != ALLOW_FULL_ONLY) {
15010                        builder.append(" or ");
15011                        builder.append(INTERACT_ACROSS_USERS);
15012                    }
15013                    String msg = builder.toString();
15014                    Slog.w(TAG, msg);
15015                    throw new SecurityException(msg);
15016                }
15017            }
15018        }
15019        if (!allowAll && targetUserId < 0) {
15020            throw new IllegalArgumentException(
15021                    "Call does not support special user #" + targetUserId);
15022        }
15023        // Check shell permission
15024        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15025            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15026                    targetUserId)) {
15027                throw new SecurityException("Shell does not have permission to access user "
15028                        + targetUserId + "\n " + Debug.getCallers(3));
15029            }
15030        }
15031        return targetUserId;
15032    }
15033
15034    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15035            String className, int flags) {
15036        boolean result = false;
15037        // For apps that don't have pre-defined UIDs, check for permission
15038        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15039            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15040                if (ActivityManager.checkUidPermission(
15041                        INTERACT_ACROSS_USERS,
15042                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15043                    ComponentName comp = new ComponentName(aInfo.packageName, className);
15044                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
15045                            + " requests FLAG_SINGLE_USER, but app does not hold "
15046                            + INTERACT_ACROSS_USERS;
15047                    Slog.w(TAG, msg);
15048                    throw new SecurityException(msg);
15049                }
15050                // Permission passed
15051                result = true;
15052            }
15053        } else if ("system".equals(componentProcessName)) {
15054            result = true;
15055        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15056            // Phone app and persistent apps are allowed to export singleuser providers.
15057            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15058                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15059        }
15060        if (DEBUG_MU) {
15061            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15062                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15063        }
15064        return result;
15065    }
15066
15067    /**
15068     * Checks to see if the caller is in the same app as the singleton
15069     * component, or the component is in a special app. It allows special apps
15070     * to export singleton components but prevents exporting singleton
15071     * components for regular apps.
15072     */
15073    boolean isValidSingletonCall(int callingUid, int componentUid) {
15074        int componentAppId = UserHandle.getAppId(componentUid);
15075        return UserHandle.isSameApp(callingUid, componentUid)
15076                || componentAppId == Process.SYSTEM_UID
15077                || componentAppId == Process.PHONE_UID
15078                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15079                        == PackageManager.PERMISSION_GRANTED;
15080    }
15081
15082    public int bindService(IApplicationThread caller, IBinder token,
15083            Intent service, String resolvedType,
15084            IServiceConnection connection, int flags, int userId) {
15085        enforceNotIsolatedCaller("bindService");
15086
15087        // Refuse possible leaked file descriptors
15088        if (service != null && service.hasFileDescriptors() == true) {
15089            throw new IllegalArgumentException("File descriptors passed in Intent");
15090        }
15091
15092        synchronized(this) {
15093            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15094                    connection, flags, userId);
15095        }
15096    }
15097
15098    public boolean unbindService(IServiceConnection connection) {
15099        synchronized (this) {
15100            return mServices.unbindServiceLocked(connection);
15101        }
15102    }
15103
15104    public void publishService(IBinder token, Intent intent, IBinder service) {
15105        // Refuse possible leaked file descriptors
15106        if (intent != null && intent.hasFileDescriptors() == true) {
15107            throw new IllegalArgumentException("File descriptors passed in Intent");
15108        }
15109
15110        synchronized(this) {
15111            if (!(token instanceof ServiceRecord)) {
15112                throw new IllegalArgumentException("Invalid service token");
15113            }
15114            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15115        }
15116    }
15117
15118    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15119        // Refuse possible leaked file descriptors
15120        if (intent != null && intent.hasFileDescriptors() == true) {
15121            throw new IllegalArgumentException("File descriptors passed in Intent");
15122        }
15123
15124        synchronized(this) {
15125            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15126        }
15127    }
15128
15129    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15130        synchronized(this) {
15131            if (!(token instanceof ServiceRecord)) {
15132                throw new IllegalArgumentException("Invalid service token");
15133            }
15134            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15135        }
15136    }
15137
15138    // =========================================================
15139    // BACKUP AND RESTORE
15140    // =========================================================
15141
15142    // Cause the target app to be launched if necessary and its backup agent
15143    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15144    // activity manager to announce its creation.
15145    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15146        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15147        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15148
15149        synchronized(this) {
15150            // !!! TODO: currently no check here that we're already bound
15151            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15152            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15153            synchronized (stats) {
15154                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15155            }
15156
15157            // Backup agent is now in use, its package can't be stopped.
15158            try {
15159                AppGlobals.getPackageManager().setPackageStoppedState(
15160                        app.packageName, false, UserHandle.getUserId(app.uid));
15161            } catch (RemoteException e) {
15162            } catch (IllegalArgumentException e) {
15163                Slog.w(TAG, "Failed trying to unstop package "
15164                        + app.packageName + ": " + e);
15165            }
15166
15167            BackupRecord r = new BackupRecord(ss, app, backupMode);
15168            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15169                    ? new ComponentName(app.packageName, app.backupAgentName)
15170                    : new ComponentName("android", "FullBackupAgent");
15171            // startProcessLocked() returns existing proc's record if it's already running
15172            ProcessRecord proc = startProcessLocked(app.processName, app,
15173                    false, 0, "backup", hostingName, false, false, false);
15174            if (proc == null) {
15175                Slog.e(TAG, "Unable to start backup agent process " + r);
15176                return false;
15177            }
15178
15179            r.app = proc;
15180            mBackupTarget = r;
15181            mBackupAppName = app.packageName;
15182
15183            // Try not to kill the process during backup
15184            updateOomAdjLocked(proc);
15185
15186            // If the process is already attached, schedule the creation of the backup agent now.
15187            // If it is not yet live, this will be done when it attaches to the framework.
15188            if (proc.thread != null) {
15189                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15190                try {
15191                    proc.thread.scheduleCreateBackupAgent(app,
15192                            compatibilityInfoForPackageLocked(app), backupMode);
15193                } catch (RemoteException e) {
15194                    // Will time out on the backup manager side
15195                }
15196            } else {
15197                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15198            }
15199            // Invariants: at this point, the target app process exists and the application
15200            // is either already running or in the process of coming up.  mBackupTarget and
15201            // mBackupAppName describe the app, so that when it binds back to the AM we
15202            // know that it's scheduled for a backup-agent operation.
15203        }
15204
15205        return true;
15206    }
15207
15208    @Override
15209    public void clearPendingBackup() {
15210        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15211        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15212
15213        synchronized (this) {
15214            mBackupTarget = null;
15215            mBackupAppName = null;
15216        }
15217    }
15218
15219    // A backup agent has just come up
15220    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15221        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15222                + " = " + agent);
15223
15224        synchronized(this) {
15225            if (!agentPackageName.equals(mBackupAppName)) {
15226                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15227                return;
15228            }
15229        }
15230
15231        long oldIdent = Binder.clearCallingIdentity();
15232        try {
15233            IBackupManager bm = IBackupManager.Stub.asInterface(
15234                    ServiceManager.getService(Context.BACKUP_SERVICE));
15235            bm.agentConnected(agentPackageName, agent);
15236        } catch (RemoteException e) {
15237            // can't happen; the backup manager service is local
15238        } catch (Exception e) {
15239            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15240            e.printStackTrace();
15241        } finally {
15242            Binder.restoreCallingIdentity(oldIdent);
15243        }
15244    }
15245
15246    // done with this agent
15247    public void unbindBackupAgent(ApplicationInfo appInfo) {
15248        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15249        if (appInfo == null) {
15250            Slog.w(TAG, "unbind backup agent for null app");
15251            return;
15252        }
15253
15254        synchronized(this) {
15255            try {
15256                if (mBackupAppName == null) {
15257                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15258                    return;
15259                }
15260
15261                if (!mBackupAppName.equals(appInfo.packageName)) {
15262                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15263                    return;
15264                }
15265
15266                // Not backing this app up any more; reset its OOM adjustment
15267                final ProcessRecord proc = mBackupTarget.app;
15268                updateOomAdjLocked(proc);
15269
15270                // If the app crashed during backup, 'thread' will be null here
15271                if (proc.thread != null) {
15272                    try {
15273                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15274                                compatibilityInfoForPackageLocked(appInfo));
15275                    } catch (Exception e) {
15276                        Slog.e(TAG, "Exception when unbinding backup agent:");
15277                        e.printStackTrace();
15278                    }
15279                }
15280            } finally {
15281                mBackupTarget = null;
15282                mBackupAppName = null;
15283            }
15284        }
15285    }
15286    // =========================================================
15287    // BROADCASTS
15288    // =========================================================
15289
15290    private final List getStickiesLocked(String action, IntentFilter filter,
15291            List cur, int userId) {
15292        final ContentResolver resolver = mContext.getContentResolver();
15293        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15294        if (stickies == null) {
15295            return cur;
15296        }
15297        final ArrayList<Intent> list = stickies.get(action);
15298        if (list == null) {
15299            return cur;
15300        }
15301        int N = list.size();
15302        for (int i=0; i<N; i++) {
15303            Intent intent = list.get(i);
15304            if (filter.match(resolver, intent, true, TAG) >= 0) {
15305                if (cur == null) {
15306                    cur = new ArrayList<Intent>();
15307                }
15308                cur.add(intent);
15309            }
15310        }
15311        return cur;
15312    }
15313
15314    boolean isPendingBroadcastProcessLocked(int pid) {
15315        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15316                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15317    }
15318
15319    void skipPendingBroadcastLocked(int pid) {
15320            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15321            for (BroadcastQueue queue : mBroadcastQueues) {
15322                queue.skipPendingBroadcastLocked(pid);
15323            }
15324    }
15325
15326    // The app just attached; send any pending broadcasts that it should receive
15327    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15328        boolean didSomething = false;
15329        for (BroadcastQueue queue : mBroadcastQueues) {
15330            didSomething |= queue.sendPendingBroadcastsLocked(app);
15331        }
15332        return didSomething;
15333    }
15334
15335    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15336            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15337        enforceNotIsolatedCaller("registerReceiver");
15338        int callingUid;
15339        int callingPid;
15340        synchronized(this) {
15341            ProcessRecord callerApp = null;
15342            if (caller != null) {
15343                callerApp = getRecordForAppLocked(caller);
15344                if (callerApp == null) {
15345                    throw new SecurityException(
15346                            "Unable to find app for caller " + caller
15347                            + " (pid=" + Binder.getCallingPid()
15348                            + ") when registering receiver " + receiver);
15349                }
15350                if (callerApp.info.uid != Process.SYSTEM_UID &&
15351                        !callerApp.pkgList.containsKey(callerPackage) &&
15352                        !"android".equals(callerPackage)) {
15353                    throw new SecurityException("Given caller package " + callerPackage
15354                            + " is not running in process " + callerApp);
15355                }
15356                callingUid = callerApp.info.uid;
15357                callingPid = callerApp.pid;
15358            } else {
15359                callerPackage = null;
15360                callingUid = Binder.getCallingUid();
15361                callingPid = Binder.getCallingPid();
15362            }
15363
15364            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15365                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15366
15367            List allSticky = null;
15368
15369            // Look for any matching sticky broadcasts...
15370            Iterator actions = filter.actionsIterator();
15371            if (actions != null) {
15372                while (actions.hasNext()) {
15373                    String action = (String)actions.next();
15374                    allSticky = getStickiesLocked(action, filter, allSticky,
15375                            UserHandle.USER_ALL);
15376                    allSticky = getStickiesLocked(action, filter, allSticky,
15377                            UserHandle.getUserId(callingUid));
15378                }
15379            } else {
15380                allSticky = getStickiesLocked(null, filter, allSticky,
15381                        UserHandle.USER_ALL);
15382                allSticky = getStickiesLocked(null, filter, allSticky,
15383                        UserHandle.getUserId(callingUid));
15384            }
15385
15386            // The first sticky in the list is returned directly back to
15387            // the client.
15388            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15389
15390            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15391                    + ": " + sticky);
15392
15393            if (receiver == null) {
15394                return sticky;
15395            }
15396
15397            ReceiverList rl
15398                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15399            if (rl == null) {
15400                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15401                        userId, receiver);
15402                if (rl.app != null) {
15403                    rl.app.receivers.add(rl);
15404                } else {
15405                    try {
15406                        receiver.asBinder().linkToDeath(rl, 0);
15407                    } catch (RemoteException e) {
15408                        return sticky;
15409                    }
15410                    rl.linkedToDeath = true;
15411                }
15412                mRegisteredReceivers.put(receiver.asBinder(), rl);
15413            } else if (rl.uid != callingUid) {
15414                throw new IllegalArgumentException(
15415                        "Receiver requested to register for uid " + callingUid
15416                        + " was previously registered for uid " + rl.uid);
15417            } else if (rl.pid != callingPid) {
15418                throw new IllegalArgumentException(
15419                        "Receiver requested to register for pid " + callingPid
15420                        + " was previously registered for pid " + rl.pid);
15421            } else if (rl.userId != userId) {
15422                throw new IllegalArgumentException(
15423                        "Receiver requested to register for user " + userId
15424                        + " was previously registered for user " + rl.userId);
15425            }
15426            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15427                    permission, callingUid, userId);
15428            rl.add(bf);
15429            if (!bf.debugCheck()) {
15430                Slog.w(TAG, "==> For Dynamic broadast");
15431            }
15432            mReceiverResolver.addFilter(bf);
15433
15434            // Enqueue broadcasts for all existing stickies that match
15435            // this filter.
15436            if (allSticky != null) {
15437                ArrayList receivers = new ArrayList();
15438                receivers.add(bf);
15439
15440                int N = allSticky.size();
15441                for (int i=0; i<N; i++) {
15442                    Intent intent = (Intent)allSticky.get(i);
15443                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15444                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15445                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15446                            null, null, false, true, true, -1);
15447                    queue.enqueueParallelBroadcastLocked(r);
15448                    queue.scheduleBroadcastsLocked();
15449                }
15450            }
15451
15452            return sticky;
15453        }
15454    }
15455
15456    public void unregisterReceiver(IIntentReceiver receiver) {
15457        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15458
15459        final long origId = Binder.clearCallingIdentity();
15460        try {
15461            boolean doTrim = false;
15462
15463            synchronized(this) {
15464                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15465                if (rl != null) {
15466                    if (rl.curBroadcast != null) {
15467                        BroadcastRecord r = rl.curBroadcast;
15468                        final boolean doNext = finishReceiverLocked(
15469                                receiver.asBinder(), r.resultCode, r.resultData,
15470                                r.resultExtras, r.resultAbort);
15471                        if (doNext) {
15472                            doTrim = true;
15473                            r.queue.processNextBroadcast(false);
15474                        }
15475                    }
15476
15477                    if (rl.app != null) {
15478                        rl.app.receivers.remove(rl);
15479                    }
15480                    removeReceiverLocked(rl);
15481                    if (rl.linkedToDeath) {
15482                        rl.linkedToDeath = false;
15483                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15484                    }
15485                }
15486            }
15487
15488            // If we actually concluded any broadcasts, we might now be able
15489            // to trim the recipients' apps from our working set
15490            if (doTrim) {
15491                trimApplications();
15492                return;
15493            }
15494
15495        } finally {
15496            Binder.restoreCallingIdentity(origId);
15497        }
15498    }
15499
15500    void removeReceiverLocked(ReceiverList rl) {
15501        mRegisteredReceivers.remove(rl.receiver.asBinder());
15502        int N = rl.size();
15503        for (int i=0; i<N; i++) {
15504            mReceiverResolver.removeFilter(rl.get(i));
15505        }
15506    }
15507
15508    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15509        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15510            ProcessRecord r = mLruProcesses.get(i);
15511            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15512                try {
15513                    r.thread.dispatchPackageBroadcast(cmd, packages);
15514                } catch (RemoteException ex) {
15515                }
15516            }
15517        }
15518    }
15519
15520    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15521            int callingUid, int[] users) {
15522        List<ResolveInfo> receivers = null;
15523        try {
15524            HashSet<ComponentName> singleUserReceivers = null;
15525            boolean scannedFirstReceivers = false;
15526            for (int user : users) {
15527                // Skip users that have Shell restrictions
15528                if (callingUid == Process.SHELL_UID
15529                        && getUserManagerLocked().hasUserRestriction(
15530                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15531                    continue;
15532                }
15533                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15534                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15535                if (user != 0 && newReceivers != null) {
15536                    // If this is not the primary user, we need to check for
15537                    // any receivers that should be filtered out.
15538                    for (int i=0; i<newReceivers.size(); i++) {
15539                        ResolveInfo ri = newReceivers.get(i);
15540                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15541                            newReceivers.remove(i);
15542                            i--;
15543                        }
15544                    }
15545                }
15546                if (newReceivers != null && newReceivers.size() == 0) {
15547                    newReceivers = null;
15548                }
15549                if (receivers == null) {
15550                    receivers = newReceivers;
15551                } else if (newReceivers != null) {
15552                    // We need to concatenate the additional receivers
15553                    // found with what we have do far.  This would be easy,
15554                    // but we also need to de-dup any receivers that are
15555                    // singleUser.
15556                    if (!scannedFirstReceivers) {
15557                        // Collect any single user receivers we had already retrieved.
15558                        scannedFirstReceivers = true;
15559                        for (int i=0; i<receivers.size(); i++) {
15560                            ResolveInfo ri = receivers.get(i);
15561                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15562                                ComponentName cn = new ComponentName(
15563                                        ri.activityInfo.packageName, ri.activityInfo.name);
15564                                if (singleUserReceivers == null) {
15565                                    singleUserReceivers = new HashSet<ComponentName>();
15566                                }
15567                                singleUserReceivers.add(cn);
15568                            }
15569                        }
15570                    }
15571                    // Add the new results to the existing results, tracking
15572                    // and de-dupping single user receivers.
15573                    for (int i=0; i<newReceivers.size(); i++) {
15574                        ResolveInfo ri = newReceivers.get(i);
15575                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15576                            ComponentName cn = new ComponentName(
15577                                    ri.activityInfo.packageName, ri.activityInfo.name);
15578                            if (singleUserReceivers == null) {
15579                                singleUserReceivers = new HashSet<ComponentName>();
15580                            }
15581                            if (!singleUserReceivers.contains(cn)) {
15582                                singleUserReceivers.add(cn);
15583                                receivers.add(ri);
15584                            }
15585                        } else {
15586                            receivers.add(ri);
15587                        }
15588                    }
15589                }
15590            }
15591        } catch (RemoteException ex) {
15592            // pm is in same process, this will never happen.
15593        }
15594        return receivers;
15595    }
15596
15597    private final int broadcastIntentLocked(ProcessRecord callerApp,
15598            String callerPackage, Intent intent, String resolvedType,
15599            IIntentReceiver resultTo, int resultCode, String resultData,
15600            Bundle map, String requiredPermission, int appOp,
15601            boolean ordered, boolean sticky, int callingPid, int callingUid,
15602            int userId) {
15603        intent = new Intent(intent);
15604
15605        // By default broadcasts do not go to stopped apps.
15606        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15607
15608        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15609            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15610            + " ordered=" + ordered + " userid=" + userId);
15611        if ((resultTo != null) && !ordered) {
15612            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15613        }
15614
15615        userId = handleIncomingUser(callingPid, callingUid, userId,
15616                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15617
15618        // Make sure that the user who is receiving this broadcast is started.
15619        // If not, we will just skip it.
15620
15621        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15622            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15623                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15624                Slog.w(TAG, "Skipping broadcast of " + intent
15625                        + ": user " + userId + " is stopped");
15626                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15627            }
15628        }
15629
15630        /*
15631         * Prevent non-system code (defined here to be non-persistent
15632         * processes) from sending protected broadcasts.
15633         */
15634        int callingAppId = UserHandle.getAppId(callingUid);
15635        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15636            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15637            || callingAppId == Process.NFC_UID || callingUid == 0) {
15638            // Always okay.
15639        } else if (callerApp == null || !callerApp.persistent) {
15640            try {
15641                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15642                        intent.getAction())) {
15643                    String msg = "Permission Denial: not allowed to send broadcast "
15644                            + intent.getAction() + " from pid="
15645                            + callingPid + ", uid=" + callingUid;
15646                    Slog.w(TAG, msg);
15647                    throw new SecurityException(msg);
15648                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15649                    // Special case for compatibility: we don't want apps to send this,
15650                    // but historically it has not been protected and apps may be using it
15651                    // to poke their own app widget.  So, instead of making it protected,
15652                    // just limit it to the caller.
15653                    if (callerApp == null) {
15654                        String msg = "Permission Denial: not allowed to send broadcast "
15655                                + intent.getAction() + " from unknown caller.";
15656                        Slog.w(TAG, msg);
15657                        throw new SecurityException(msg);
15658                    } else if (intent.getComponent() != null) {
15659                        // They are good enough to send to an explicit component...  verify
15660                        // it is being sent to the calling app.
15661                        if (!intent.getComponent().getPackageName().equals(
15662                                callerApp.info.packageName)) {
15663                            String msg = "Permission Denial: not allowed to send broadcast "
15664                                    + intent.getAction() + " to "
15665                                    + intent.getComponent().getPackageName() + " from "
15666                                    + callerApp.info.packageName;
15667                            Slog.w(TAG, msg);
15668                            throw new SecurityException(msg);
15669                        }
15670                    } else {
15671                        // Limit broadcast to their own package.
15672                        intent.setPackage(callerApp.info.packageName);
15673                    }
15674                }
15675            } catch (RemoteException e) {
15676                Slog.w(TAG, "Remote exception", e);
15677                return ActivityManager.BROADCAST_SUCCESS;
15678            }
15679        }
15680
15681        // Handle special intents: if this broadcast is from the package
15682        // manager about a package being removed, we need to remove all of
15683        // its activities from the history stack.
15684        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15685                intent.getAction());
15686        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15687                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15688                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15689                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15690                || uidRemoved) {
15691            if (checkComponentPermission(
15692                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15693                    callingPid, callingUid, -1, true)
15694                    == PackageManager.PERMISSION_GRANTED) {
15695                if (uidRemoved) {
15696                    final Bundle intentExtras = intent.getExtras();
15697                    final int uid = intentExtras != null
15698                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15699                    if (uid >= 0) {
15700                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15701                        synchronized (bs) {
15702                            bs.removeUidStatsLocked(uid);
15703                        }
15704                        mAppOpsService.uidRemoved(uid);
15705                    }
15706                } else {
15707                    // If resources are unavailable just force stop all
15708                    // those packages and flush the attribute cache as well.
15709                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15710                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15711                        if (list != null && (list.length > 0)) {
15712                            for (String pkg : list) {
15713                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15714                                        "storage unmount");
15715                            }
15716                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15717                            sendPackageBroadcastLocked(
15718                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15719                        }
15720                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15721                            intent.getAction())) {
15722                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15723                    } else {
15724                        Uri data = intent.getData();
15725                        String ssp;
15726                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15727                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15728                                    intent.getAction());
15729                            boolean fullUninstall = removed &&
15730                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15731                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15732                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15733                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15734                                        false, fullUninstall, userId,
15735                                        removed ? "pkg removed" : "pkg changed");
15736                            }
15737                            if (removed) {
15738                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15739                                        new String[] {ssp}, userId);
15740                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15741                                    mAppOpsService.packageRemoved(
15742                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15743
15744                                    // Remove all permissions granted from/to this package
15745                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15746                                }
15747                            }
15748                        }
15749                    }
15750                }
15751            } else {
15752                String msg = "Permission Denial: " + intent.getAction()
15753                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15754                        + ", uid=" + callingUid + ")"
15755                        + " requires "
15756                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15757                Slog.w(TAG, msg);
15758                throw new SecurityException(msg);
15759            }
15760
15761        // Special case for adding a package: by default turn on compatibility
15762        // mode.
15763        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15764            Uri data = intent.getData();
15765            String ssp;
15766            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15767                mCompatModePackages.handlePackageAddedLocked(ssp,
15768                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15769            }
15770        }
15771
15772        /*
15773         * If this is the time zone changed action, queue up a message that will reset the timezone
15774         * of all currently running processes. This message will get queued up before the broadcast
15775         * happens.
15776         */
15777        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15778            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15779        }
15780
15781        /*
15782         * If the user set the time, let all running processes know.
15783         */
15784        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15785            final int is24Hour = intent.getBooleanExtra(
15786                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15787            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15788            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15789            synchronized (stats) {
15790                stats.noteCurrentTimeChangedLocked();
15791            }
15792        }
15793
15794        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15795            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15796        }
15797
15798        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15799            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15800            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15801        }
15802
15803        // Add to the sticky list if requested.
15804        if (sticky) {
15805            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15806                    callingPid, callingUid)
15807                    != PackageManager.PERMISSION_GRANTED) {
15808                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15809                        + callingPid + ", uid=" + callingUid
15810                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15811                Slog.w(TAG, msg);
15812                throw new SecurityException(msg);
15813            }
15814            if (requiredPermission != null) {
15815                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15816                        + " and enforce permission " + requiredPermission);
15817                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15818            }
15819            if (intent.getComponent() != null) {
15820                throw new SecurityException(
15821                        "Sticky broadcasts can't target a specific component");
15822            }
15823            // We use userId directly here, since the "all" target is maintained
15824            // as a separate set of sticky broadcasts.
15825            if (userId != UserHandle.USER_ALL) {
15826                // But first, if this is not a broadcast to all users, then
15827                // make sure it doesn't conflict with an existing broadcast to
15828                // all users.
15829                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15830                        UserHandle.USER_ALL);
15831                if (stickies != null) {
15832                    ArrayList<Intent> list = stickies.get(intent.getAction());
15833                    if (list != null) {
15834                        int N = list.size();
15835                        int i;
15836                        for (i=0; i<N; i++) {
15837                            if (intent.filterEquals(list.get(i))) {
15838                                throw new IllegalArgumentException(
15839                                        "Sticky broadcast " + intent + " for user "
15840                                        + userId + " conflicts with existing global broadcast");
15841                            }
15842                        }
15843                    }
15844                }
15845            }
15846            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15847            if (stickies == null) {
15848                stickies = new ArrayMap<String, ArrayList<Intent>>();
15849                mStickyBroadcasts.put(userId, stickies);
15850            }
15851            ArrayList<Intent> list = stickies.get(intent.getAction());
15852            if (list == null) {
15853                list = new ArrayList<Intent>();
15854                stickies.put(intent.getAction(), list);
15855            }
15856            int N = list.size();
15857            int i;
15858            for (i=0; i<N; i++) {
15859                if (intent.filterEquals(list.get(i))) {
15860                    // This sticky already exists, replace it.
15861                    list.set(i, new Intent(intent));
15862                    break;
15863                }
15864            }
15865            if (i >= N) {
15866                list.add(new Intent(intent));
15867            }
15868        }
15869
15870        int[] users;
15871        if (userId == UserHandle.USER_ALL) {
15872            // Caller wants broadcast to go to all started users.
15873            users = mStartedUserArray;
15874        } else {
15875            // Caller wants broadcast to go to one specific user.
15876            users = new int[] {userId};
15877        }
15878
15879        // Figure out who all will receive this broadcast.
15880        List receivers = null;
15881        List<BroadcastFilter> registeredReceivers = null;
15882        // Need to resolve the intent to interested receivers...
15883        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15884                 == 0) {
15885            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15886        }
15887        if (intent.getComponent() == null) {
15888            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15889                // Query one target user at a time, excluding shell-restricted users
15890                UserManagerService ums = getUserManagerLocked();
15891                for (int i = 0; i < users.length; i++) {
15892                    if (ums.hasUserRestriction(
15893                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15894                        continue;
15895                    }
15896                    List<BroadcastFilter> registeredReceiversForUser =
15897                            mReceiverResolver.queryIntent(intent,
15898                                    resolvedType, false, users[i]);
15899                    if (registeredReceivers == null) {
15900                        registeredReceivers = registeredReceiversForUser;
15901                    } else if (registeredReceiversForUser != null) {
15902                        registeredReceivers.addAll(registeredReceiversForUser);
15903                    }
15904                }
15905            } else {
15906                registeredReceivers = mReceiverResolver.queryIntent(intent,
15907                        resolvedType, false, userId);
15908            }
15909        }
15910
15911        final boolean replacePending =
15912                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15913
15914        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15915                + " replacePending=" + replacePending);
15916
15917        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15918        if (!ordered && NR > 0) {
15919            // If we are not serializing this broadcast, then send the
15920            // registered receivers separately so they don't wait for the
15921            // components to be launched.
15922            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15923            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15924                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15925                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15926                    ordered, sticky, false, userId);
15927            if (DEBUG_BROADCAST) Slog.v(
15928                    TAG, "Enqueueing parallel broadcast " + r);
15929            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15930            if (!replaced) {
15931                queue.enqueueParallelBroadcastLocked(r);
15932                queue.scheduleBroadcastsLocked();
15933            }
15934            registeredReceivers = null;
15935            NR = 0;
15936        }
15937
15938        // Merge into one list.
15939        int ir = 0;
15940        if (receivers != null) {
15941            // A special case for PACKAGE_ADDED: do not allow the package
15942            // being added to see this broadcast.  This prevents them from
15943            // using this as a back door to get run as soon as they are
15944            // installed.  Maybe in the future we want to have a special install
15945            // broadcast or such for apps, but we'd like to deliberately make
15946            // this decision.
15947            String skipPackages[] = null;
15948            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15949                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15950                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15951                Uri data = intent.getData();
15952                if (data != null) {
15953                    String pkgName = data.getSchemeSpecificPart();
15954                    if (pkgName != null) {
15955                        skipPackages = new String[] { pkgName };
15956                    }
15957                }
15958            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15959                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15960            }
15961            if (skipPackages != null && (skipPackages.length > 0)) {
15962                for (String skipPackage : skipPackages) {
15963                    if (skipPackage != null) {
15964                        int NT = receivers.size();
15965                        for (int it=0; it<NT; it++) {
15966                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15967                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15968                                receivers.remove(it);
15969                                it--;
15970                                NT--;
15971                            }
15972                        }
15973                    }
15974                }
15975            }
15976
15977            int NT = receivers != null ? receivers.size() : 0;
15978            int it = 0;
15979            ResolveInfo curt = null;
15980            BroadcastFilter curr = null;
15981            while (it < NT && ir < NR) {
15982                if (curt == null) {
15983                    curt = (ResolveInfo)receivers.get(it);
15984                }
15985                if (curr == null) {
15986                    curr = registeredReceivers.get(ir);
15987                }
15988                if (curr.getPriority() >= curt.priority) {
15989                    // Insert this broadcast record into the final list.
15990                    receivers.add(it, curr);
15991                    ir++;
15992                    curr = null;
15993                    it++;
15994                    NT++;
15995                } else {
15996                    // Skip to the next ResolveInfo in the final list.
15997                    it++;
15998                    curt = null;
15999                }
16000            }
16001        }
16002        while (ir < NR) {
16003            if (receivers == null) {
16004                receivers = new ArrayList();
16005            }
16006            receivers.add(registeredReceivers.get(ir));
16007            ir++;
16008        }
16009
16010        if ((receivers != null && receivers.size() > 0)
16011                || resultTo != null) {
16012            BroadcastQueue queue = broadcastQueueForIntent(intent);
16013            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16014                    callerPackage, callingPid, callingUid, resolvedType,
16015                    requiredPermission, appOp, receivers, resultTo, resultCode,
16016                    resultData, map, ordered, sticky, false, userId);
16017            if (DEBUG_BROADCAST) Slog.v(
16018                    TAG, "Enqueueing ordered broadcast " + r
16019                    + ": prev had " + queue.mOrderedBroadcasts.size());
16020            if (DEBUG_BROADCAST) {
16021                int seq = r.intent.getIntExtra("seq", -1);
16022                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16023            }
16024            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16025            if (!replaced) {
16026                queue.enqueueOrderedBroadcastLocked(r);
16027                queue.scheduleBroadcastsLocked();
16028            }
16029        }
16030
16031        return ActivityManager.BROADCAST_SUCCESS;
16032    }
16033
16034    final Intent verifyBroadcastLocked(Intent intent) {
16035        // Refuse possible leaked file descriptors
16036        if (intent != null && intent.hasFileDescriptors() == true) {
16037            throw new IllegalArgumentException("File descriptors passed in Intent");
16038        }
16039
16040        int flags = intent.getFlags();
16041
16042        if (!mProcessesReady) {
16043            // if the caller really truly claims to know what they're doing, go
16044            // ahead and allow the broadcast without launching any receivers
16045            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16046                intent = new Intent(intent);
16047                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16048            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16049                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16050                        + " before boot completion");
16051                throw new IllegalStateException("Cannot broadcast before boot completed");
16052            }
16053        }
16054
16055        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16056            throw new IllegalArgumentException(
16057                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16058        }
16059
16060        return intent;
16061    }
16062
16063    public final int broadcastIntent(IApplicationThread caller,
16064            Intent intent, String resolvedType, IIntentReceiver resultTo,
16065            int resultCode, String resultData, Bundle map,
16066            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16067        enforceNotIsolatedCaller("broadcastIntent");
16068        synchronized(this) {
16069            intent = verifyBroadcastLocked(intent);
16070
16071            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16072            final int callingPid = Binder.getCallingPid();
16073            final int callingUid = Binder.getCallingUid();
16074            final long origId = Binder.clearCallingIdentity();
16075            int res = broadcastIntentLocked(callerApp,
16076                    callerApp != null ? callerApp.info.packageName : null,
16077                    intent, resolvedType, resultTo,
16078                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16079                    callingPid, callingUid, userId);
16080            Binder.restoreCallingIdentity(origId);
16081            return res;
16082        }
16083    }
16084
16085    int broadcastIntentInPackage(String packageName, int uid,
16086            Intent intent, String resolvedType, IIntentReceiver resultTo,
16087            int resultCode, String resultData, Bundle map,
16088            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16089        synchronized(this) {
16090            intent = verifyBroadcastLocked(intent);
16091
16092            final long origId = Binder.clearCallingIdentity();
16093            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16094                    resultTo, resultCode, resultData, map, requiredPermission,
16095                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16096            Binder.restoreCallingIdentity(origId);
16097            return res;
16098        }
16099    }
16100
16101    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16102        // Refuse possible leaked file descriptors
16103        if (intent != null && intent.hasFileDescriptors() == true) {
16104            throw new IllegalArgumentException("File descriptors passed in Intent");
16105        }
16106
16107        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16108                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16109
16110        synchronized(this) {
16111            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16112                    != PackageManager.PERMISSION_GRANTED) {
16113                String msg = "Permission Denial: unbroadcastIntent() from pid="
16114                        + Binder.getCallingPid()
16115                        + ", uid=" + Binder.getCallingUid()
16116                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16117                Slog.w(TAG, msg);
16118                throw new SecurityException(msg);
16119            }
16120            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16121            if (stickies != null) {
16122                ArrayList<Intent> list = stickies.get(intent.getAction());
16123                if (list != null) {
16124                    int N = list.size();
16125                    int i;
16126                    for (i=0; i<N; i++) {
16127                        if (intent.filterEquals(list.get(i))) {
16128                            list.remove(i);
16129                            break;
16130                        }
16131                    }
16132                    if (list.size() <= 0) {
16133                        stickies.remove(intent.getAction());
16134                    }
16135                }
16136                if (stickies.size() <= 0) {
16137                    mStickyBroadcasts.remove(userId);
16138                }
16139            }
16140        }
16141    }
16142
16143    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16144            String resultData, Bundle resultExtras, boolean resultAbort) {
16145        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16146        if (r == null) {
16147            Slog.w(TAG, "finishReceiver called but not found on queue");
16148            return false;
16149        }
16150
16151        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16152    }
16153
16154    void backgroundServicesFinishedLocked(int userId) {
16155        for (BroadcastQueue queue : mBroadcastQueues) {
16156            queue.backgroundServicesFinishedLocked(userId);
16157        }
16158    }
16159
16160    public void finishReceiver(IBinder who, int resultCode, String resultData,
16161            Bundle resultExtras, boolean resultAbort) {
16162        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16163
16164        // Refuse possible leaked file descriptors
16165        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16166            throw new IllegalArgumentException("File descriptors passed in Bundle");
16167        }
16168
16169        final long origId = Binder.clearCallingIdentity();
16170        try {
16171            boolean doNext = false;
16172            BroadcastRecord r;
16173
16174            synchronized(this) {
16175                r = broadcastRecordForReceiverLocked(who);
16176                if (r != null) {
16177                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16178                        resultData, resultExtras, resultAbort, true);
16179                }
16180            }
16181
16182            if (doNext) {
16183                r.queue.processNextBroadcast(false);
16184            }
16185            trimApplications();
16186        } finally {
16187            Binder.restoreCallingIdentity(origId);
16188        }
16189    }
16190
16191    // =========================================================
16192    // INSTRUMENTATION
16193    // =========================================================
16194
16195    public boolean startInstrumentation(ComponentName className,
16196            String profileFile, int flags, Bundle arguments,
16197            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16198            int userId, String abiOverride) {
16199        enforceNotIsolatedCaller("startInstrumentation");
16200        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16201                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16202        // Refuse possible leaked file descriptors
16203        if (arguments != null && arguments.hasFileDescriptors()) {
16204            throw new IllegalArgumentException("File descriptors passed in Bundle");
16205        }
16206
16207        synchronized(this) {
16208            InstrumentationInfo ii = null;
16209            ApplicationInfo ai = null;
16210            try {
16211                ii = mContext.getPackageManager().getInstrumentationInfo(
16212                    className, STOCK_PM_FLAGS);
16213                ai = AppGlobals.getPackageManager().getApplicationInfo(
16214                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16215            } catch (PackageManager.NameNotFoundException e) {
16216            } catch (RemoteException e) {
16217            }
16218            if (ii == null) {
16219                reportStartInstrumentationFailure(watcher, className,
16220                        "Unable to find instrumentation info for: " + className);
16221                return false;
16222            }
16223            if (ai == null) {
16224                reportStartInstrumentationFailure(watcher, className,
16225                        "Unable to find instrumentation target package: " + ii.targetPackage);
16226                return false;
16227            }
16228
16229            int match = mContext.getPackageManager().checkSignatures(
16230                    ii.targetPackage, ii.packageName);
16231            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16232                String msg = "Permission Denial: starting instrumentation "
16233                        + className + " from pid="
16234                        + Binder.getCallingPid()
16235                        + ", uid=" + Binder.getCallingPid()
16236                        + " not allowed because package " + ii.packageName
16237                        + " does not have a signature matching the target "
16238                        + ii.targetPackage;
16239                reportStartInstrumentationFailure(watcher, className, msg);
16240                throw new SecurityException(msg);
16241            }
16242
16243            final long origId = Binder.clearCallingIdentity();
16244            // Instrumentation can kill and relaunch even persistent processes
16245            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16246                    "start instr");
16247            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16248            app.instrumentationClass = className;
16249            app.instrumentationInfo = ai;
16250            app.instrumentationProfileFile = profileFile;
16251            app.instrumentationArguments = arguments;
16252            app.instrumentationWatcher = watcher;
16253            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16254            app.instrumentationResultClass = className;
16255            Binder.restoreCallingIdentity(origId);
16256        }
16257
16258        return true;
16259    }
16260
16261    /**
16262     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16263     * error to the logs, but if somebody is watching, send the report there too.  This enables
16264     * the "am" command to report errors with more information.
16265     *
16266     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16267     * @param cn The component name of the instrumentation.
16268     * @param report The error report.
16269     */
16270    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16271            ComponentName cn, String report) {
16272        Slog.w(TAG, report);
16273        try {
16274            if (watcher != null) {
16275                Bundle results = new Bundle();
16276                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16277                results.putString("Error", report);
16278                watcher.instrumentationStatus(cn, -1, results);
16279            }
16280        } catch (RemoteException e) {
16281            Slog.w(TAG, e);
16282        }
16283    }
16284
16285    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16286        if (app.instrumentationWatcher != null) {
16287            try {
16288                // NOTE:  IInstrumentationWatcher *must* be oneway here
16289                app.instrumentationWatcher.instrumentationFinished(
16290                    app.instrumentationClass,
16291                    resultCode,
16292                    results);
16293            } catch (RemoteException e) {
16294            }
16295        }
16296        if (app.instrumentationUiAutomationConnection != null) {
16297            try {
16298                app.instrumentationUiAutomationConnection.shutdown();
16299            } catch (RemoteException re) {
16300                /* ignore */
16301            }
16302            // Only a UiAutomation can set this flag and now that
16303            // it is finished we make sure it is reset to its default.
16304            mUserIsMonkey = false;
16305        }
16306        app.instrumentationWatcher = null;
16307        app.instrumentationUiAutomationConnection = null;
16308        app.instrumentationClass = null;
16309        app.instrumentationInfo = null;
16310        app.instrumentationProfileFile = null;
16311        app.instrumentationArguments = null;
16312
16313        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16314                "finished inst");
16315    }
16316
16317    public void finishInstrumentation(IApplicationThread target,
16318            int resultCode, Bundle results) {
16319        int userId = UserHandle.getCallingUserId();
16320        // Refuse possible leaked file descriptors
16321        if (results != null && results.hasFileDescriptors()) {
16322            throw new IllegalArgumentException("File descriptors passed in Intent");
16323        }
16324
16325        synchronized(this) {
16326            ProcessRecord app = getRecordForAppLocked(target);
16327            if (app == null) {
16328                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16329                return;
16330            }
16331            final long origId = Binder.clearCallingIdentity();
16332            finishInstrumentationLocked(app, resultCode, results);
16333            Binder.restoreCallingIdentity(origId);
16334        }
16335    }
16336
16337    // =========================================================
16338    // CONFIGURATION
16339    // =========================================================
16340
16341    public ConfigurationInfo getDeviceConfigurationInfo() {
16342        ConfigurationInfo config = new ConfigurationInfo();
16343        synchronized (this) {
16344            config.reqTouchScreen = mConfiguration.touchscreen;
16345            config.reqKeyboardType = mConfiguration.keyboard;
16346            config.reqNavigation = mConfiguration.navigation;
16347            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16348                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16349                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16350            }
16351            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16352                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16353                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16354            }
16355            config.reqGlEsVersion = GL_ES_VERSION;
16356        }
16357        return config;
16358    }
16359
16360    ActivityStack getFocusedStack() {
16361        return mStackSupervisor.getFocusedStack();
16362    }
16363
16364    public Configuration getConfiguration() {
16365        Configuration ci;
16366        synchronized(this) {
16367            ci = new Configuration(mConfiguration);
16368        }
16369        return ci;
16370    }
16371
16372    public void updatePersistentConfiguration(Configuration values) {
16373        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16374                "updateConfiguration()");
16375        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16376                "updateConfiguration()");
16377        if (values == null) {
16378            throw new NullPointerException("Configuration must not be null");
16379        }
16380
16381        synchronized(this) {
16382            final long origId = Binder.clearCallingIdentity();
16383            updateConfigurationLocked(values, null, true, false);
16384            Binder.restoreCallingIdentity(origId);
16385        }
16386    }
16387
16388    public void updateConfiguration(Configuration values) {
16389        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16390                "updateConfiguration()");
16391
16392        synchronized(this) {
16393            if (values == null && mWindowManager != null) {
16394                // sentinel: fetch the current configuration from the window manager
16395                values = mWindowManager.computeNewConfiguration();
16396            }
16397
16398            if (mWindowManager != null) {
16399                mProcessList.applyDisplaySize(mWindowManager);
16400            }
16401
16402            final long origId = Binder.clearCallingIdentity();
16403            if (values != null) {
16404                Settings.System.clearConfiguration(values);
16405            }
16406            updateConfigurationLocked(values, null, false, false);
16407            Binder.restoreCallingIdentity(origId);
16408        }
16409    }
16410
16411    /**
16412     * Do either or both things: (1) change the current configuration, and (2)
16413     * make sure the given activity is running with the (now) current
16414     * configuration.  Returns true if the activity has been left running, or
16415     * false if <var>starting</var> is being destroyed to match the new
16416     * configuration.
16417     * @param persistent TODO
16418     */
16419    boolean updateConfigurationLocked(Configuration values,
16420            ActivityRecord starting, boolean persistent, boolean initLocale) {
16421        int changes = 0;
16422
16423        if (values != null) {
16424            Configuration newConfig = new Configuration(mConfiguration);
16425            changes = newConfig.updateFrom(values);
16426            if (changes != 0) {
16427                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16428                    Slog.i(TAG, "Updating configuration to: " + values);
16429                }
16430
16431                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16432
16433                if (values.locale != null && !initLocale) {
16434                    saveLocaleLocked(values.locale,
16435                                     !values.locale.equals(mConfiguration.locale),
16436                                     values.userSetLocale);
16437                }
16438
16439                mConfigurationSeq++;
16440                if (mConfigurationSeq <= 0) {
16441                    mConfigurationSeq = 1;
16442                }
16443                newConfig.seq = mConfigurationSeq;
16444                mConfiguration = newConfig;
16445                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16446                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16447                //mUsageStatsService.noteStartConfig(newConfig);
16448
16449                final Configuration configCopy = new Configuration(mConfiguration);
16450
16451                // TODO: If our config changes, should we auto dismiss any currently
16452                // showing dialogs?
16453                mShowDialogs = shouldShowDialogs(newConfig);
16454
16455                AttributeCache ac = AttributeCache.instance();
16456                if (ac != null) {
16457                    ac.updateConfiguration(configCopy);
16458                }
16459
16460                // Make sure all resources in our process are updated
16461                // right now, so that anyone who is going to retrieve
16462                // resource values after we return will be sure to get
16463                // the new ones.  This is especially important during
16464                // boot, where the first config change needs to guarantee
16465                // all resources have that config before following boot
16466                // code is executed.
16467                mSystemThread.applyConfigurationToResources(configCopy);
16468
16469                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16470                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16471                    msg.obj = new Configuration(configCopy);
16472                    mHandler.sendMessage(msg);
16473                }
16474
16475                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16476                    ProcessRecord app = mLruProcesses.get(i);
16477                    try {
16478                        if (app.thread != null) {
16479                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16480                                    + app.processName + " new config " + mConfiguration);
16481                            app.thread.scheduleConfigurationChanged(configCopy);
16482                        }
16483                    } catch (Exception e) {
16484                    }
16485                }
16486                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16487                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16488                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16489                        | Intent.FLAG_RECEIVER_FOREGROUND);
16490                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16491                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16492                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16493                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16494                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16495                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16496                    broadcastIntentLocked(null, null, intent,
16497                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16498                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16499                }
16500            }
16501        }
16502
16503        boolean kept = true;
16504        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16505        // mainStack is null during startup.
16506        if (mainStack != null) {
16507            if (changes != 0 && starting == null) {
16508                // If the configuration changed, and the caller is not already
16509                // in the process of starting an activity, then find the top
16510                // activity to check if its configuration needs to change.
16511                starting = mainStack.topRunningActivityLocked(null);
16512            }
16513
16514            if (starting != null) {
16515                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16516                // And we need to make sure at this point that all other activities
16517                // are made visible with the correct configuration.
16518                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16519            }
16520        }
16521
16522        if (values != null && mWindowManager != null) {
16523            mWindowManager.setNewConfiguration(mConfiguration);
16524        }
16525
16526        return kept;
16527    }
16528
16529    /**
16530     * Decide based on the configuration whether we should shouw the ANR,
16531     * crash, etc dialogs.  The idea is that if there is no affordnace to
16532     * press the on-screen buttons, we shouldn't show the dialog.
16533     *
16534     * A thought: SystemUI might also want to get told about this, the Power
16535     * dialog / global actions also might want different behaviors.
16536     */
16537    private static final boolean shouldShowDialogs(Configuration config) {
16538        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16539                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16540    }
16541
16542    /**
16543     * Save the locale.  You must be inside a synchronized (this) block.
16544     */
16545    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16546        if(isDiff) {
16547            SystemProperties.set("user.language", l.getLanguage());
16548            SystemProperties.set("user.region", l.getCountry());
16549        }
16550
16551        if(isPersist) {
16552            SystemProperties.set("persist.sys.language", l.getLanguage());
16553            SystemProperties.set("persist.sys.country", l.getCountry());
16554            SystemProperties.set("persist.sys.localevar", l.getVariant());
16555
16556            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16557        }
16558    }
16559
16560    @Override
16561    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16562        synchronized (this) {
16563            ActivityRecord srec = ActivityRecord.forToken(token);
16564            if (srec.task != null && srec.task.stack != null) {
16565                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16566            }
16567        }
16568        return false;
16569    }
16570
16571    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16572            Intent resultData) {
16573
16574        synchronized (this) {
16575            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16576            if (stack != null) {
16577                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16578            }
16579            return false;
16580        }
16581    }
16582
16583    public int getLaunchedFromUid(IBinder activityToken) {
16584        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16585        if (srec == null) {
16586            return -1;
16587        }
16588        return srec.launchedFromUid;
16589    }
16590
16591    public String getLaunchedFromPackage(IBinder activityToken) {
16592        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16593        if (srec == null) {
16594            return null;
16595        }
16596        return srec.launchedFromPackage;
16597    }
16598
16599    // =========================================================
16600    // LIFETIME MANAGEMENT
16601    // =========================================================
16602
16603    // Returns which broadcast queue the app is the current [or imminent] receiver
16604    // on, or 'null' if the app is not an active broadcast recipient.
16605    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16606        BroadcastRecord r = app.curReceiver;
16607        if (r != null) {
16608            return r.queue;
16609        }
16610
16611        // It's not the current receiver, but it might be starting up to become one
16612        synchronized (this) {
16613            for (BroadcastQueue queue : mBroadcastQueues) {
16614                r = queue.mPendingBroadcast;
16615                if (r != null && r.curApp == app) {
16616                    // found it; report which queue it's in
16617                    return queue;
16618                }
16619            }
16620        }
16621
16622        return null;
16623    }
16624
16625    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16626            boolean doingAll, long now) {
16627        if (mAdjSeq == app.adjSeq) {
16628            // This adjustment has already been computed.
16629            return app.curRawAdj;
16630        }
16631
16632        if (app.thread == null) {
16633            app.adjSeq = mAdjSeq;
16634            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16635            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16636            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16637        }
16638
16639        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16640        app.adjSource = null;
16641        app.adjTarget = null;
16642        app.empty = false;
16643        app.cached = false;
16644
16645        final int activitiesSize = app.activities.size();
16646
16647        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16648            // The max adjustment doesn't allow this app to be anything
16649            // below foreground, so it is not worth doing work for it.
16650            app.adjType = "fixed";
16651            app.adjSeq = mAdjSeq;
16652            app.curRawAdj = app.maxAdj;
16653            app.foregroundActivities = false;
16654            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16655            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16656            // System processes can do UI, and when they do we want to have
16657            // them trim their memory after the user leaves the UI.  To
16658            // facilitate this, here we need to determine whether or not it
16659            // is currently showing UI.
16660            app.systemNoUi = true;
16661            if (app == TOP_APP) {
16662                app.systemNoUi = false;
16663            } else if (activitiesSize > 0) {
16664                for (int j = 0; j < activitiesSize; j++) {
16665                    final ActivityRecord r = app.activities.get(j);
16666                    if (r.visible) {
16667                        app.systemNoUi = false;
16668                    }
16669                }
16670            }
16671            if (!app.systemNoUi) {
16672                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16673            }
16674            return (app.curAdj=app.maxAdj);
16675        }
16676
16677        app.systemNoUi = false;
16678
16679        // Determine the importance of the process, starting with most
16680        // important to least, and assign an appropriate OOM adjustment.
16681        int adj;
16682        int schedGroup;
16683        int procState;
16684        boolean foregroundActivities = false;
16685        BroadcastQueue queue;
16686        if (app == TOP_APP) {
16687            // The last app on the list is the foreground app.
16688            adj = ProcessList.FOREGROUND_APP_ADJ;
16689            schedGroup = Process.THREAD_GROUP_DEFAULT;
16690            app.adjType = "top-activity";
16691            foregroundActivities = true;
16692            procState = ActivityManager.PROCESS_STATE_TOP;
16693        } else if (app.instrumentationClass != null) {
16694            // Don't want to kill running instrumentation.
16695            adj = ProcessList.FOREGROUND_APP_ADJ;
16696            schedGroup = Process.THREAD_GROUP_DEFAULT;
16697            app.adjType = "instrumentation";
16698            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16699        } else if ((queue = isReceivingBroadcast(app)) != null) {
16700            // An app that is currently receiving a broadcast also
16701            // counts as being in the foreground for OOM killer purposes.
16702            // It's placed in a sched group based on the nature of the
16703            // broadcast as reflected by which queue it's active in.
16704            adj = ProcessList.FOREGROUND_APP_ADJ;
16705            schedGroup = (queue == mFgBroadcastQueue)
16706                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16707            app.adjType = "broadcast";
16708            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16709        } else if (app.executingServices.size() > 0) {
16710            // An app that is currently executing a service callback also
16711            // counts as being in the foreground.
16712            adj = ProcessList.FOREGROUND_APP_ADJ;
16713            schedGroup = app.execServicesFg ?
16714                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16715            app.adjType = "exec-service";
16716            procState = ActivityManager.PROCESS_STATE_SERVICE;
16717            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16718        } else {
16719            // As far as we know the process is empty.  We may change our mind later.
16720            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16721            // At this point we don't actually know the adjustment.  Use the cached adj
16722            // value that the caller wants us to.
16723            adj = cachedAdj;
16724            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16725            app.cached = true;
16726            app.empty = true;
16727            app.adjType = "cch-empty";
16728        }
16729
16730        // Examine all activities if not already foreground.
16731        if (!foregroundActivities && activitiesSize > 0) {
16732            for (int j = 0; j < activitiesSize; j++) {
16733                final ActivityRecord r = app.activities.get(j);
16734                if (r.app != app) {
16735                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16736                            + app + "?!?");
16737                    continue;
16738                }
16739                if (r.visible) {
16740                    // App has a visible activity; only upgrade adjustment.
16741                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16742                        adj = ProcessList.VISIBLE_APP_ADJ;
16743                        app.adjType = "visible";
16744                    }
16745                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16746                        procState = ActivityManager.PROCESS_STATE_TOP;
16747                    }
16748                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16749                    app.cached = false;
16750                    app.empty = false;
16751                    foregroundActivities = true;
16752                    break;
16753                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16754                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16755                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16756                        app.adjType = "pausing";
16757                    }
16758                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16759                        procState = ActivityManager.PROCESS_STATE_TOP;
16760                    }
16761                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16762                    app.cached = false;
16763                    app.empty = false;
16764                    foregroundActivities = true;
16765                } else if (r.state == ActivityState.STOPPING) {
16766                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16767                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16768                        app.adjType = "stopping";
16769                    }
16770                    // For the process state, we will at this point consider the
16771                    // process to be cached.  It will be cached either as an activity
16772                    // or empty depending on whether the activity is finishing.  We do
16773                    // this so that we can treat the process as cached for purposes of
16774                    // memory trimming (determing current memory level, trim command to
16775                    // send to process) since there can be an arbitrary number of stopping
16776                    // processes and they should soon all go into the cached state.
16777                    if (!r.finishing) {
16778                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16779                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16780                        }
16781                    }
16782                    app.cached = false;
16783                    app.empty = false;
16784                    foregroundActivities = true;
16785                } else {
16786                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16787                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16788                        app.adjType = "cch-act";
16789                    }
16790                }
16791            }
16792        }
16793
16794        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16795            if (app.foregroundServices) {
16796                // The user is aware of this app, so make it visible.
16797                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16798                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16799                app.cached = false;
16800                app.adjType = "fg-service";
16801                schedGroup = Process.THREAD_GROUP_DEFAULT;
16802            } else if (app.forcingToForeground != null) {
16803                // The user is aware of this app, so make it visible.
16804                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16805                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16806                app.cached = false;
16807                app.adjType = "force-fg";
16808                app.adjSource = app.forcingToForeground;
16809                schedGroup = Process.THREAD_GROUP_DEFAULT;
16810            }
16811        }
16812
16813        if (app == mHeavyWeightProcess) {
16814            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16815                // We don't want to kill the current heavy-weight process.
16816                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16817                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16818                app.cached = false;
16819                app.adjType = "heavy";
16820            }
16821            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16822                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16823            }
16824        }
16825
16826        if (app == mHomeProcess) {
16827            if (adj > ProcessList.HOME_APP_ADJ) {
16828                // This process is hosting what we currently consider to be the
16829                // home app, so we don't want to let it go into the background.
16830                adj = ProcessList.HOME_APP_ADJ;
16831                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16832                app.cached = false;
16833                app.adjType = "home";
16834            }
16835            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16836                procState = ActivityManager.PROCESS_STATE_HOME;
16837            }
16838        }
16839
16840        if (app == mPreviousProcess && app.activities.size() > 0) {
16841            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16842                // This was the previous process that showed UI to the user.
16843                // We want to try to keep it around more aggressively, to give
16844                // a good experience around switching between two apps.
16845                adj = ProcessList.PREVIOUS_APP_ADJ;
16846                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16847                app.cached = false;
16848                app.adjType = "previous";
16849            }
16850            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16851                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16852            }
16853        }
16854
16855        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16856                + " reason=" + app.adjType);
16857
16858        // By default, we use the computed adjustment.  It may be changed if
16859        // there are applications dependent on our services or providers, but
16860        // this gives us a baseline and makes sure we don't get into an
16861        // infinite recursion.
16862        app.adjSeq = mAdjSeq;
16863        app.curRawAdj = adj;
16864        app.hasStartedServices = false;
16865
16866        if (mBackupTarget != null && app == mBackupTarget.app) {
16867            // If possible we want to avoid killing apps while they're being backed up
16868            if (adj > ProcessList.BACKUP_APP_ADJ) {
16869                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16870                adj = ProcessList.BACKUP_APP_ADJ;
16871                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16872                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16873                }
16874                app.adjType = "backup";
16875                app.cached = false;
16876            }
16877            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16878                procState = ActivityManager.PROCESS_STATE_BACKUP;
16879            }
16880        }
16881
16882        boolean mayBeTop = false;
16883
16884        for (int is = app.services.size()-1;
16885                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16886                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16887                        || procState > ActivityManager.PROCESS_STATE_TOP);
16888                is--) {
16889            ServiceRecord s = app.services.valueAt(is);
16890            if (s.startRequested) {
16891                app.hasStartedServices = true;
16892                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16893                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16894                }
16895                if (app.hasShownUi && app != mHomeProcess) {
16896                    // If this process has shown some UI, let it immediately
16897                    // go to the LRU list because it may be pretty heavy with
16898                    // UI stuff.  We'll tag it with a label just to help
16899                    // debug and understand what is going on.
16900                    if (adj > ProcessList.SERVICE_ADJ) {
16901                        app.adjType = "cch-started-ui-services";
16902                    }
16903                } else {
16904                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16905                        // This service has seen some activity within
16906                        // recent memory, so we will keep its process ahead
16907                        // of the background processes.
16908                        if (adj > ProcessList.SERVICE_ADJ) {
16909                            adj = ProcessList.SERVICE_ADJ;
16910                            app.adjType = "started-services";
16911                            app.cached = false;
16912                        }
16913                    }
16914                    // If we have let the service slide into the background
16915                    // state, still have some text describing what it is doing
16916                    // even though the service no longer has an impact.
16917                    if (adj > ProcessList.SERVICE_ADJ) {
16918                        app.adjType = "cch-started-services";
16919                    }
16920                }
16921            }
16922            for (int conni = s.connections.size()-1;
16923                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16924                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16925                            || procState > ActivityManager.PROCESS_STATE_TOP);
16926                    conni--) {
16927                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16928                for (int i = 0;
16929                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16930                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16931                                || procState > ActivityManager.PROCESS_STATE_TOP);
16932                        i++) {
16933                    // XXX should compute this based on the max of
16934                    // all connected clients.
16935                    ConnectionRecord cr = clist.get(i);
16936                    if (cr.binding.client == app) {
16937                        // Binding to ourself is not interesting.
16938                        continue;
16939                    }
16940                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16941                        ProcessRecord client = cr.binding.client;
16942                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16943                                TOP_APP, doingAll, now);
16944                        int clientProcState = client.curProcState;
16945                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16946                            // If the other app is cached for any reason, for purposes here
16947                            // we are going to consider it empty.  The specific cached state
16948                            // doesn't propagate except under certain conditions.
16949                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16950                        }
16951                        String adjType = null;
16952                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16953                            // Not doing bind OOM management, so treat
16954                            // this guy more like a started service.
16955                            if (app.hasShownUi && app != mHomeProcess) {
16956                                // If this process has shown some UI, let it immediately
16957                                // go to the LRU list because it may be pretty heavy with
16958                                // UI stuff.  We'll tag it with a label just to help
16959                                // debug and understand what is going on.
16960                                if (adj > clientAdj) {
16961                                    adjType = "cch-bound-ui-services";
16962                                }
16963                                app.cached = false;
16964                                clientAdj = adj;
16965                                clientProcState = procState;
16966                            } else {
16967                                if (now >= (s.lastActivity
16968                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16969                                    // This service has not seen activity within
16970                                    // recent memory, so allow it to drop to the
16971                                    // LRU list if there is no other reason to keep
16972                                    // it around.  We'll also tag it with a label just
16973                                    // to help debug and undertand what is going on.
16974                                    if (adj > clientAdj) {
16975                                        adjType = "cch-bound-services";
16976                                    }
16977                                    clientAdj = adj;
16978                                }
16979                            }
16980                        }
16981                        if (adj > clientAdj) {
16982                            // If this process has recently shown UI, and
16983                            // the process that is binding to it is less
16984                            // important than being visible, then we don't
16985                            // care about the binding as much as we care
16986                            // about letting this process get into the LRU
16987                            // list to be killed and restarted if needed for
16988                            // memory.
16989                            if (app.hasShownUi && app != mHomeProcess
16990                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16991                                adjType = "cch-bound-ui-services";
16992                            } else {
16993                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16994                                        |Context.BIND_IMPORTANT)) != 0) {
16995                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16996                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16997                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16998                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16999                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17000                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17001                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17002                                    adj = clientAdj;
17003                                } else {
17004                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
17005                                        adj = ProcessList.VISIBLE_APP_ADJ;
17006                                    }
17007                                }
17008                                if (!client.cached) {
17009                                    app.cached = false;
17010                                }
17011                                adjType = "service";
17012                            }
17013                        }
17014                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17015                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17016                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17017                            }
17018                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17019                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17020                                    // Special handling of clients who are in the top state.
17021                                    // We *may* want to consider this process to be in the
17022                                    // top state as well, but only if there is not another
17023                                    // reason for it to be running.  Being on the top is a
17024                                    // special state, meaning you are specifically running
17025                                    // for the current top app.  If the process is already
17026                                    // running in the background for some other reason, it
17027                                    // is more important to continue considering it to be
17028                                    // in the background state.
17029                                    mayBeTop = true;
17030                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17031                                } else {
17032                                    // Special handling for above-top states (persistent
17033                                    // processes).  These should not bring the current process
17034                                    // into the top state, since they are not on top.  Instead
17035                                    // give them the best state after that.
17036                                    clientProcState =
17037                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17038                                }
17039                            }
17040                        } else {
17041                            if (clientProcState <
17042                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17043                                clientProcState =
17044                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17045                            }
17046                        }
17047                        if (procState > clientProcState) {
17048                            procState = clientProcState;
17049                        }
17050                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17051                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17052                            app.pendingUiClean = true;
17053                        }
17054                        if (adjType != null) {
17055                            app.adjType = adjType;
17056                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17057                                    .REASON_SERVICE_IN_USE;
17058                            app.adjSource = cr.binding.client;
17059                            app.adjSourceProcState = clientProcState;
17060                            app.adjTarget = s.name;
17061                        }
17062                    }
17063                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17064                        app.treatLikeActivity = true;
17065                    }
17066                    final ActivityRecord a = cr.activity;
17067                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17068                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17069                                (a.visible || a.state == ActivityState.RESUMED
17070                                 || a.state == ActivityState.PAUSING)) {
17071                            adj = ProcessList.FOREGROUND_APP_ADJ;
17072                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17073                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17074                            }
17075                            app.cached = false;
17076                            app.adjType = "service";
17077                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17078                                    .REASON_SERVICE_IN_USE;
17079                            app.adjSource = a;
17080                            app.adjSourceProcState = procState;
17081                            app.adjTarget = s.name;
17082                        }
17083                    }
17084                }
17085            }
17086        }
17087
17088        for (int provi = app.pubProviders.size()-1;
17089                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17090                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17091                        || procState > ActivityManager.PROCESS_STATE_TOP);
17092                provi--) {
17093            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17094            for (int i = cpr.connections.size()-1;
17095                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17096                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17097                            || procState > ActivityManager.PROCESS_STATE_TOP);
17098                    i--) {
17099                ContentProviderConnection conn = cpr.connections.get(i);
17100                ProcessRecord client = conn.client;
17101                if (client == app) {
17102                    // Being our own client is not interesting.
17103                    continue;
17104                }
17105                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17106                int clientProcState = client.curProcState;
17107                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17108                    // If the other app is cached for any reason, for purposes here
17109                    // we are going to consider it empty.
17110                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17111                }
17112                if (adj > clientAdj) {
17113                    if (app.hasShownUi && app != mHomeProcess
17114                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17115                        app.adjType = "cch-ui-provider";
17116                    } else {
17117                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17118                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17119                        app.adjType = "provider";
17120                    }
17121                    app.cached &= client.cached;
17122                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17123                            .REASON_PROVIDER_IN_USE;
17124                    app.adjSource = client;
17125                    app.adjSourceProcState = clientProcState;
17126                    app.adjTarget = cpr.name;
17127                }
17128                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17129                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17130                        // Special handling of clients who are in the top state.
17131                        // We *may* want to consider this process to be in the
17132                        // top state as well, but only if there is not another
17133                        // reason for it to be running.  Being on the top is a
17134                        // special state, meaning you are specifically running
17135                        // for the current top app.  If the process is already
17136                        // running in the background for some other reason, it
17137                        // is more important to continue considering it to be
17138                        // in the background state.
17139                        mayBeTop = true;
17140                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17141                    } else {
17142                        // Special handling for above-top states (persistent
17143                        // processes).  These should not bring the current process
17144                        // into the top state, since they are not on top.  Instead
17145                        // give them the best state after that.
17146                        clientProcState =
17147                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17148                    }
17149                }
17150                if (procState > clientProcState) {
17151                    procState = clientProcState;
17152                }
17153                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17154                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17155                }
17156            }
17157            // If the provider has external (non-framework) process
17158            // dependencies, ensure that its adjustment is at least
17159            // FOREGROUND_APP_ADJ.
17160            if (cpr.hasExternalProcessHandles()) {
17161                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17162                    adj = ProcessList.FOREGROUND_APP_ADJ;
17163                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17164                    app.cached = false;
17165                    app.adjType = "provider";
17166                    app.adjTarget = cpr.name;
17167                }
17168                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17169                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17170                }
17171            }
17172        }
17173
17174        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17175            // A client of one of our services or providers is in the top state.  We
17176            // *may* want to be in the top state, but not if we are already running in
17177            // the background for some other reason.  For the decision here, we are going
17178            // to pick out a few specific states that we want to remain in when a client
17179            // is top (states that tend to be longer-term) and otherwise allow it to go
17180            // to the top state.
17181            switch (procState) {
17182                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17183                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17184                case ActivityManager.PROCESS_STATE_SERVICE:
17185                    // These all are longer-term states, so pull them up to the top
17186                    // of the background states, but not all the way to the top state.
17187                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17188                    break;
17189                default:
17190                    // Otherwise, top is a better choice, so take it.
17191                    procState = ActivityManager.PROCESS_STATE_TOP;
17192                    break;
17193            }
17194        }
17195
17196        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17197            if (app.hasClientActivities) {
17198                // This is a cached process, but with client activities.  Mark it so.
17199                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17200                app.adjType = "cch-client-act";
17201            } else if (app.treatLikeActivity) {
17202                // This is a cached process, but somebody wants us to treat it like it has
17203                // an activity, okay!
17204                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17205                app.adjType = "cch-as-act";
17206            }
17207        }
17208
17209        if (adj == ProcessList.SERVICE_ADJ) {
17210            if (doingAll) {
17211                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17212                mNewNumServiceProcs++;
17213                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17214                if (!app.serviceb) {
17215                    // This service isn't far enough down on the LRU list to
17216                    // normally be a B service, but if we are low on RAM and it
17217                    // is large we want to force it down since we would prefer to
17218                    // keep launcher over it.
17219                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17220                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17221                        app.serviceHighRam = true;
17222                        app.serviceb = true;
17223                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17224                    } else {
17225                        mNewNumAServiceProcs++;
17226                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17227                    }
17228                } else {
17229                    app.serviceHighRam = false;
17230                }
17231            }
17232            if (app.serviceb) {
17233                adj = ProcessList.SERVICE_B_ADJ;
17234            }
17235        }
17236
17237        app.curRawAdj = adj;
17238
17239        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17240        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17241        if (adj > app.maxAdj) {
17242            adj = app.maxAdj;
17243            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17244                schedGroup = Process.THREAD_GROUP_DEFAULT;
17245            }
17246        }
17247
17248        // Do final modification to adj.  Everything we do between here and applying
17249        // the final setAdj must be done in this function, because we will also use
17250        // it when computing the final cached adj later.  Note that we don't need to
17251        // worry about this for max adj above, since max adj will always be used to
17252        // keep it out of the cached vaues.
17253        app.curAdj = app.modifyRawOomAdj(adj);
17254        app.curSchedGroup = schedGroup;
17255        app.curProcState = procState;
17256        app.foregroundActivities = foregroundActivities;
17257
17258        return app.curRawAdj;
17259    }
17260
17261    /**
17262     * Schedule PSS collection of a process.
17263     */
17264    void requestPssLocked(ProcessRecord proc, int procState) {
17265        if (mPendingPssProcesses.contains(proc)) {
17266            return;
17267        }
17268        if (mPendingPssProcesses.size() == 0) {
17269            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17270        }
17271        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17272        proc.pssProcState = procState;
17273        mPendingPssProcesses.add(proc);
17274    }
17275
17276    /**
17277     * Schedule PSS collection of all processes.
17278     */
17279    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17280        if (!always) {
17281            if (now < (mLastFullPssTime +
17282                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17283                return;
17284            }
17285        }
17286        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17287        mLastFullPssTime = now;
17288        mFullPssPending = true;
17289        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17290        mPendingPssProcesses.clear();
17291        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17292            ProcessRecord app = mLruProcesses.get(i);
17293            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17294                app.pssProcState = app.setProcState;
17295                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17296                        isSleeping(), now);
17297                mPendingPssProcesses.add(app);
17298            }
17299        }
17300        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17301    }
17302
17303    /**
17304     * Ask a given process to GC right now.
17305     */
17306    final void performAppGcLocked(ProcessRecord app) {
17307        try {
17308            app.lastRequestedGc = SystemClock.uptimeMillis();
17309            if (app.thread != null) {
17310                if (app.reportLowMemory) {
17311                    app.reportLowMemory = false;
17312                    app.thread.scheduleLowMemory();
17313                } else {
17314                    app.thread.processInBackground();
17315                }
17316            }
17317        } catch (Exception e) {
17318            // whatever.
17319        }
17320    }
17321
17322    /**
17323     * Returns true if things are idle enough to perform GCs.
17324     */
17325    private final boolean canGcNowLocked() {
17326        boolean processingBroadcasts = false;
17327        for (BroadcastQueue q : mBroadcastQueues) {
17328            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17329                processingBroadcasts = true;
17330            }
17331        }
17332        return !processingBroadcasts
17333                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17334    }
17335
17336    /**
17337     * Perform GCs on all processes that are waiting for it, but only
17338     * if things are idle.
17339     */
17340    final void performAppGcsLocked() {
17341        final int N = mProcessesToGc.size();
17342        if (N <= 0) {
17343            return;
17344        }
17345        if (canGcNowLocked()) {
17346            while (mProcessesToGc.size() > 0) {
17347                ProcessRecord proc = mProcessesToGc.remove(0);
17348                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17349                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17350                            <= SystemClock.uptimeMillis()) {
17351                        // To avoid spamming the system, we will GC processes one
17352                        // at a time, waiting a few seconds between each.
17353                        performAppGcLocked(proc);
17354                        scheduleAppGcsLocked();
17355                        return;
17356                    } else {
17357                        // It hasn't been long enough since we last GCed this
17358                        // process...  put it in the list to wait for its time.
17359                        addProcessToGcListLocked(proc);
17360                        break;
17361                    }
17362                }
17363            }
17364
17365            scheduleAppGcsLocked();
17366        }
17367    }
17368
17369    /**
17370     * If all looks good, perform GCs on all processes waiting for them.
17371     */
17372    final void performAppGcsIfAppropriateLocked() {
17373        if (canGcNowLocked()) {
17374            performAppGcsLocked();
17375            return;
17376        }
17377        // Still not idle, wait some more.
17378        scheduleAppGcsLocked();
17379    }
17380
17381    /**
17382     * Schedule the execution of all pending app GCs.
17383     */
17384    final void scheduleAppGcsLocked() {
17385        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17386
17387        if (mProcessesToGc.size() > 0) {
17388            // Schedule a GC for the time to the next process.
17389            ProcessRecord proc = mProcessesToGc.get(0);
17390            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17391
17392            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17393            long now = SystemClock.uptimeMillis();
17394            if (when < (now+GC_TIMEOUT)) {
17395                when = now + GC_TIMEOUT;
17396            }
17397            mHandler.sendMessageAtTime(msg, when);
17398        }
17399    }
17400
17401    /**
17402     * Add a process to the array of processes waiting to be GCed.  Keeps the
17403     * list in sorted order by the last GC time.  The process can't already be
17404     * on the list.
17405     */
17406    final void addProcessToGcListLocked(ProcessRecord proc) {
17407        boolean added = false;
17408        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17409            if (mProcessesToGc.get(i).lastRequestedGc <
17410                    proc.lastRequestedGc) {
17411                added = true;
17412                mProcessesToGc.add(i+1, proc);
17413                break;
17414            }
17415        }
17416        if (!added) {
17417            mProcessesToGc.add(0, proc);
17418        }
17419    }
17420
17421    /**
17422     * Set up to ask a process to GC itself.  This will either do it
17423     * immediately, or put it on the list of processes to gc the next
17424     * time things are idle.
17425     */
17426    final void scheduleAppGcLocked(ProcessRecord app) {
17427        long now = SystemClock.uptimeMillis();
17428        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17429            return;
17430        }
17431        if (!mProcessesToGc.contains(app)) {
17432            addProcessToGcListLocked(app);
17433            scheduleAppGcsLocked();
17434        }
17435    }
17436
17437    final void checkExcessivePowerUsageLocked(boolean doKills) {
17438        updateCpuStatsNow();
17439
17440        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17441        boolean doWakeKills = doKills;
17442        boolean doCpuKills = doKills;
17443        if (mLastPowerCheckRealtime == 0) {
17444            doWakeKills = false;
17445        }
17446        if (mLastPowerCheckUptime == 0) {
17447            doCpuKills = false;
17448        }
17449        if (stats.isScreenOn()) {
17450            doWakeKills = false;
17451        }
17452        final long curRealtime = SystemClock.elapsedRealtime();
17453        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17454        final long curUptime = SystemClock.uptimeMillis();
17455        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17456        mLastPowerCheckRealtime = curRealtime;
17457        mLastPowerCheckUptime = curUptime;
17458        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17459            doWakeKills = false;
17460        }
17461        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17462            doCpuKills = false;
17463        }
17464        int i = mLruProcesses.size();
17465        while (i > 0) {
17466            i--;
17467            ProcessRecord app = mLruProcesses.get(i);
17468            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17469                long wtime;
17470                synchronized (stats) {
17471                    wtime = stats.getProcessWakeTime(app.info.uid,
17472                            app.pid, curRealtime);
17473                }
17474                long wtimeUsed = wtime - app.lastWakeTime;
17475                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17476                if (DEBUG_POWER) {
17477                    StringBuilder sb = new StringBuilder(128);
17478                    sb.append("Wake for ");
17479                    app.toShortString(sb);
17480                    sb.append(": over ");
17481                    TimeUtils.formatDuration(realtimeSince, sb);
17482                    sb.append(" used ");
17483                    TimeUtils.formatDuration(wtimeUsed, sb);
17484                    sb.append(" (");
17485                    sb.append((wtimeUsed*100)/realtimeSince);
17486                    sb.append("%)");
17487                    Slog.i(TAG, sb.toString());
17488                    sb.setLength(0);
17489                    sb.append("CPU for ");
17490                    app.toShortString(sb);
17491                    sb.append(": over ");
17492                    TimeUtils.formatDuration(uptimeSince, sb);
17493                    sb.append(" used ");
17494                    TimeUtils.formatDuration(cputimeUsed, sb);
17495                    sb.append(" (");
17496                    sb.append((cputimeUsed*100)/uptimeSince);
17497                    sb.append("%)");
17498                    Slog.i(TAG, sb.toString());
17499                }
17500                // If a process has held a wake lock for more
17501                // than 50% of the time during this period,
17502                // that sounds bad.  Kill!
17503                if (doWakeKills && realtimeSince > 0
17504                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17505                    synchronized (stats) {
17506                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17507                                realtimeSince, wtimeUsed);
17508                    }
17509                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17510                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17511                } else if (doCpuKills && uptimeSince > 0
17512                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17513                    synchronized (stats) {
17514                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17515                                uptimeSince, cputimeUsed);
17516                    }
17517                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17518                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17519                } else {
17520                    app.lastWakeTime = wtime;
17521                    app.lastCpuTime = app.curCpuTime;
17522                }
17523            }
17524        }
17525    }
17526
17527    private final boolean applyOomAdjLocked(ProcessRecord app,
17528            ProcessRecord TOP_APP, boolean doingAll, long now) {
17529        boolean success = true;
17530
17531        if (app.curRawAdj != app.setRawAdj) {
17532            app.setRawAdj = app.curRawAdj;
17533        }
17534
17535        int changes = 0;
17536
17537        if (app.curAdj != app.setAdj) {
17538            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17539            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17540                TAG, "Set " + app.pid + " " + app.processName +
17541                " adj " + app.curAdj + ": " + app.adjType);
17542            app.setAdj = app.curAdj;
17543        }
17544
17545        if (app.setSchedGroup != app.curSchedGroup) {
17546            app.setSchedGroup = app.curSchedGroup;
17547            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17548                    "Setting process group of " + app.processName
17549                    + " to " + app.curSchedGroup);
17550            if (app.waitingToKill != null &&
17551                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17552                app.kill(app.waitingToKill, true);
17553                success = false;
17554            } else {
17555                if (true) {
17556                    long oldId = Binder.clearCallingIdentity();
17557                    try {
17558                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17559                    } catch (Exception e) {
17560                        Slog.w(TAG, "Failed setting process group of " + app.pid
17561                                + " to " + app.curSchedGroup);
17562                        e.printStackTrace();
17563                    } finally {
17564                        Binder.restoreCallingIdentity(oldId);
17565                    }
17566                } else {
17567                    if (app.thread != null) {
17568                        try {
17569                            app.thread.setSchedulingGroup(app.curSchedGroup);
17570                        } catch (RemoteException e) {
17571                        }
17572                    }
17573                }
17574                Process.setSwappiness(app.pid,
17575                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17576            }
17577        }
17578        if (app.repForegroundActivities != app.foregroundActivities) {
17579            app.repForegroundActivities = app.foregroundActivities;
17580            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17581        }
17582        if (app.repProcState != app.curProcState) {
17583            app.repProcState = app.curProcState;
17584            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17585            if (app.thread != null) {
17586                try {
17587                    if (false) {
17588                        //RuntimeException h = new RuntimeException("here");
17589                        Slog.i(TAG, "Sending new process state " + app.repProcState
17590                                + " to " + app /*, h*/);
17591                    }
17592                    app.thread.setProcessState(app.repProcState);
17593                } catch (RemoteException e) {
17594                }
17595            }
17596        }
17597        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17598                app.setProcState)) {
17599            app.lastStateTime = now;
17600            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17601                    isSleeping(), now);
17602            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17603                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17604                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17605                    + (app.nextPssTime-now) + ": " + app);
17606        } else {
17607            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17608                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17609                requestPssLocked(app, app.setProcState);
17610                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17611                        isSleeping(), now);
17612            } else if (false && DEBUG_PSS) {
17613                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17614            }
17615        }
17616        if (app.setProcState != app.curProcState) {
17617            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17618                    "Proc state change of " + app.processName
17619                    + " to " + app.curProcState);
17620            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17621            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17622            if (setImportant && !curImportant) {
17623                // This app is no longer something we consider important enough to allow to
17624                // use arbitrary amounts of battery power.  Note
17625                // its current wake lock time to later know to kill it if
17626                // it is not behaving well.
17627                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17628                synchronized (stats) {
17629                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17630                            app.pid, SystemClock.elapsedRealtime());
17631                }
17632                app.lastCpuTime = app.curCpuTime;
17633
17634            }
17635            app.setProcState = app.curProcState;
17636            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17637                app.notCachedSinceIdle = false;
17638            }
17639            if (!doingAll) {
17640                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17641            } else {
17642                app.procStateChanged = true;
17643            }
17644        }
17645
17646        if (changes != 0) {
17647            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17648            int i = mPendingProcessChanges.size()-1;
17649            ProcessChangeItem item = null;
17650            while (i >= 0) {
17651                item = mPendingProcessChanges.get(i);
17652                if (item.pid == app.pid) {
17653                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17654                    break;
17655                }
17656                i--;
17657            }
17658            if (i < 0) {
17659                // No existing item in pending changes; need a new one.
17660                final int NA = mAvailProcessChanges.size();
17661                if (NA > 0) {
17662                    item = mAvailProcessChanges.remove(NA-1);
17663                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17664                } else {
17665                    item = new ProcessChangeItem();
17666                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17667                }
17668                item.changes = 0;
17669                item.pid = app.pid;
17670                item.uid = app.info.uid;
17671                if (mPendingProcessChanges.size() == 0) {
17672                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17673                            "*** Enqueueing dispatch processes changed!");
17674                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17675                }
17676                mPendingProcessChanges.add(item);
17677            }
17678            item.changes |= changes;
17679            item.processState = app.repProcState;
17680            item.foregroundActivities = app.repForegroundActivities;
17681            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17682                    + Integer.toHexString(System.identityHashCode(item))
17683                    + " " + app.toShortString() + ": changes=" + item.changes
17684                    + " procState=" + item.processState
17685                    + " foreground=" + item.foregroundActivities
17686                    + " type=" + app.adjType + " source=" + app.adjSource
17687                    + " target=" + app.adjTarget);
17688        }
17689
17690        return success;
17691    }
17692
17693    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17694        if (proc.thread != null) {
17695            if (proc.baseProcessTracker != null) {
17696                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17697            }
17698            if (proc.repProcState >= 0) {
17699                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17700                        proc.repProcState);
17701            }
17702        }
17703    }
17704
17705    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17706            ProcessRecord TOP_APP, boolean doingAll, long now) {
17707        if (app.thread == null) {
17708            return false;
17709        }
17710
17711        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17712
17713        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17714    }
17715
17716    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17717            boolean oomAdj) {
17718        if (isForeground != proc.foregroundServices) {
17719            proc.foregroundServices = isForeground;
17720            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17721                    proc.info.uid);
17722            if (isForeground) {
17723                if (curProcs == null) {
17724                    curProcs = new ArrayList<ProcessRecord>();
17725                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17726                }
17727                if (!curProcs.contains(proc)) {
17728                    curProcs.add(proc);
17729                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17730                            proc.info.packageName, proc.info.uid);
17731                }
17732            } else {
17733                if (curProcs != null) {
17734                    if (curProcs.remove(proc)) {
17735                        mBatteryStatsService.noteEvent(
17736                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17737                                proc.info.packageName, proc.info.uid);
17738                        if (curProcs.size() <= 0) {
17739                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17740                        }
17741                    }
17742                }
17743            }
17744            if (oomAdj) {
17745                updateOomAdjLocked();
17746            }
17747        }
17748    }
17749
17750    private final ActivityRecord resumedAppLocked() {
17751        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17752        String pkg;
17753        int uid;
17754        if (act != null) {
17755            pkg = act.packageName;
17756            uid = act.info.applicationInfo.uid;
17757        } else {
17758            pkg = null;
17759            uid = -1;
17760        }
17761        // Has the UID or resumed package name changed?
17762        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17763                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17764            if (mCurResumedPackage != null) {
17765                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17766                        mCurResumedPackage, mCurResumedUid);
17767            }
17768            mCurResumedPackage = pkg;
17769            mCurResumedUid = uid;
17770            if (mCurResumedPackage != null) {
17771                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17772                        mCurResumedPackage, mCurResumedUid);
17773            }
17774        }
17775        return act;
17776    }
17777
17778    final boolean updateOomAdjLocked(ProcessRecord app) {
17779        final ActivityRecord TOP_ACT = resumedAppLocked();
17780        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17781        final boolean wasCached = app.cached;
17782
17783        mAdjSeq++;
17784
17785        // This is the desired cached adjusment we want to tell it to use.
17786        // If our app is currently cached, we know it, and that is it.  Otherwise,
17787        // we don't know it yet, and it needs to now be cached we will then
17788        // need to do a complete oom adj.
17789        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17790                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17791        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17792                SystemClock.uptimeMillis());
17793        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17794            // Changed to/from cached state, so apps after it in the LRU
17795            // list may also be changed.
17796            updateOomAdjLocked();
17797        }
17798        return success;
17799    }
17800
17801    final void updateOomAdjLocked() {
17802        final ActivityRecord TOP_ACT = resumedAppLocked();
17803        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17804        final long now = SystemClock.uptimeMillis();
17805        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17806        final int N = mLruProcesses.size();
17807
17808        if (false) {
17809            RuntimeException e = new RuntimeException();
17810            e.fillInStackTrace();
17811            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17812        }
17813
17814        mAdjSeq++;
17815        mNewNumServiceProcs = 0;
17816        mNewNumAServiceProcs = 0;
17817
17818        final int emptyProcessLimit;
17819        final int cachedProcessLimit;
17820        if (mProcessLimit <= 0) {
17821            emptyProcessLimit = cachedProcessLimit = 0;
17822        } else if (mProcessLimit == 1) {
17823            emptyProcessLimit = 1;
17824            cachedProcessLimit = 0;
17825        } else {
17826            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17827            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17828        }
17829
17830        // Let's determine how many processes we have running vs.
17831        // how many slots we have for background processes; we may want
17832        // to put multiple processes in a slot of there are enough of
17833        // them.
17834        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17835                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17836        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17837        if (numEmptyProcs > cachedProcessLimit) {
17838            // If there are more empty processes than our limit on cached
17839            // processes, then use the cached process limit for the factor.
17840            // This ensures that the really old empty processes get pushed
17841            // down to the bottom, so if we are running low on memory we will
17842            // have a better chance at keeping around more cached processes
17843            // instead of a gazillion empty processes.
17844            numEmptyProcs = cachedProcessLimit;
17845        }
17846        int emptyFactor = numEmptyProcs/numSlots;
17847        if (emptyFactor < 1) emptyFactor = 1;
17848        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17849        if (cachedFactor < 1) cachedFactor = 1;
17850        int stepCached = 0;
17851        int stepEmpty = 0;
17852        int numCached = 0;
17853        int numEmpty = 0;
17854        int numTrimming = 0;
17855
17856        mNumNonCachedProcs = 0;
17857        mNumCachedHiddenProcs = 0;
17858
17859        // First update the OOM adjustment for each of the
17860        // application processes based on their current state.
17861        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17862        int nextCachedAdj = curCachedAdj+1;
17863        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17864        int nextEmptyAdj = curEmptyAdj+2;
17865        for (int i=N-1; i>=0; i--) {
17866            ProcessRecord app = mLruProcesses.get(i);
17867            if (!app.killedByAm && app.thread != null) {
17868                app.procStateChanged = false;
17869                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17870
17871                // If we haven't yet assigned the final cached adj
17872                // to the process, do that now.
17873                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17874                    switch (app.curProcState) {
17875                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17876                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17877                            // This process is a cached process holding activities...
17878                            // assign it the next cached value for that type, and then
17879                            // step that cached level.
17880                            app.curRawAdj = curCachedAdj;
17881                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17882                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17883                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17884                                    + ")");
17885                            if (curCachedAdj != nextCachedAdj) {
17886                                stepCached++;
17887                                if (stepCached >= cachedFactor) {
17888                                    stepCached = 0;
17889                                    curCachedAdj = nextCachedAdj;
17890                                    nextCachedAdj += 2;
17891                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17892                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17893                                    }
17894                                }
17895                            }
17896                            break;
17897                        default:
17898                            // For everything else, assign next empty cached process
17899                            // level and bump that up.  Note that this means that
17900                            // long-running services that have dropped down to the
17901                            // cached level will be treated as empty (since their process
17902                            // state is still as a service), which is what we want.
17903                            app.curRawAdj = curEmptyAdj;
17904                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17905                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17906                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17907                                    + ")");
17908                            if (curEmptyAdj != nextEmptyAdj) {
17909                                stepEmpty++;
17910                                if (stepEmpty >= emptyFactor) {
17911                                    stepEmpty = 0;
17912                                    curEmptyAdj = nextEmptyAdj;
17913                                    nextEmptyAdj += 2;
17914                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17915                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17916                                    }
17917                                }
17918                            }
17919                            break;
17920                    }
17921                }
17922
17923                applyOomAdjLocked(app, TOP_APP, true, now);
17924
17925                // Count the number of process types.
17926                switch (app.curProcState) {
17927                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17928                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17929                        mNumCachedHiddenProcs++;
17930                        numCached++;
17931                        if (numCached > cachedProcessLimit) {
17932                            app.kill("cached #" + numCached, true);
17933                        }
17934                        break;
17935                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17936                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17937                                && app.lastActivityTime < oldTime) {
17938                            app.kill("empty for "
17939                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17940                                    / 1000) + "s", true);
17941                        } else {
17942                            numEmpty++;
17943                            if (numEmpty > emptyProcessLimit) {
17944                                app.kill("empty #" + numEmpty, true);
17945                            }
17946                        }
17947                        break;
17948                    default:
17949                        mNumNonCachedProcs++;
17950                        break;
17951                }
17952
17953                if (app.isolated && app.services.size() <= 0) {
17954                    // If this is an isolated process, and there are no
17955                    // services running in it, then the process is no longer
17956                    // needed.  We agressively kill these because we can by
17957                    // definition not re-use the same process again, and it is
17958                    // good to avoid having whatever code was running in them
17959                    // left sitting around after no longer needed.
17960                    app.kill("isolated not needed", true);
17961                }
17962
17963                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17964                        && !app.killedByAm) {
17965                    numTrimming++;
17966                }
17967            }
17968        }
17969
17970        mNumServiceProcs = mNewNumServiceProcs;
17971
17972        // Now determine the memory trimming level of background processes.
17973        // Unfortunately we need to start at the back of the list to do this
17974        // properly.  We only do this if the number of background apps we
17975        // are managing to keep around is less than half the maximum we desire;
17976        // if we are keeping a good number around, we'll let them use whatever
17977        // memory they want.
17978        final int numCachedAndEmpty = numCached + numEmpty;
17979        int memFactor;
17980        if (numCached <= ProcessList.TRIM_CACHED_APPS
17981                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17982            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17983                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17984            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17985                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17986            } else {
17987                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17988            }
17989        } else {
17990            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17991        }
17992        // We always allow the memory level to go up (better).  We only allow it to go
17993        // down if we are in a state where that is allowed, *and* the total number of processes
17994        // has gone down since last time.
17995        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17996                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17997                + " last=" + mLastNumProcesses);
17998        if (memFactor > mLastMemoryLevel) {
17999            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18000                memFactor = mLastMemoryLevel;
18001                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18002            }
18003        }
18004        mLastMemoryLevel = memFactor;
18005        mLastNumProcesses = mLruProcesses.size();
18006        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18007        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18008        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18009            if (mLowRamStartTime == 0) {
18010                mLowRamStartTime = now;
18011            }
18012            int step = 0;
18013            int fgTrimLevel;
18014            switch (memFactor) {
18015                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18016                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18017                    break;
18018                case ProcessStats.ADJ_MEM_FACTOR_LOW:
18019                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18020                    break;
18021                default:
18022                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18023                    break;
18024            }
18025            int factor = numTrimming/3;
18026            int minFactor = 2;
18027            if (mHomeProcess != null) minFactor++;
18028            if (mPreviousProcess != null) minFactor++;
18029            if (factor < minFactor) factor = minFactor;
18030            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18031            for (int i=N-1; i>=0; i--) {
18032                ProcessRecord app = mLruProcesses.get(i);
18033                if (allChanged || app.procStateChanged) {
18034                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18035                    app.procStateChanged = false;
18036                }
18037                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18038                        && !app.killedByAm) {
18039                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
18040                        try {
18041                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18042                                    "Trimming memory of " + app.processName
18043                                    + " to " + curLevel);
18044                            app.thread.scheduleTrimMemory(curLevel);
18045                        } catch (RemoteException e) {
18046                        }
18047                        if (false) {
18048                            // For now we won't do this; our memory trimming seems
18049                            // to be good enough at this point that destroying
18050                            // activities causes more harm than good.
18051                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18052                                    && app != mHomeProcess && app != mPreviousProcess) {
18053                                // Need to do this on its own message because the stack may not
18054                                // be in a consistent state at this point.
18055                                // For these apps we will also finish their activities
18056                                // to help them free memory.
18057                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18058                            }
18059                        }
18060                    }
18061                    app.trimMemoryLevel = curLevel;
18062                    step++;
18063                    if (step >= factor) {
18064                        step = 0;
18065                        switch (curLevel) {
18066                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18067                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18068                                break;
18069                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18070                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18071                                break;
18072                        }
18073                    }
18074                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18075                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18076                            && app.thread != null) {
18077                        try {
18078                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18079                                    "Trimming memory of heavy-weight " + app.processName
18080                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18081                            app.thread.scheduleTrimMemory(
18082                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18083                        } catch (RemoteException e) {
18084                        }
18085                    }
18086                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18087                } else {
18088                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18089                            || app.systemNoUi) && app.pendingUiClean) {
18090                        // If this application is now in the background and it
18091                        // had done UI, then give it the special trim level to
18092                        // have it free UI resources.
18093                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18094                        if (app.trimMemoryLevel < level && app.thread != null) {
18095                            try {
18096                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18097                                        "Trimming memory of bg-ui " + app.processName
18098                                        + " to " + level);
18099                                app.thread.scheduleTrimMemory(level);
18100                            } catch (RemoteException e) {
18101                            }
18102                        }
18103                        app.pendingUiClean = false;
18104                    }
18105                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18106                        try {
18107                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18108                                    "Trimming memory of fg " + app.processName
18109                                    + " to " + fgTrimLevel);
18110                            app.thread.scheduleTrimMemory(fgTrimLevel);
18111                        } catch (RemoteException e) {
18112                        }
18113                    }
18114                    app.trimMemoryLevel = fgTrimLevel;
18115                }
18116            }
18117        } else {
18118            if (mLowRamStartTime != 0) {
18119                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18120                mLowRamStartTime = 0;
18121            }
18122            for (int i=N-1; i>=0; i--) {
18123                ProcessRecord app = mLruProcesses.get(i);
18124                if (allChanged || app.procStateChanged) {
18125                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18126                    app.procStateChanged = false;
18127                }
18128                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18129                        || app.systemNoUi) && app.pendingUiClean) {
18130                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18131                            && app.thread != null) {
18132                        try {
18133                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18134                                    "Trimming memory of ui hidden " + app.processName
18135                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18136                            app.thread.scheduleTrimMemory(
18137                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18138                        } catch (RemoteException e) {
18139                        }
18140                    }
18141                    app.pendingUiClean = false;
18142                }
18143                app.trimMemoryLevel = 0;
18144            }
18145        }
18146
18147        if (mAlwaysFinishActivities) {
18148            // Need to do this on its own message because the stack may not
18149            // be in a consistent state at this point.
18150            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18151        }
18152
18153        if (allChanged) {
18154            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18155        }
18156
18157        if (mProcessStats.shouldWriteNowLocked(now)) {
18158            mHandler.post(new Runnable() {
18159                @Override public void run() {
18160                    synchronized (ActivityManagerService.this) {
18161                        mProcessStats.writeStateAsyncLocked();
18162                    }
18163                }
18164            });
18165        }
18166
18167        if (DEBUG_OOM_ADJ) {
18168            if (false) {
18169                RuntimeException here = new RuntimeException("here");
18170                here.fillInStackTrace();
18171                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18172            } else {
18173                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18174            }
18175        }
18176    }
18177
18178    final void trimApplications() {
18179        synchronized (this) {
18180            int i;
18181
18182            // First remove any unused application processes whose package
18183            // has been removed.
18184            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18185                final ProcessRecord app = mRemovedProcesses.get(i);
18186                if (app.activities.size() == 0
18187                        && app.curReceiver == null && app.services.size() == 0) {
18188                    Slog.i(
18189                        TAG, "Exiting empty application process "
18190                        + app.processName + " ("
18191                        + (app.thread != null ? app.thread.asBinder() : null)
18192                        + ")\n");
18193                    if (app.pid > 0 && app.pid != MY_PID) {
18194                        app.kill("empty", false);
18195                    } else {
18196                        try {
18197                            app.thread.scheduleExit();
18198                        } catch (Exception e) {
18199                            // Ignore exceptions.
18200                        }
18201                    }
18202                    cleanUpApplicationRecordLocked(app, false, true, -1);
18203                    mRemovedProcesses.remove(i);
18204
18205                    if (app.persistent) {
18206                        addAppLocked(app.info, false, null /* ABI override */);
18207                    }
18208                }
18209            }
18210
18211            // Now update the oom adj for all processes.
18212            updateOomAdjLocked();
18213        }
18214    }
18215
18216    /** This method sends the specified signal to each of the persistent apps */
18217    public void signalPersistentProcesses(int sig) throws RemoteException {
18218        if (sig != Process.SIGNAL_USR1) {
18219            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18220        }
18221
18222        synchronized (this) {
18223            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18224                    != PackageManager.PERMISSION_GRANTED) {
18225                throw new SecurityException("Requires permission "
18226                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18227            }
18228
18229            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18230                ProcessRecord r = mLruProcesses.get(i);
18231                if (r.thread != null && r.persistent) {
18232                    Process.sendSignal(r.pid, sig);
18233                }
18234            }
18235        }
18236    }
18237
18238    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18239        if (proc == null || proc == mProfileProc) {
18240            proc = mProfileProc;
18241            profileType = mProfileType;
18242            clearProfilerLocked();
18243        }
18244        if (proc == null) {
18245            return;
18246        }
18247        try {
18248            proc.thread.profilerControl(false, null, profileType);
18249        } catch (RemoteException e) {
18250            throw new IllegalStateException("Process disappeared");
18251        }
18252    }
18253
18254    private void clearProfilerLocked() {
18255        if (mProfileFd != null) {
18256            try {
18257                mProfileFd.close();
18258            } catch (IOException e) {
18259            }
18260        }
18261        mProfileApp = null;
18262        mProfileProc = null;
18263        mProfileFile = null;
18264        mProfileType = 0;
18265        mAutoStopProfiler = false;
18266        mSamplingInterval = 0;
18267    }
18268
18269    public boolean profileControl(String process, int userId, boolean start,
18270            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18271
18272        try {
18273            synchronized (this) {
18274                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18275                // its own permission.
18276                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18277                        != PackageManager.PERMISSION_GRANTED) {
18278                    throw new SecurityException("Requires permission "
18279                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18280                }
18281
18282                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18283                    throw new IllegalArgumentException("null profile info or fd");
18284                }
18285
18286                ProcessRecord proc = null;
18287                if (process != null) {
18288                    proc = findProcessLocked(process, userId, "profileControl");
18289                }
18290
18291                if (start && (proc == null || proc.thread == null)) {
18292                    throw new IllegalArgumentException("Unknown process: " + process);
18293                }
18294
18295                if (start) {
18296                    stopProfilerLocked(null, 0);
18297                    setProfileApp(proc.info, proc.processName, profilerInfo);
18298                    mProfileProc = proc;
18299                    mProfileType = profileType;
18300                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18301                    try {
18302                        fd = fd.dup();
18303                    } catch (IOException e) {
18304                        fd = null;
18305                    }
18306                    profilerInfo.profileFd = fd;
18307                    proc.thread.profilerControl(start, profilerInfo, profileType);
18308                    fd = null;
18309                    mProfileFd = null;
18310                } else {
18311                    stopProfilerLocked(proc, profileType);
18312                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18313                        try {
18314                            profilerInfo.profileFd.close();
18315                        } catch (IOException e) {
18316                        }
18317                    }
18318                }
18319
18320                return true;
18321            }
18322        } catch (RemoteException e) {
18323            throw new IllegalStateException("Process disappeared");
18324        } finally {
18325            if (profilerInfo != null && profilerInfo.profileFd != null) {
18326                try {
18327                    profilerInfo.profileFd.close();
18328                } catch (IOException e) {
18329                }
18330            }
18331        }
18332    }
18333
18334    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18335        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18336                userId, true, ALLOW_FULL_ONLY, callName, null);
18337        ProcessRecord proc = null;
18338        try {
18339            int pid = Integer.parseInt(process);
18340            synchronized (mPidsSelfLocked) {
18341                proc = mPidsSelfLocked.get(pid);
18342            }
18343        } catch (NumberFormatException e) {
18344        }
18345
18346        if (proc == null) {
18347            ArrayMap<String, SparseArray<ProcessRecord>> all
18348                    = mProcessNames.getMap();
18349            SparseArray<ProcessRecord> procs = all.get(process);
18350            if (procs != null && procs.size() > 0) {
18351                proc = procs.valueAt(0);
18352                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18353                    for (int i=1; i<procs.size(); i++) {
18354                        ProcessRecord thisProc = procs.valueAt(i);
18355                        if (thisProc.userId == userId) {
18356                            proc = thisProc;
18357                            break;
18358                        }
18359                    }
18360                }
18361            }
18362        }
18363
18364        return proc;
18365    }
18366
18367    public boolean dumpHeap(String process, int userId, boolean managed,
18368            String path, ParcelFileDescriptor fd) throws RemoteException {
18369
18370        try {
18371            synchronized (this) {
18372                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18373                // its own permission (same as profileControl).
18374                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18375                        != PackageManager.PERMISSION_GRANTED) {
18376                    throw new SecurityException("Requires permission "
18377                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18378                }
18379
18380                if (fd == null) {
18381                    throw new IllegalArgumentException("null fd");
18382                }
18383
18384                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18385                if (proc == null || proc.thread == null) {
18386                    throw new IllegalArgumentException("Unknown process: " + process);
18387                }
18388
18389                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18390                if (!isDebuggable) {
18391                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18392                        throw new SecurityException("Process not debuggable: " + proc);
18393                    }
18394                }
18395
18396                proc.thread.dumpHeap(managed, path, fd);
18397                fd = null;
18398                return true;
18399            }
18400        } catch (RemoteException e) {
18401            throw new IllegalStateException("Process disappeared");
18402        } finally {
18403            if (fd != null) {
18404                try {
18405                    fd.close();
18406                } catch (IOException e) {
18407                }
18408            }
18409        }
18410    }
18411
18412    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18413    public void monitor() {
18414        synchronized (this) { }
18415    }
18416
18417    void onCoreSettingsChange(Bundle settings) {
18418        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18419            ProcessRecord processRecord = mLruProcesses.get(i);
18420            try {
18421                if (processRecord.thread != null) {
18422                    processRecord.thread.setCoreSettings(settings);
18423                }
18424            } catch (RemoteException re) {
18425                /* ignore */
18426            }
18427        }
18428    }
18429
18430    // Multi-user methods
18431
18432    /**
18433     * Start user, if its not already running, but don't bring it to foreground.
18434     */
18435    @Override
18436    public boolean startUserInBackground(final int userId) {
18437        return startUser(userId, /* foreground */ false);
18438    }
18439
18440    /**
18441     * Start user, if its not already running, and bring it to foreground.
18442     */
18443    boolean startUserInForeground(final int userId, Dialog dlg) {
18444        boolean result = startUser(userId, /* foreground */ true);
18445        dlg.dismiss();
18446        return result;
18447    }
18448
18449    /**
18450     * Refreshes the list of users related to the current user when either a
18451     * user switch happens or when a new related user is started in the
18452     * background.
18453     */
18454    private void updateCurrentProfileIdsLocked() {
18455        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18456                mCurrentUserId, false /* enabledOnly */);
18457        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18458        for (int i = 0; i < currentProfileIds.length; i++) {
18459            currentProfileIds[i] = profiles.get(i).id;
18460        }
18461        mCurrentProfileIds = currentProfileIds;
18462
18463        synchronized (mUserProfileGroupIdsSelfLocked) {
18464            mUserProfileGroupIdsSelfLocked.clear();
18465            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18466            for (int i = 0; i < users.size(); i++) {
18467                UserInfo user = users.get(i);
18468                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18469                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18470                }
18471            }
18472        }
18473    }
18474
18475    private Set getProfileIdsLocked(int userId) {
18476        Set userIds = new HashSet<Integer>();
18477        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18478                userId, false /* enabledOnly */);
18479        for (UserInfo user : profiles) {
18480            userIds.add(Integer.valueOf(user.id));
18481        }
18482        return userIds;
18483    }
18484
18485    @Override
18486    public boolean switchUser(final int userId) {
18487        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18488        String userName;
18489        synchronized (this) {
18490            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18491            if (userInfo == null) {
18492                Slog.w(TAG, "No user info for user #" + userId);
18493                return false;
18494            }
18495            if (userInfo.isManagedProfile()) {
18496                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18497                return false;
18498            }
18499            userName = userInfo.name;
18500            mTargetUserId = userId;
18501        }
18502        mHandler.removeMessages(START_USER_SWITCH_MSG);
18503        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18504        return true;
18505    }
18506
18507    private void showUserSwitchDialog(int userId, String userName) {
18508        // The dialog will show and then initiate the user switch by calling startUserInForeground
18509        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18510                true /* above system */);
18511        d.show();
18512    }
18513
18514    private boolean startUser(final int userId, final boolean foreground) {
18515        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18516                != PackageManager.PERMISSION_GRANTED) {
18517            String msg = "Permission Denial: switchUser() from pid="
18518                    + Binder.getCallingPid()
18519                    + ", uid=" + Binder.getCallingUid()
18520                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18521            Slog.w(TAG, msg);
18522            throw new SecurityException(msg);
18523        }
18524
18525        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18526
18527        final long ident = Binder.clearCallingIdentity();
18528        try {
18529            synchronized (this) {
18530                final int oldUserId = mCurrentUserId;
18531                if (oldUserId == userId) {
18532                    return true;
18533                }
18534
18535                mStackSupervisor.setLockTaskModeLocked(null, false);
18536
18537                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18538                if (userInfo == null) {
18539                    Slog.w(TAG, "No user info for user #" + userId);
18540                    return false;
18541                }
18542                if (foreground && userInfo.isManagedProfile()) {
18543                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18544                    return false;
18545                }
18546
18547                if (foreground) {
18548                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18549                            R.anim.screen_user_enter);
18550                }
18551
18552                boolean needStart = false;
18553
18554                // If the user we are switching to is not currently started, then
18555                // we need to start it now.
18556                if (mStartedUsers.get(userId) == null) {
18557                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18558                    updateStartedUserArrayLocked();
18559                    needStart = true;
18560                }
18561
18562                final Integer userIdInt = Integer.valueOf(userId);
18563                mUserLru.remove(userIdInt);
18564                mUserLru.add(userIdInt);
18565
18566                if (foreground) {
18567                    mCurrentUserId = userId;
18568                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18569                    updateCurrentProfileIdsLocked();
18570                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18571                    // Once the internal notion of the active user has switched, we lock the device
18572                    // with the option to show the user switcher on the keyguard.
18573                    mWindowManager.lockNow(null);
18574                } else {
18575                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18576                    updateCurrentProfileIdsLocked();
18577                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18578                    mUserLru.remove(currentUserIdInt);
18579                    mUserLru.add(currentUserIdInt);
18580                }
18581
18582                final UserStartedState uss = mStartedUsers.get(userId);
18583
18584                // Make sure user is in the started state.  If it is currently
18585                // stopping, we need to knock that off.
18586                if (uss.mState == UserStartedState.STATE_STOPPING) {
18587                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18588                    // so we can just fairly silently bring the user back from
18589                    // the almost-dead.
18590                    uss.mState = UserStartedState.STATE_RUNNING;
18591                    updateStartedUserArrayLocked();
18592                    needStart = true;
18593                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18594                    // This means ACTION_SHUTDOWN has been sent, so we will
18595                    // need to treat this as a new boot of the user.
18596                    uss.mState = UserStartedState.STATE_BOOTING;
18597                    updateStartedUserArrayLocked();
18598                    needStart = true;
18599                }
18600
18601                if (uss.mState == UserStartedState.STATE_BOOTING) {
18602                    // Booting up a new user, need to tell system services about it.
18603                    // Note that this is on the same handler as scheduling of broadcasts,
18604                    // which is important because it needs to go first.
18605                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18606                }
18607
18608                if (foreground) {
18609                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18610                            oldUserId));
18611                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18612                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18613                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18614                            oldUserId, userId, uss));
18615                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18616                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18617                }
18618
18619                if (needStart) {
18620                    // Send USER_STARTED broadcast
18621                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18622                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18623                            | Intent.FLAG_RECEIVER_FOREGROUND);
18624                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18625                    broadcastIntentLocked(null, null, intent,
18626                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18627                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18628                }
18629
18630                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18631                    if (userId != UserHandle.USER_OWNER) {
18632                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18633                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18634                        broadcastIntentLocked(null, null, intent, null,
18635                                new IIntentReceiver.Stub() {
18636                                    public void performReceive(Intent intent, int resultCode,
18637                                            String data, Bundle extras, boolean ordered,
18638                                            boolean sticky, int sendingUser) {
18639                                        onUserInitialized(uss, foreground, oldUserId, userId);
18640                                    }
18641                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18642                                true, false, MY_PID, Process.SYSTEM_UID,
18643                                userId);
18644                        uss.initializing = true;
18645                    } else {
18646                        getUserManagerLocked().makeInitialized(userInfo.id);
18647                    }
18648                }
18649
18650                if (foreground) {
18651                    if (!uss.initializing) {
18652                        moveUserToForeground(uss, oldUserId, userId);
18653                    }
18654                } else {
18655                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18656                }
18657
18658                if (needStart) {
18659                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18660                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18661                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18662                    broadcastIntentLocked(null, null, intent,
18663                            null, new IIntentReceiver.Stub() {
18664                                @Override
18665                                public void performReceive(Intent intent, int resultCode, String data,
18666                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18667                                        throws RemoteException {
18668                                }
18669                            }, 0, null, null,
18670                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18671                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18672                }
18673            }
18674        } finally {
18675            Binder.restoreCallingIdentity(ident);
18676        }
18677
18678        return true;
18679    }
18680
18681    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18682        long ident = Binder.clearCallingIdentity();
18683        try {
18684            Intent intent;
18685            if (oldUserId >= 0) {
18686                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18687                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18688                int count = profiles.size();
18689                for (int i = 0; i < count; i++) {
18690                    int profileUserId = profiles.get(i).id;
18691                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18692                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18693                            | Intent.FLAG_RECEIVER_FOREGROUND);
18694                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18695                    broadcastIntentLocked(null, null, intent,
18696                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18697                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18698                }
18699            }
18700            if (newUserId >= 0) {
18701                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18702                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18703                int count = profiles.size();
18704                for (int i = 0; i < count; i++) {
18705                    int profileUserId = profiles.get(i).id;
18706                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18707                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18708                            | Intent.FLAG_RECEIVER_FOREGROUND);
18709                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18710                    broadcastIntentLocked(null, null, intent,
18711                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18712                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18713                }
18714                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18715                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18716                        | Intent.FLAG_RECEIVER_FOREGROUND);
18717                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18718                broadcastIntentLocked(null, null, intent,
18719                        null, null, 0, null, null,
18720                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18721                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18722            }
18723        } finally {
18724            Binder.restoreCallingIdentity(ident);
18725        }
18726    }
18727
18728    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18729            final int newUserId) {
18730        final int N = mUserSwitchObservers.beginBroadcast();
18731        if (N > 0) {
18732            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18733                int mCount = 0;
18734                @Override
18735                public void sendResult(Bundle data) throws RemoteException {
18736                    synchronized (ActivityManagerService.this) {
18737                        if (mCurUserSwitchCallback == this) {
18738                            mCount++;
18739                            if (mCount == N) {
18740                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18741                            }
18742                        }
18743                    }
18744                }
18745            };
18746            synchronized (this) {
18747                uss.switching = true;
18748                mCurUserSwitchCallback = callback;
18749            }
18750            for (int i=0; i<N; i++) {
18751                try {
18752                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18753                            newUserId, callback);
18754                } catch (RemoteException e) {
18755                }
18756            }
18757        } else {
18758            synchronized (this) {
18759                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18760            }
18761        }
18762        mUserSwitchObservers.finishBroadcast();
18763    }
18764
18765    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18766        synchronized (this) {
18767            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18768            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18769        }
18770    }
18771
18772    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18773        mCurUserSwitchCallback = null;
18774        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18775        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18776                oldUserId, newUserId, uss));
18777    }
18778
18779    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18780        synchronized (this) {
18781            if (foreground) {
18782                moveUserToForeground(uss, oldUserId, newUserId);
18783            }
18784        }
18785
18786        completeSwitchAndInitalize(uss, newUserId, true, false);
18787    }
18788
18789    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18790        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18791        if (homeInFront) {
18792            startHomeActivityLocked(newUserId);
18793        } else {
18794            mStackSupervisor.resumeTopActivitiesLocked();
18795        }
18796        EventLogTags.writeAmSwitchUser(newUserId);
18797        getUserManagerLocked().userForeground(newUserId);
18798        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18799    }
18800
18801    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18802        completeSwitchAndInitalize(uss, newUserId, false, true);
18803    }
18804
18805    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18806            boolean clearInitializing, boolean clearSwitching) {
18807        boolean unfrozen = false;
18808        synchronized (this) {
18809            if (clearInitializing) {
18810                uss.initializing = false;
18811                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18812            }
18813            if (clearSwitching) {
18814                uss.switching = false;
18815            }
18816            if (!uss.switching && !uss.initializing) {
18817                mWindowManager.stopFreezingScreen();
18818                unfrozen = true;
18819            }
18820        }
18821        if (unfrozen) {
18822            final int N = mUserSwitchObservers.beginBroadcast();
18823            for (int i=0; i<N; i++) {
18824                try {
18825                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18826                } catch (RemoteException e) {
18827                }
18828            }
18829            mUserSwitchObservers.finishBroadcast();
18830        }
18831    }
18832
18833    void scheduleStartProfilesLocked() {
18834        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18835            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18836                    DateUtils.SECOND_IN_MILLIS);
18837        }
18838    }
18839
18840    void startProfilesLocked() {
18841        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18842        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18843                mCurrentUserId, false /* enabledOnly */);
18844        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18845        for (UserInfo user : profiles) {
18846            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18847                    && user.id != mCurrentUserId) {
18848                toStart.add(user);
18849            }
18850        }
18851        final int n = toStart.size();
18852        int i = 0;
18853        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18854            startUserInBackground(toStart.get(i).id);
18855        }
18856        if (i < n) {
18857            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18858        }
18859    }
18860
18861    void finishUserBoot(UserStartedState uss) {
18862        synchronized (this) {
18863            if (uss.mState == UserStartedState.STATE_BOOTING
18864                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18865                uss.mState = UserStartedState.STATE_RUNNING;
18866                final int userId = uss.mHandle.getIdentifier();
18867                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18868                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18869                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18870                broadcastIntentLocked(null, null, intent,
18871                        null, null, 0, null, null,
18872                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18873                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18874            }
18875        }
18876    }
18877
18878    void finishUserSwitch(UserStartedState uss) {
18879        synchronized (this) {
18880            finishUserBoot(uss);
18881
18882            startProfilesLocked();
18883
18884            int num = mUserLru.size();
18885            int i = 0;
18886            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18887                Integer oldUserId = mUserLru.get(i);
18888                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18889                if (oldUss == null) {
18890                    // Shouldn't happen, but be sane if it does.
18891                    mUserLru.remove(i);
18892                    num--;
18893                    continue;
18894                }
18895                if (oldUss.mState == UserStartedState.STATE_STOPPING
18896                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18897                    // This user is already stopping, doesn't count.
18898                    num--;
18899                    i++;
18900                    continue;
18901                }
18902                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18903                    // Owner and current can't be stopped, but count as running.
18904                    i++;
18905                    continue;
18906                }
18907                // This is a user to be stopped.
18908                stopUserLocked(oldUserId, null);
18909                num--;
18910                i++;
18911            }
18912        }
18913    }
18914
18915    @Override
18916    public int stopUser(final int userId, final IStopUserCallback callback) {
18917        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18918                != PackageManager.PERMISSION_GRANTED) {
18919            String msg = "Permission Denial: switchUser() from pid="
18920                    + Binder.getCallingPid()
18921                    + ", uid=" + Binder.getCallingUid()
18922                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18923            Slog.w(TAG, msg);
18924            throw new SecurityException(msg);
18925        }
18926        if (userId <= 0) {
18927            throw new IllegalArgumentException("Can't stop primary user " + userId);
18928        }
18929        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18930        synchronized (this) {
18931            return stopUserLocked(userId, callback);
18932        }
18933    }
18934
18935    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18936        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18937        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18938            return ActivityManager.USER_OP_IS_CURRENT;
18939        }
18940
18941        final UserStartedState uss = mStartedUsers.get(userId);
18942        if (uss == null) {
18943            // User is not started, nothing to do...  but we do need to
18944            // callback if requested.
18945            if (callback != null) {
18946                mHandler.post(new Runnable() {
18947                    @Override
18948                    public void run() {
18949                        try {
18950                            callback.userStopped(userId);
18951                        } catch (RemoteException e) {
18952                        }
18953                    }
18954                });
18955            }
18956            return ActivityManager.USER_OP_SUCCESS;
18957        }
18958
18959        if (callback != null) {
18960            uss.mStopCallbacks.add(callback);
18961        }
18962
18963        if (uss.mState != UserStartedState.STATE_STOPPING
18964                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18965            uss.mState = UserStartedState.STATE_STOPPING;
18966            updateStartedUserArrayLocked();
18967
18968            long ident = Binder.clearCallingIdentity();
18969            try {
18970                // We are going to broadcast ACTION_USER_STOPPING and then
18971                // once that is done send a final ACTION_SHUTDOWN and then
18972                // stop the user.
18973                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18974                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18975                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18976                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18977                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18978                // This is the result receiver for the final shutdown broadcast.
18979                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18980                    @Override
18981                    public void performReceive(Intent intent, int resultCode, String data,
18982                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18983                        finishUserStop(uss);
18984                    }
18985                };
18986                // This is the result receiver for the initial stopping broadcast.
18987                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18988                    @Override
18989                    public void performReceive(Intent intent, int resultCode, String data,
18990                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18991                        // On to the next.
18992                        synchronized (ActivityManagerService.this) {
18993                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18994                                // Whoops, we are being started back up.  Abort, abort!
18995                                return;
18996                            }
18997                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18998                        }
18999                        mBatteryStatsService.noteEvent(
19000                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19001                                Integer.toString(userId), userId);
19002                        mSystemServiceManager.stopUser(userId);
19003                        broadcastIntentLocked(null, null, shutdownIntent,
19004                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19005                                true, false, MY_PID, Process.SYSTEM_UID, userId);
19006                    }
19007                };
19008                // Kick things off.
19009                broadcastIntentLocked(null, null, stoppingIntent,
19010                        null, stoppingReceiver, 0, null, null,
19011                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19012                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19013            } finally {
19014                Binder.restoreCallingIdentity(ident);
19015            }
19016        }
19017
19018        return ActivityManager.USER_OP_SUCCESS;
19019    }
19020
19021    void finishUserStop(UserStartedState uss) {
19022        final int userId = uss.mHandle.getIdentifier();
19023        boolean stopped;
19024        ArrayList<IStopUserCallback> callbacks;
19025        synchronized (this) {
19026            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19027            if (mStartedUsers.get(userId) != uss) {
19028                stopped = false;
19029            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19030                stopped = false;
19031            } else {
19032                stopped = true;
19033                // User can no longer run.
19034                mStartedUsers.remove(userId);
19035                mUserLru.remove(Integer.valueOf(userId));
19036                updateStartedUserArrayLocked();
19037
19038                // Clean up all state and processes associated with the user.
19039                // Kill all the processes for the user.
19040                forceStopUserLocked(userId, "finish user");
19041            }
19042
19043            // Explicitly remove the old information in mRecentTasks.
19044            removeRecentTasksForUserLocked(userId);
19045        }
19046
19047        for (int i=0; i<callbacks.size(); i++) {
19048            try {
19049                if (stopped) callbacks.get(i).userStopped(userId);
19050                else callbacks.get(i).userStopAborted(userId);
19051            } catch (RemoteException e) {
19052            }
19053        }
19054
19055        if (stopped) {
19056            mSystemServiceManager.cleanupUser(userId);
19057            synchronized (this) {
19058                mStackSupervisor.removeUserLocked(userId);
19059            }
19060        }
19061    }
19062
19063    @Override
19064    public UserInfo getCurrentUser() {
19065        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19066                != PackageManager.PERMISSION_GRANTED) && (
19067                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19068                != PackageManager.PERMISSION_GRANTED)) {
19069            String msg = "Permission Denial: getCurrentUser() from pid="
19070                    + Binder.getCallingPid()
19071                    + ", uid=" + Binder.getCallingUid()
19072                    + " requires " + INTERACT_ACROSS_USERS;
19073            Slog.w(TAG, msg);
19074            throw new SecurityException(msg);
19075        }
19076        synchronized (this) {
19077            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19078            return getUserManagerLocked().getUserInfo(userId);
19079        }
19080    }
19081
19082    int getCurrentUserIdLocked() {
19083        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19084    }
19085
19086    @Override
19087    public boolean isUserRunning(int userId, boolean orStopped) {
19088        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19089                != PackageManager.PERMISSION_GRANTED) {
19090            String msg = "Permission Denial: isUserRunning() from pid="
19091                    + Binder.getCallingPid()
19092                    + ", uid=" + Binder.getCallingUid()
19093                    + " requires " + INTERACT_ACROSS_USERS;
19094            Slog.w(TAG, msg);
19095            throw new SecurityException(msg);
19096        }
19097        synchronized (this) {
19098            return isUserRunningLocked(userId, orStopped);
19099        }
19100    }
19101
19102    boolean isUserRunningLocked(int userId, boolean orStopped) {
19103        UserStartedState state = mStartedUsers.get(userId);
19104        if (state == null) {
19105            return false;
19106        }
19107        if (orStopped) {
19108            return true;
19109        }
19110        return state.mState != UserStartedState.STATE_STOPPING
19111                && state.mState != UserStartedState.STATE_SHUTDOWN;
19112    }
19113
19114    @Override
19115    public int[] getRunningUserIds() {
19116        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19117                != PackageManager.PERMISSION_GRANTED) {
19118            String msg = "Permission Denial: isUserRunning() from pid="
19119                    + Binder.getCallingPid()
19120                    + ", uid=" + Binder.getCallingUid()
19121                    + " requires " + INTERACT_ACROSS_USERS;
19122            Slog.w(TAG, msg);
19123            throw new SecurityException(msg);
19124        }
19125        synchronized (this) {
19126            return mStartedUserArray;
19127        }
19128    }
19129
19130    private void updateStartedUserArrayLocked() {
19131        int num = 0;
19132        for (int i=0; i<mStartedUsers.size();  i++) {
19133            UserStartedState uss = mStartedUsers.valueAt(i);
19134            // This list does not include stopping users.
19135            if (uss.mState != UserStartedState.STATE_STOPPING
19136                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19137                num++;
19138            }
19139        }
19140        mStartedUserArray = new int[num];
19141        num = 0;
19142        for (int i=0; i<mStartedUsers.size();  i++) {
19143            UserStartedState uss = mStartedUsers.valueAt(i);
19144            if (uss.mState != UserStartedState.STATE_STOPPING
19145                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19146                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19147                num++;
19148            }
19149        }
19150    }
19151
19152    @Override
19153    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19154        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19155                != PackageManager.PERMISSION_GRANTED) {
19156            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19157                    + Binder.getCallingPid()
19158                    + ", uid=" + Binder.getCallingUid()
19159                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19160            Slog.w(TAG, msg);
19161            throw new SecurityException(msg);
19162        }
19163
19164        mUserSwitchObservers.register(observer);
19165    }
19166
19167    @Override
19168    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19169        mUserSwitchObservers.unregister(observer);
19170    }
19171
19172    private boolean userExists(int userId) {
19173        if (userId == 0) {
19174            return true;
19175        }
19176        UserManagerService ums = getUserManagerLocked();
19177        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19178    }
19179
19180    int[] getUsersLocked() {
19181        UserManagerService ums = getUserManagerLocked();
19182        return ums != null ? ums.getUserIds() : new int[] { 0 };
19183    }
19184
19185    UserManagerService getUserManagerLocked() {
19186        if (mUserManager == null) {
19187            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19188            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19189        }
19190        return mUserManager;
19191    }
19192
19193    private int applyUserId(int uid, int userId) {
19194        return UserHandle.getUid(userId, uid);
19195    }
19196
19197    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19198        if (info == null) return null;
19199        ApplicationInfo newInfo = new ApplicationInfo(info);
19200        newInfo.uid = applyUserId(info.uid, userId);
19201        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19202                + info.packageName;
19203        return newInfo;
19204    }
19205
19206    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19207        if (aInfo == null
19208                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19209            return aInfo;
19210        }
19211
19212        ActivityInfo info = new ActivityInfo(aInfo);
19213        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19214        return info;
19215    }
19216
19217    private final class LocalService extends ActivityManagerInternal {
19218        @Override
19219        public void goingToSleep() {
19220            ActivityManagerService.this.goingToSleep();
19221        }
19222
19223        @Override
19224        public void wakingUp() {
19225            ActivityManagerService.this.wakingUp();
19226        }
19227
19228        @Override
19229        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19230                String processName, String abiOverride, int uid, Runnable crashHandler) {
19231            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19232                    processName, abiOverride, uid, crashHandler);
19233        }
19234    }
19235
19236    /**
19237     * An implementation of IAppTask, that allows an app to manage its own tasks via
19238     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19239     * only the process that calls getAppTasks() can call the AppTask methods.
19240     */
19241    class AppTaskImpl extends IAppTask.Stub {
19242        private int mTaskId;
19243        private int mCallingUid;
19244
19245        public AppTaskImpl(int taskId, int callingUid) {
19246            mTaskId = taskId;
19247            mCallingUid = callingUid;
19248        }
19249
19250        private void checkCaller() {
19251            if (mCallingUid != Binder.getCallingUid()) {
19252                throw new SecurityException("Caller " + mCallingUid
19253                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19254            }
19255        }
19256
19257        @Override
19258        public void finishAndRemoveTask() {
19259            checkCaller();
19260
19261            synchronized (ActivityManagerService.this) {
19262                long origId = Binder.clearCallingIdentity();
19263                try {
19264                    if (!removeTaskByIdLocked(mTaskId, false)) {
19265                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19266                    }
19267                } finally {
19268                    Binder.restoreCallingIdentity(origId);
19269                }
19270            }
19271        }
19272
19273        @Override
19274        public ActivityManager.RecentTaskInfo getTaskInfo() {
19275            checkCaller();
19276
19277            synchronized (ActivityManagerService.this) {
19278                long origId = Binder.clearCallingIdentity();
19279                try {
19280                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19281                    if (tr == null) {
19282                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19283                    }
19284                    return createRecentTaskInfoFromTaskRecord(tr);
19285                } finally {
19286                    Binder.restoreCallingIdentity(origId);
19287                }
19288            }
19289        }
19290
19291        @Override
19292        public void moveToFront() {
19293            checkCaller();
19294
19295            final TaskRecord tr;
19296            synchronized (ActivityManagerService.this) {
19297                tr = recentTaskForIdLocked(mTaskId);
19298                if (tr == null) {
19299                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19300                }
19301                if (tr.getRootActivity() != null) {
19302                    moveTaskToFrontLocked(tr.taskId, 0, null);
19303                    return;
19304                }
19305            }
19306
19307            startActivityFromRecentsInner(tr.taskId, null);
19308        }
19309
19310        @Override
19311        public int startActivity(IBinder whoThread, String callingPackage,
19312                Intent intent, String resolvedType, Bundle options) {
19313            checkCaller();
19314
19315            int callingUser = UserHandle.getCallingUserId();
19316            TaskRecord tr;
19317            IApplicationThread appThread;
19318            synchronized (ActivityManagerService.this) {
19319                tr = recentTaskForIdLocked(mTaskId);
19320                if (tr == null) {
19321                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19322                }
19323                appThread = ApplicationThreadNative.asInterface(whoThread);
19324                if (appThread == null) {
19325                    throw new IllegalArgumentException("Bad app thread " + appThread);
19326                }
19327            }
19328            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19329                    resolvedType, null, null, null, null, 0, 0, null, null,
19330                    null, options, callingUser, null, tr);
19331        }
19332
19333        @Override
19334        public void setExcludeFromRecents(boolean exclude) {
19335            checkCaller();
19336
19337            synchronized (ActivityManagerService.this) {
19338                long origId = Binder.clearCallingIdentity();
19339                try {
19340                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19341                    if (tr == null) {
19342                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19343                    }
19344                    Intent intent = tr.getBaseIntent();
19345                    if (exclude) {
19346                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19347                    } else {
19348                        intent.setFlags(intent.getFlags()
19349                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19350                    }
19351                } finally {
19352                    Binder.restoreCallingIdentity(origId);
19353                }
19354            }
19355        }
19356    }
19357}
19358