ActivityManagerService.java revision 6edb5c665dcb024ae7cfb95b9a92e30dcc5777c1
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.UserManagerService;
85import com.android.server.wm.AppTransition;
86import com.android.server.wm.WindowManagerService;
87import com.google.android.collect.Lists;
88import com.google.android.collect.Maps;
89
90import libcore.io.IoUtils;
91
92import org.xmlpull.v1.XmlPullParser;
93import org.xmlpull.v1.XmlPullParserException;
94import org.xmlpull.v1.XmlSerializer;
95
96import android.app.Activity;
97import android.app.ActivityManager;
98import android.app.ActivityManager.RunningTaskInfo;
99import android.app.ActivityManager.StackInfo;
100import android.app.ActivityManagerInternal;
101import android.app.ActivityManagerNative;
102import android.app.ActivityOptions;
103import android.app.ActivityThread;
104import android.app.AlertDialog;
105import android.app.AppGlobals;
106import android.app.ApplicationErrorReport;
107import android.app.Dialog;
108import android.app.IActivityController;
109import android.app.IApplicationThread;
110import android.app.IInstrumentationWatcher;
111import android.app.INotificationManager;
112import android.app.IProcessObserver;
113import android.app.IServiceConnection;
114import android.app.IStopUserCallback;
115import android.app.IUiAutomationConnection;
116import android.app.IUserSwitchObserver;
117import android.app.Instrumentation;
118import android.app.Notification;
119import android.app.NotificationManager;
120import android.app.PendingIntent;
121import android.app.backup.IBackupManager;
122import android.content.ActivityNotFoundException;
123import android.content.BroadcastReceiver;
124import android.content.ClipData;
125import android.content.ComponentCallbacks2;
126import android.content.ComponentName;
127import android.content.ContentProvider;
128import android.content.ContentResolver;
129import android.content.Context;
130import android.content.DialogInterface;
131import android.content.IContentProvider;
132import android.content.IIntentReceiver;
133import android.content.IIntentSender;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.ConfigurationInfo;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageManager;
142import android.content.pm.InstrumentationInfo;
143import android.content.pm.PackageInfo;
144import android.content.pm.PackageManager;
145import android.content.pm.ParceledListSlice;
146import android.content.pm.UserInfo;
147import android.content.pm.PackageManager.NameNotFoundException;
148import android.content.pm.PathPermission;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.res.CompatibilityInfo;
153import android.content.res.Configuration;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IRemoteCallback;
170import android.os.IUserManager;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.Process;
176import android.os.RemoteCallbackList;
177import android.os.RemoteException;
178import android.os.SELinux;
179import android.os.ServiceManager;
180import android.os.StrictMode;
181import android.os.SystemClock;
182import android.os.SystemProperties;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.provider.Settings;
187import android.text.format.DateUtils;
188import android.text.format.Time;
189import android.util.AtomicFile;
190import android.util.EventLog;
191import android.util.Log;
192import android.util.Pair;
193import android.util.PrintWriterPrinter;
194import android.util.Slog;
195import android.util.SparseArray;
196import android.util.TimeUtils;
197import android.util.Xml;
198import android.view.Gravity;
199import android.view.LayoutInflater;
200import android.view.View;
201import android.view.WindowManager;
202import dalvik.system.VMRuntime;
203
204import java.io.BufferedInputStream;
205import java.io.BufferedOutputStream;
206import java.io.DataInputStream;
207import java.io.DataOutputStream;
208import java.io.File;
209import java.io.FileDescriptor;
210import java.io.FileInputStream;
211import java.io.FileNotFoundException;
212import java.io.FileOutputStream;
213import java.io.IOException;
214import java.io.InputStreamReader;
215import java.io.PrintWriter;
216import java.io.StringWriter;
217import java.lang.ref.WeakReference;
218import java.util.ArrayList;
219import java.util.Arrays;
220import java.util.Collections;
221import java.util.Comparator;
222import java.util.HashMap;
223import java.util.HashSet;
224import java.util.Iterator;
225import java.util.List;
226import java.util.Locale;
227import java.util.Map;
228import java.util.Set;
229import java.util.concurrent.atomic.AtomicBoolean;
230import java.util.concurrent.atomic.AtomicLong;
231
232public final class ActivityManagerService extends ActivityManagerNative
233        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
234
235    private static final String USER_DATA_DIR = "/data/user/";
236    // File that stores last updated system version and called preboot receivers
237    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
238
239    static final String TAG = "ActivityManager";
240    static final String TAG_MU = "ActivityManagerServiceMU";
241    static final boolean DEBUG = false;
242    static final boolean localLOGV = DEBUG;
243    static final boolean DEBUG_BACKUP = localLOGV || false;
244    static final boolean DEBUG_BROADCAST = localLOGV || false;
245    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
246    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_CLEANUP = localLOGV || false;
248    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
249    static final boolean DEBUG_FOCUS = false;
250    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
251    static final boolean DEBUG_MU = localLOGV || false;
252    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
253    static final boolean DEBUG_LRU = localLOGV || false;
254    static final boolean DEBUG_PAUSE = localLOGV || false;
255    static final boolean DEBUG_POWER = localLOGV || false;
256    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
257    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
258    static final boolean DEBUG_PROCESSES = localLOGV || false;
259    static final boolean DEBUG_PROVIDER = localLOGV || false;
260    static final boolean DEBUG_RESULTS = localLOGV || false;
261    static final boolean DEBUG_SERVICE = localLOGV || false;
262    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
263    static final boolean DEBUG_STACK = localLOGV || false;
264    static final boolean DEBUG_SWITCH = localLOGV || false;
265    static final boolean DEBUG_TASKS = localLOGV || false;
266    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
267    static final boolean DEBUG_TRANSITION = localLOGV || false;
268    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
269    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
270    static final boolean DEBUG_VISBILITY = localLOGV || false;
271    static final boolean DEBUG_PSS = localLOGV || false;
272    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
273    static final boolean DEBUG_RECENTS = localLOGV || false;
274    static final boolean VALIDATE_TOKENS = false;
275    static final boolean SHOW_ACTIVITY_START_TIME = true;
276
277    // Control over CPU and battery monitoring.
278    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
279    static final boolean MONITOR_CPU_USAGE = true;
280    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
281    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
282    static final boolean MONITOR_THREAD_CPU_USAGE = false;
283
284    // The flags that are set for all calls we make to the package manager.
285    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
286
287    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
288
289    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
290
291    // Maximum number recent bitmaps to keep in memory.
292    static final int MAX_RECENT_BITMAPS = 5;
293
294    // Amount of time after a call to stopAppSwitches() during which we will
295    // prevent further untrusted switches from happening.
296    static final long APP_SWITCH_DELAY_TIME = 5*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real.
300    static final int PROC_START_TIMEOUT = 10*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real, when the process was
304    // started with a wrapper for instrumentation (such as Valgrind) because it
305    // could take much longer than usual.
306    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
307
308    // How long to wait after going idle before forcing apps to GC.
309    static final int GC_TIMEOUT = 5*1000;
310
311    // The minimum amount of time between successive GC requests for a process.
312    static final int GC_MIN_INTERVAL = 60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process.
315    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process
318    // when the request is due to the memory state being lowered.
319    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
320
321    // The rate at which we check for apps using excessive power -- 15 mins.
322    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on wake locks to start killing things.
326    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on CPU usage to start killing things.
330    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // How long we allow a receiver to run before giving up on it.
333    static final int BROADCAST_FG_TIMEOUT = 10*1000;
334    static final int BROADCAST_BG_TIMEOUT = 60*1000;
335
336    // How long we wait until we timeout on key dispatching.
337    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
338
339    // How long we wait until we timeout on key dispatching during instrumentation.
340    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
341
342    // Amount of time we wait for observers to handle a user switch before
343    // giving up on them and unfreezing the screen.
344    static final int USER_SWITCH_TIMEOUT = 2*1000;
345
346    // Maximum number of users we allow to be running at a time.
347    static final int MAX_RUNNING_USERS = 3;
348
349    // How long to wait in getAssistContextExtras for the activity and foreground services
350    // to respond with the result.
351    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
352
353    // Maximum number of persisted Uri grants a package is allowed
354    static final int MAX_PERSISTED_URI_GRANTS = 128;
355
356    static final int MY_PID = Process.myPid();
357
358    static final String[] EMPTY_STRING_ARRAY = new String[0];
359
360    // How many bytes to write into the dropbox log before truncating
361    static final int DROPBOX_MAX_SIZE = 256 * 1024;
362
363    // Access modes for handleIncomingUser.
364    static final int ALLOW_NON_FULL = 0;
365    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
366    static final int ALLOW_FULL_ONLY = 2;
367
368    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
369
370    /** All system services */
371    SystemServiceManager mSystemServiceManager;
372
373    /** Run all ActivityStacks through this */
374    ActivityStackSupervisor mStackSupervisor;
375
376    public IntentFirewall mIntentFirewall;
377
378    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
379    // default actuion automatically.  Important for devices without direct input
380    // devices.
381    private boolean mShowDialogs = true;
382
383    BroadcastQueue mFgBroadcastQueue;
384    BroadcastQueue mBgBroadcastQueue;
385    // Convenient for easy iteration over the queues. Foreground is first
386    // so that dispatch of foreground broadcasts gets precedence.
387    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
388
389    BroadcastQueue broadcastQueueForIntent(Intent intent) {
390        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
391        if (DEBUG_BACKGROUND_BROADCAST) {
392            Slog.i(TAG, "Broadcast intent " + intent + " on "
393                    + (isFg ? "foreground" : "background")
394                    + " queue");
395        }
396        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
397    }
398
399    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
400        for (BroadcastQueue queue : mBroadcastQueues) {
401            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
402            if (r != null) {
403                return r;
404            }
405        }
406        return null;
407    }
408
409    /**
410     * Activity we have told the window manager to have key focus.
411     */
412    ActivityRecord mFocusedActivity = null;
413
414    /**
415     * List of intents that were used to start the most recent tasks.
416     */
417    ArrayList<TaskRecord> mRecentTasks;
418    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    public class PendingAssistExtras extends Binder implements Runnable {
436        public final ActivityRecord activity;
437        public final Bundle extras;
438        public final Intent intent;
439        public final String hint;
440        public final int userHandle;
441        public boolean haveResult = false;
442        public Bundle result = null;
443        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
444                String _hint, int _userHandle) {
445            activity = _activity;
446            extras = _extras;
447            intent = _intent;
448            hint = _hint;
449            userHandle = _userHandle;
450        }
451        @Override
452        public void run() {
453            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
454            synchronized (this) {
455                haveResult = true;
456                notifyAll();
457            }
458        }
459    }
460
461    final ArrayList<PendingAssistExtras> mPendingAssistExtras
462            = new ArrayList<PendingAssistExtras>();
463
464    /**
465     * Process management.
466     */
467    final ProcessList mProcessList = new ProcessList();
468
469    /**
470     * All of the applications we currently have running organized by name.
471     * The keys are strings of the application package name (as
472     * returned by the package manager), and the keys are ApplicationRecord
473     * objects.
474     */
475    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
476
477    /**
478     * Tracking long-term execution of processes to look for abuse and other
479     * bad app behavior.
480     */
481    final ProcessStatsService mProcessStats;
482
483    /**
484     * The currently running isolated processes.
485     */
486    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
487
488    /**
489     * Counter for assigning isolated process uids, to avoid frequently reusing the
490     * same ones.
491     */
492    int mNextIsolatedProcessUid = 0;
493
494    /**
495     * The currently running heavy-weight process, if any.
496     */
497    ProcessRecord mHeavyWeightProcess = null;
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Information about a process that is currently marked as bad.
506     */
507    static final class BadProcessInfo {
508        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
509            this.time = time;
510            this.shortMsg = shortMsg;
511            this.longMsg = longMsg;
512            this.stack = stack;
513        }
514
515        final long time;
516        final String shortMsg;
517        final String longMsg;
518        final String stack;
519    }
520
521    /**
522     * Set of applications that we consider to be bad, and will reject
523     * incoming broadcasts from (which the user has no control over).
524     * Processes are added to this set when they have crashed twice within
525     * a minimum amount of time; they are removed from it when they are
526     * later restarted (hopefully due to some user action).  The value is the
527     * time it was added to the list.
528     */
529    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
530
531    /**
532     * All of the processes we currently have running organized by pid.
533     * The keys are the pid running the application.
534     *
535     * <p>NOTE: This object is protected by its own lock, NOT the global
536     * activity manager lock!
537     */
538    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
539
540    /**
541     * All of the processes that have been forced to be foreground.  The key
542     * is the pid of the caller who requested it (we hold a death
543     * link on it).
544     */
545    abstract class ForegroundToken implements IBinder.DeathRecipient {
546        int pid;
547        IBinder token;
548    }
549    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
550
551    /**
552     * List of records for processes that someone had tried to start before the
553     * system was ready.  We don't start them at that point, but ensure they
554     * are started by the time booting is complete.
555     */
556    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of persistent applications that are in the process
560     * of being started.
561     */
562    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes that are being forcibly torn down.
566     */
567    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * List of running applications, sorted by recent usage.
571     * The first entry in the list is the least recently used.
572     */
573    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Where in mLruProcesses that the processes hosting activities start.
577     */
578    int mLruProcessActivityStart = 0;
579
580    /**
581     * Where in mLruProcesses that the processes hosting services start.
582     * This is after (lower index) than mLruProcessesActivityStart.
583     */
584    int mLruProcessServiceStart = 0;
585
586    /**
587     * List of processes that should gc as soon as things are idle.
588     */
589    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
590
591    /**
592     * Processes we want to collect PSS data from.
593     */
594    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Last time we requested PSS data of all processes.
598     */
599    long mLastFullPssTime = SystemClock.uptimeMillis();
600
601    /**
602     * If set, the next time we collect PSS data we should do a full collection
603     * with data from native processes and the kernel.
604     */
605    boolean mFullPssPending = false;
606
607    /**
608     * This is the process holding what we currently consider to be
609     * the "home" activity.
610     */
611    ProcessRecord mHomeProcess;
612
613    /**
614     * This is the process holding the activity the user last visited that
615     * is in a different process from the one they are currently in.
616     */
617    ProcessRecord mPreviousProcess;
618
619    /**
620     * The time at which the previous process was last visible.
621     */
622    long mPreviousProcessVisibleTime;
623
624    /**
625     * Which uses have been started, so are allowed to run code.
626     */
627    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
628
629    /**
630     * LRU list of history of current users.  Most recently current is at the end.
631     */
632    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
633
634    /**
635     * Constant array of the users that are currently started.
636     */
637    int[] mStartedUserArray = new int[] { 0 };
638
639    /**
640     * Registered observers of the user switching mechanics.
641     */
642    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
643            = new RemoteCallbackList<IUserSwitchObserver>();
644
645    /**
646     * Currently active user switch.
647     */
648    Object mCurUserSwitchCallback;
649
650    /**
651     * Packages that the user has asked to have run in screen size
652     * compatibility mode instead of filling the screen.
653     */
654    final CompatModePackages mCompatModePackages;
655
656    /**
657     * Set of IntentSenderRecord objects that are currently active.
658     */
659    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
660            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
661
662    /**
663     * Fingerprints (hashCode()) of stack traces that we've
664     * already logged DropBox entries for.  Guarded by itself.  If
665     * something (rogue user app) forces this over
666     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
667     */
668    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
669    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
670
671    /**
672     * Strict Mode background batched logging state.
673     *
674     * The string buffer is guarded by itself, and its lock is also
675     * used to determine if another batched write is already
676     * in-flight.
677     */
678    private final StringBuilder mStrictModeBuffer = new StringBuilder();
679
680    /**
681     * Keeps track of all IIntentReceivers that have been registered for
682     * broadcasts.  Hash keys are the receiver IBinder, hash value is
683     * a ReceiverList.
684     */
685    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
686            new HashMap<IBinder, ReceiverList>();
687
688    /**
689     * Resolver for broadcast intents to registered receivers.
690     * Holds BroadcastFilter (subclass of IntentFilter).
691     */
692    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
693            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
694        @Override
695        protected boolean allowFilterResult(
696                BroadcastFilter filter, List<BroadcastFilter> dest) {
697            IBinder target = filter.receiverList.receiver.asBinder();
698            for (int i=dest.size()-1; i>=0; i--) {
699                if (dest.get(i).receiverList.receiver.asBinder() == target) {
700                    return false;
701                }
702            }
703            return true;
704        }
705
706        @Override
707        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
708            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
709                    || userId == filter.owningUserId) {
710                return super.newResult(filter, match, userId);
711            }
712            return null;
713        }
714
715        @Override
716        protected BroadcastFilter[] newArray(int size) {
717            return new BroadcastFilter[size];
718        }
719
720        @Override
721        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
722            return packageName.equals(filter.packageName);
723        }
724    };
725
726    /**
727     * State of all active sticky broadcasts per user.  Keys are the action of the
728     * sticky Intent, values are an ArrayList of all broadcasted intents with
729     * that action (which should usually be one).  The SparseArray is keyed
730     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
731     * for stickies that are sent to all users.
732     */
733    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
734            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
735
736    final ActiveServices mServices;
737
738    /**
739     * Backup/restore process management
740     */
741    String mBackupAppName = null;
742    BackupRecord mBackupTarget = null;
743
744    final ProviderMap mProviderMap;
745
746    /**
747     * List of content providers who have clients waiting for them.  The
748     * application is currently being launched and the provider will be
749     * removed from this list once it is published.
750     */
751    final ArrayList<ContentProviderRecord> mLaunchingProviders
752            = new ArrayList<ContentProviderRecord>();
753
754    /**
755     * File storing persisted {@link #mGrantedUriPermissions}.
756     */
757    private final AtomicFile mGrantFile;
758
759    /** XML constants used in {@link #mGrantFile} */
760    private static final String TAG_URI_GRANTS = "uri-grants";
761    private static final String TAG_URI_GRANT = "uri-grant";
762    private static final String ATTR_USER_HANDLE = "userHandle";
763    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
764    private static final String ATTR_TARGET_USER_ID = "targetUserId";
765    private static final String ATTR_SOURCE_PKG = "sourcePkg";
766    private static final String ATTR_TARGET_PKG = "targetPkg";
767    private static final String ATTR_URI = "uri";
768    private static final String ATTR_MODE_FLAGS = "modeFlags";
769    private static final String ATTR_CREATED_TIME = "createdTime";
770    private static final String ATTR_PREFIX = "prefix";
771
772    /**
773     * Global set of specific {@link Uri} permissions that have been granted.
774     * This optimized lookup structure maps from {@link UriPermission#targetUid}
775     * to {@link UriPermission#uri} to {@link UriPermission}.
776     */
777    @GuardedBy("this")
778    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
779            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
780
781    public static class GrantUri {
782        public final int sourceUserId;
783        public final Uri uri;
784        public boolean prefix;
785
786        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
787            this.sourceUserId = sourceUserId;
788            this.uri = uri;
789            this.prefix = prefix;
790        }
791
792        @Override
793        public int hashCode() {
794            return toString().hashCode();
795        }
796
797        @Override
798        public boolean equals(Object o) {
799            if (o instanceof GrantUri) {
800                GrantUri other = (GrantUri) o;
801                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
802                        && prefix == other.prefix;
803            }
804            return false;
805        }
806
807        @Override
808        public String toString() {
809            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
810            if (prefix) result += " [prefix]";
811            return result;
812        }
813
814        public String toSafeString() {
815            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
816            if (prefix) result += " [prefix]";
817            return result;
818        }
819
820        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
821            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
822                    ContentProvider.getUriWithoutUserId(uri), false);
823        }
824    }
825
826    CoreSettingsObserver mCoreSettingsObserver;
827
828    /**
829     * Thread-local storage used to carry caller permissions over through
830     * indirect content-provider access.
831     */
832    private class Identity {
833        public int pid;
834        public int uid;
835
836        Identity(int _pid, int _uid) {
837            pid = _pid;
838            uid = _uid;
839        }
840    }
841
842    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
843
844    /**
845     * All information we have collected about the runtime performance of
846     * any user id that can impact battery performance.
847     */
848    final BatteryStatsService mBatteryStatsService;
849
850    /**
851     * Information about component usage
852     */
853    UsageStatsManagerInternal mUsageStatsService;
854
855    /**
856     * Information about and control over application operations
857     */
858    final AppOpsService mAppOpsService;
859
860    /**
861     * Save recent tasks information across reboots.
862     */
863    final TaskPersister mTaskPersister;
864
865    /**
866     * Current configuration information.  HistoryRecord objects are given
867     * a reference to this object to indicate which configuration they are
868     * currently running in, so this object must be kept immutable.
869     */
870    Configuration mConfiguration = new Configuration();
871
872    /**
873     * Current sequencing integer of the configuration, for skipping old
874     * configurations.
875     */
876    int mConfigurationSeq = 0;
877
878    /**
879     * Hardware-reported OpenGLES version.
880     */
881    final int GL_ES_VERSION;
882
883    /**
884     * List of initialization arguments to pass to all processes when binding applications to them.
885     * For example, references to the commonly used services.
886     */
887    HashMap<String, IBinder> mAppBindArgs;
888
889    /**
890     * Temporary to avoid allocations.  Protected by main lock.
891     */
892    final StringBuilder mStringBuilder = new StringBuilder(256);
893
894    /**
895     * Used to control how we initialize the service.
896     */
897    ComponentName mTopComponent;
898    String mTopAction = Intent.ACTION_MAIN;
899    String mTopData;
900    boolean mProcessesReady = false;
901    boolean mSystemReady = false;
902    boolean mBooting = false;
903    boolean mCallFinishBooting = false;
904    boolean mBootAnimationComplete = false;
905    boolean mWaitingUpdate = false;
906    boolean mDidUpdate = false;
907    boolean mOnBattery = false;
908    boolean mLaunchWarningShown = false;
909
910    Context mContext;
911
912    int mFactoryTest;
913
914    boolean mCheckedForSetup;
915
916    /**
917     * The time at which we will allow normal application switches again,
918     * after a call to {@link #stopAppSwitches()}.
919     */
920    long mAppSwitchesAllowedTime;
921
922    /**
923     * This is set to true after the first switch after mAppSwitchesAllowedTime
924     * is set; any switches after that will clear the time.
925     */
926    boolean mDidAppSwitch;
927
928    /**
929     * Last time (in realtime) at which we checked for power usage.
930     */
931    long mLastPowerCheckRealtime;
932
933    /**
934     * Last time (in uptime) at which we checked for power usage.
935     */
936    long mLastPowerCheckUptime;
937
938    /**
939     * Set while we are wanting to sleep, to prevent any
940     * activities from being started/resumed.
941     */
942    private boolean mSleeping = false;
943
944    /**
945     * Set while we are running a voice interaction.  This overrides
946     * sleeping while it is active.
947     */
948    private boolean mRunningVoice = false;
949
950    /**
951     * State of external calls telling us if the device is asleep.
952     */
953    private boolean mWentToSleep = false;
954
955    /**
956     * State of external call telling us if the lock screen is shown.
957     */
958    private boolean mLockScreenShown = false;
959
960    /**
961     * Set if we are shutting down the system, similar to sleeping.
962     */
963    boolean mShuttingDown = false;
964
965    /**
966     * Current sequence id for oom_adj computation traversal.
967     */
968    int mAdjSeq = 0;
969
970    /**
971     * Current sequence id for process LRU updating.
972     */
973    int mLruSeq = 0;
974
975    /**
976     * Keep track of the non-cached/empty process we last found, to help
977     * determine how to distribute cached/empty processes next time.
978     */
979    int mNumNonCachedProcs = 0;
980
981    /**
982     * Keep track of the number of cached hidden procs, to balance oom adj
983     * distribution between those and empty procs.
984     */
985    int mNumCachedHiddenProcs = 0;
986
987    /**
988     * Keep track of the number of service processes we last found, to
989     * determine on the next iteration which should be B services.
990     */
991    int mNumServiceProcs = 0;
992    int mNewNumAServiceProcs = 0;
993    int mNewNumServiceProcs = 0;
994
995    /**
996     * Allow the current computed overall memory level of the system to go down?
997     * This is set to false when we are killing processes for reasons other than
998     * memory management, so that the now smaller process list will not be taken as
999     * an indication that memory is tighter.
1000     */
1001    boolean mAllowLowerMemLevel = false;
1002
1003    /**
1004     * The last computed memory level, for holding when we are in a state that
1005     * processes are going away for other reasons.
1006     */
1007    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1008
1009    /**
1010     * The last total number of process we have, to determine if changes actually look
1011     * like a shrinking number of process due to lower RAM.
1012     */
1013    int mLastNumProcesses;
1014
1015    /**
1016     * The uptime of the last time we performed idle maintenance.
1017     */
1018    long mLastIdleTime = SystemClock.uptimeMillis();
1019
1020    /**
1021     * Total time spent with RAM that has been added in the past since the last idle time.
1022     */
1023    long mLowRamTimeSinceLastIdle = 0;
1024
1025    /**
1026     * If RAM is currently low, when that horrible situation started.
1027     */
1028    long mLowRamStartTime = 0;
1029
1030    /**
1031     * For reporting to battery stats the current top application.
1032     */
1033    private String mCurResumedPackage = null;
1034    private int mCurResumedUid = -1;
1035
1036    /**
1037     * For reporting to battery stats the apps currently running foreground
1038     * service.  The ProcessMap is package/uid tuples; each of these contain
1039     * an array of the currently foreground processes.
1040     */
1041    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1042            = new ProcessMap<ArrayList<ProcessRecord>>();
1043
1044    /**
1045     * This is set if we had to do a delayed dexopt of an app before launching
1046     * it, to increase the ANR timeouts in that case.
1047     */
1048    boolean mDidDexOpt;
1049
1050    /**
1051     * Set if the systemServer made a call to enterSafeMode.
1052     */
1053    boolean mSafeMode;
1054
1055    String mDebugApp = null;
1056    boolean mWaitForDebugger = false;
1057    boolean mDebugTransient = false;
1058    String mOrigDebugApp = null;
1059    boolean mOrigWaitForDebugger = false;
1060    boolean mAlwaysFinishActivities = false;
1061    IActivityController mController = null;
1062    String mProfileApp = null;
1063    ProcessRecord mProfileProc = null;
1064    String mProfileFile;
1065    ParcelFileDescriptor mProfileFd;
1066    int mSamplingInterval = 0;
1067    boolean mAutoStopProfiler = false;
1068    int mProfileType = 0;
1069    String mOpenGlTraceApp = null;
1070
1071    static class ProcessChangeItem {
1072        static final int CHANGE_ACTIVITIES = 1<<0;
1073        static final int CHANGE_PROCESS_STATE = 1<<1;
1074        int changes;
1075        int uid;
1076        int pid;
1077        int processState;
1078        boolean foregroundActivities;
1079    }
1080
1081    final RemoteCallbackList<IProcessObserver> mProcessObservers
1082            = new RemoteCallbackList<IProcessObserver>();
1083    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1084
1085    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1086            = new ArrayList<ProcessChangeItem>();
1087    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1088            = new ArrayList<ProcessChangeItem>();
1089
1090    /**
1091     * Runtime CPU use collection thread.  This object's lock is used to
1092     * perform synchronization with the thread (notifying it to run).
1093     */
1094    final Thread mProcessCpuThread;
1095
1096    /**
1097     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1098     * Must acquire this object's lock when accessing it.
1099     * NOTE: this lock will be held while doing long operations (trawling
1100     * through all processes in /proc), so it should never be acquired by
1101     * any critical paths such as when holding the main activity manager lock.
1102     */
1103    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1104            MONITOR_THREAD_CPU_USAGE);
1105    final AtomicLong mLastCpuTime = new AtomicLong(0);
1106    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1107
1108    long mLastWriteTime = 0;
1109
1110    /**
1111     * Used to retain an update lock when the foreground activity is in
1112     * immersive mode.
1113     */
1114    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1115
1116    /**
1117     * Set to true after the system has finished booting.
1118     */
1119    boolean mBooted = false;
1120
1121    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1122    int mProcessLimitOverride = -1;
1123
1124    WindowManagerService mWindowManager;
1125
1126    final ActivityThread mSystemThread;
1127
1128    // Holds the current foreground user's id
1129    int mCurrentUserId = 0;
1130    // Holds the target user's id during a user switch
1131    int mTargetUserId = UserHandle.USER_NULL;
1132    // If there are multiple profiles for the current user, their ids are here
1133    // Currently only the primary user can have managed profiles
1134    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1135
1136    /**
1137     * Mapping from each known user ID to the profile group ID it is associated with.
1138     */
1139    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1140
1141    private UserManagerService mUserManager;
1142
1143    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1144        final ProcessRecord mApp;
1145        final int mPid;
1146        final IApplicationThread mAppThread;
1147
1148        AppDeathRecipient(ProcessRecord app, int pid,
1149                IApplicationThread thread) {
1150            if (localLOGV) Slog.v(
1151                TAG, "New death recipient " + this
1152                + " for thread " + thread.asBinder());
1153            mApp = app;
1154            mPid = pid;
1155            mAppThread = thread;
1156        }
1157
1158        @Override
1159        public void binderDied() {
1160            if (localLOGV) Slog.v(
1161                TAG, "Death received in " + this
1162                + " for thread " + mAppThread.asBinder());
1163            synchronized(ActivityManagerService.this) {
1164                appDiedLocked(mApp, mPid, mAppThread);
1165            }
1166        }
1167    }
1168
1169    static final int SHOW_ERROR_MSG = 1;
1170    static final int SHOW_NOT_RESPONDING_MSG = 2;
1171    static final int SHOW_FACTORY_ERROR_MSG = 3;
1172    static final int UPDATE_CONFIGURATION_MSG = 4;
1173    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1174    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1175    static final int SERVICE_TIMEOUT_MSG = 12;
1176    static final int UPDATE_TIME_ZONE = 13;
1177    static final int SHOW_UID_ERROR_MSG = 14;
1178    static final int IM_FEELING_LUCKY_MSG = 15;
1179    static final int PROC_START_TIMEOUT_MSG = 20;
1180    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1181    static final int KILL_APPLICATION_MSG = 22;
1182    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1183    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1184    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1185    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1186    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1187    static final int CLEAR_DNS_CACHE_MSG = 28;
1188    static final int UPDATE_HTTP_PROXY_MSG = 29;
1189    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1190    static final int DISPATCH_PROCESSES_CHANGED = 31;
1191    static final int DISPATCH_PROCESS_DIED = 32;
1192    static final int REPORT_MEM_USAGE_MSG = 33;
1193    static final int REPORT_USER_SWITCH_MSG = 34;
1194    static final int CONTINUE_USER_SWITCH_MSG = 35;
1195    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1196    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1197    static final int PERSIST_URI_GRANTS_MSG = 38;
1198    static final int REQUEST_ALL_PSS_MSG = 39;
1199    static final int START_PROFILES_MSG = 40;
1200    static final int UPDATE_TIME = 41;
1201    static final int SYSTEM_USER_START_MSG = 42;
1202    static final int SYSTEM_USER_CURRENT_MSG = 43;
1203    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1204    static final int FINISH_BOOTING_MSG = 45;
1205    static final int START_USER_SWITCH_MSG = 46;
1206    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1207
1208    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1209    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1210    static final int FIRST_COMPAT_MODE_MSG = 300;
1211    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1212
1213    AlertDialog mUidAlert;
1214    CompatModeDialog mCompatModeDialog;
1215    long mLastMemUsageReportTime = 0;
1216
1217    private LockToAppRequestDialog mLockToAppRequest;
1218
1219    /**
1220     * Flag whether the current user is a "monkey", i.e. whether
1221     * the UI is driven by a UI automation tool.
1222     */
1223    private boolean mUserIsMonkey;
1224
1225    /** Flag whether the device has a Recents UI */
1226    boolean mHasRecents;
1227
1228    /** The dimensions of the thumbnails in the Recents UI. */
1229    int mThumbnailWidth;
1230    int mThumbnailHeight;
1231
1232    final ServiceThread mHandlerThread;
1233    final MainHandler mHandler;
1234
1235    final class MainHandler extends Handler {
1236        public MainHandler(Looper looper) {
1237            super(looper, null, true);
1238        }
1239
1240        @Override
1241        public void handleMessage(Message msg) {
1242            switch (msg.what) {
1243            case SHOW_ERROR_MSG: {
1244                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1246                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1247                synchronized (ActivityManagerService.this) {
1248                    ProcessRecord proc = (ProcessRecord)data.get("app");
1249                    AppErrorResult res = (AppErrorResult) data.get("result");
1250                    if (proc != null && proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has crash dialog: " + proc);
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                        return;
1256                    }
1257                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1258                            >= Process.FIRST_APPLICATION_UID
1259                            && proc.pid != MY_PID);
1260                    for (int userId : mCurrentProfileIds) {
1261                        isBackground &= (proc.userId != userId);
1262                    }
1263                    if (isBackground && !showBackground) {
1264                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1265                        if (res != null) {
1266                            res.set(0);
1267                        }
1268                        return;
1269                    }
1270                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1271                        Dialog d = new AppErrorDialog(mContext,
1272                                ActivityManagerService.this, res, proc);
1273                        d.show();
1274                        proc.crashDialog = d;
1275                    } else {
1276                        // The device is asleep, so just pretend that the user
1277                        // saw a crash dialog and hit "force quit".
1278                        if (res != null) {
1279                            res.set(0);
1280                        }
1281                    }
1282                }
1283
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_NOT_RESPONDING_MSG: {
1287                synchronized (ActivityManagerService.this) {
1288                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1289                    ProcessRecord proc = (ProcessRecord)data.get("app");
1290                    if (proc != null && proc.anrDialog != null) {
1291                        Slog.e(TAG, "App already has anr dialog: " + proc);
1292                        return;
1293                    }
1294
1295                    Intent intent = new Intent("android.intent.action.ANR");
1296                    if (!mProcessesReady) {
1297                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1298                                | Intent.FLAG_RECEIVER_FOREGROUND);
1299                    }
1300                    broadcastIntentLocked(null, null, intent,
1301                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1302                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1303
1304                    if (mShowDialogs) {
1305                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1306                                mContext, proc, (ActivityRecord)data.get("activity"),
1307                                msg.arg1 != 0);
1308                        d.show();
1309                        proc.anrDialog = d;
1310                    } else {
1311                        // Just kill the app if there is no dialog to be shown.
1312                        killAppAtUsersRequest(proc, null);
1313                    }
1314                }
1315
1316                ensureBootCompleted();
1317            } break;
1318            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1319                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                synchronized (ActivityManagerService.this) {
1321                    ProcessRecord proc = (ProcessRecord) data.get("app");
1322                    if (proc == null) {
1323                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1324                        break;
1325                    }
1326                    if (proc.crashDialog != null) {
1327                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1328                        return;
1329                    }
1330                    AppErrorResult res = (AppErrorResult) data.get("result");
1331                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1332                        Dialog d = new StrictModeViolationDialog(mContext,
1333                                ActivityManagerService.this, res, proc);
1334                        d.show();
1335                        proc.crashDialog = d;
1336                    } else {
1337                        // The device is asleep, so just pretend that the user
1338                        // saw a crash dialog and hit "force quit".
1339                        res.set(0);
1340                    }
1341                }
1342                ensureBootCompleted();
1343            } break;
1344            case SHOW_FACTORY_ERROR_MSG: {
1345                Dialog d = new FactoryErrorDialog(
1346                    mContext, msg.getData().getCharSequence("msg"));
1347                d.show();
1348                ensureBootCompleted();
1349            } break;
1350            case UPDATE_CONFIGURATION_MSG: {
1351                final ContentResolver resolver = mContext.getContentResolver();
1352                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1353            } break;
1354            case GC_BACKGROUND_PROCESSES_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    performAppGcsIfAppropriateLocked();
1357                }
1358            } break;
1359            case WAIT_FOR_DEBUGGER_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    ProcessRecord app = (ProcessRecord)msg.obj;
1362                    if (msg.arg1 != 0) {
1363                        if (!app.waitedForDebugger) {
1364                            Dialog d = new AppWaitingForDebuggerDialog(
1365                                    ActivityManagerService.this,
1366                                    mContext, app);
1367                            app.waitDialog = d;
1368                            app.waitedForDebugger = true;
1369                            d.show();
1370                        }
1371                    } else {
1372                        if (app.waitDialog != null) {
1373                            app.waitDialog.dismiss();
1374                            app.waitDialog = null;
1375                        }
1376                    }
1377                }
1378            } break;
1379            case SERVICE_TIMEOUT_MSG: {
1380                if (mDidDexOpt) {
1381                    mDidDexOpt = false;
1382                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1383                    nmsg.obj = msg.obj;
1384                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1385                    return;
1386                }
1387                mServices.serviceTimeout((ProcessRecord)msg.obj);
1388            } break;
1389            case UPDATE_TIME_ZONE: {
1390                synchronized (ActivityManagerService.this) {
1391                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1392                        ProcessRecord r = mLruProcesses.get(i);
1393                        if (r.thread != null) {
1394                            try {
1395                                r.thread.updateTimeZone();
1396                            } catch (RemoteException ex) {
1397                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1398                            }
1399                        }
1400                    }
1401                }
1402            } break;
1403            case CLEAR_DNS_CACHE_MSG: {
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.clearDnsCache();
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1412                            }
1413                        }
1414                    }
1415                }
1416            } break;
1417            case UPDATE_HTTP_PROXY_MSG: {
1418                ProxyInfo proxy = (ProxyInfo)msg.obj;
1419                String host = "";
1420                String port = "";
1421                String exclList = "";
1422                Uri pacFileUrl = Uri.EMPTY;
1423                if (proxy != null) {
1424                    host = proxy.getHost();
1425                    port = Integer.toString(proxy.getPort());
1426                    exclList = proxy.getExclusionListAsString();
1427                    pacFileUrl = proxy.getPacFileUrl();
1428                }
1429                synchronized (ActivityManagerService.this) {
1430                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1431                        ProcessRecord r = mLruProcesses.get(i);
1432                        if (r.thread != null) {
1433                            try {
1434                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1435                            } catch (RemoteException ex) {
1436                                Slog.w(TAG, "Failed to update http proxy for: " +
1437                                        r.info.processName);
1438                            }
1439                        }
1440                    }
1441                }
1442            } break;
1443            case SHOW_UID_ERROR_MSG: {
1444                String title = "System UIDs Inconsistent";
1445                String text = "UIDs on the system are inconsistent, you need to wipe your"
1446                        + " data partition or your device will be unstable.";
1447                Log.e(TAG, title + ": " + text);
1448                if (mShowDialogs) {
1449                    // XXX This is a temporary dialog, no need to localize.
1450                    AlertDialog d = new BaseErrorDialog(mContext);
1451                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1452                    d.setCancelable(false);
1453                    d.setTitle(title);
1454                    d.setMessage(text);
1455                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1456                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1457                    mUidAlert = d;
1458                    d.show();
1459                }
1460            } break;
1461            case IM_FEELING_LUCKY_MSG: {
1462                if (mUidAlert != null) {
1463                    mUidAlert.dismiss();
1464                    mUidAlert = null;
1465                }
1466            } break;
1467            case PROC_START_TIMEOUT_MSG: {
1468                if (mDidDexOpt) {
1469                    mDidDexOpt = false;
1470                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1471                    nmsg.obj = msg.obj;
1472                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1473                    return;
1474                }
1475                ProcessRecord app = (ProcessRecord)msg.obj;
1476                synchronized (ActivityManagerService.this) {
1477                    processStartTimedOutLocked(app);
1478                }
1479            } break;
1480            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1483                }
1484            } break;
1485            case KILL_APPLICATION_MSG: {
1486                synchronized (ActivityManagerService.this) {
1487                    int appid = msg.arg1;
1488                    boolean restart = (msg.arg2 == 1);
1489                    Bundle bundle = (Bundle)msg.obj;
1490                    String pkg = bundle.getString("pkg");
1491                    String reason = bundle.getString("reason");
1492                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1493                            false, UserHandle.USER_ALL, reason);
1494                }
1495            } break;
1496            case FINALIZE_PENDING_INTENT_MSG: {
1497                ((PendingIntentRecord)msg.obj).completeFinalize();
1498            } break;
1499            case POST_HEAVY_NOTIFICATION_MSG: {
1500                INotificationManager inm = NotificationManager.getService();
1501                if (inm == null) {
1502                    return;
1503                }
1504
1505                ActivityRecord root = (ActivityRecord)msg.obj;
1506                ProcessRecord process = root.app;
1507                if (process == null) {
1508                    return;
1509                }
1510
1511                try {
1512                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1513                    String text = mContext.getString(R.string.heavy_weight_notification,
1514                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1515                    Notification notification = new Notification();
1516                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1517                    notification.when = 0;
1518                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1519                    notification.tickerText = text;
1520                    notification.defaults = 0; // please be quiet
1521                    notification.sound = null;
1522                    notification.vibrate = null;
1523                    notification.color = mContext.getResources().getColor(
1524                            com.android.internal.R.color.system_notification_accent_color);
1525                    notification.setLatestEventInfo(context, text,
1526                            mContext.getText(R.string.heavy_weight_notification_detail),
1527                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1528                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1529                                    new UserHandle(root.userId)));
1530
1531                    try {
1532                        int[] outId = new int[1];
1533                        inm.enqueueNotificationWithTag("android", "android", null,
1534                                R.string.heavy_weight_notification,
1535                                notification, outId, root.userId);
1536                    } catch (RuntimeException e) {
1537                        Slog.w(ActivityManagerService.TAG,
1538                                "Error showing notification for heavy-weight app", e);
1539                    } catch (RemoteException e) {
1540                    }
1541                } catch (NameNotFoundException e) {
1542                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1543                }
1544            } break;
1545            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1546                INotificationManager inm = NotificationManager.getService();
1547                if (inm == null) {
1548                    return;
1549                }
1550                try {
1551                    inm.cancelNotificationWithTag("android", null,
1552                            R.string.heavy_weight_notification,  msg.arg1);
1553                } catch (RuntimeException e) {
1554                    Slog.w(ActivityManagerService.TAG,
1555                            "Error canceling notification for service", e);
1556                } catch (RemoteException e) {
1557                }
1558            } break;
1559            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    checkExcessivePowerUsageLocked(true);
1562                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1563                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1564                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1565                }
1566            } break;
1567            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1568                synchronized (ActivityManagerService.this) {
1569                    ActivityRecord ar = (ActivityRecord)msg.obj;
1570                    if (mCompatModeDialog != null) {
1571                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1572                                ar.info.applicationInfo.packageName)) {
1573                            return;
1574                        }
1575                        mCompatModeDialog.dismiss();
1576                        mCompatModeDialog = null;
1577                    }
1578                    if (ar != null && false) {
1579                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1580                                ar.packageName)) {
1581                            int mode = mCompatModePackages.computeCompatModeLocked(
1582                                    ar.info.applicationInfo);
1583                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1584                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1585                                mCompatModeDialog = new CompatModeDialog(
1586                                        ActivityManagerService.this, mContext,
1587                                        ar.info.applicationInfo);
1588                                mCompatModeDialog.show();
1589                            }
1590                        }
1591                    }
1592                }
1593                break;
1594            }
1595            case DISPATCH_PROCESSES_CHANGED: {
1596                dispatchProcessesChanged();
1597                break;
1598            }
1599            case DISPATCH_PROCESS_DIED: {
1600                final int pid = msg.arg1;
1601                final int uid = msg.arg2;
1602                dispatchProcessDied(pid, uid);
1603                break;
1604            }
1605            case REPORT_MEM_USAGE_MSG: {
1606                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1607                Thread thread = new Thread() {
1608                    @Override public void run() {
1609                        reportMemUsage(memInfos);
1610                    }
1611                };
1612                thread.start();
1613                break;
1614            }
1615            case START_USER_SWITCH_MSG: {
1616                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1617                break;
1618            }
1619            case REPORT_USER_SWITCH_MSG: {
1620                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1621                break;
1622            }
1623            case CONTINUE_USER_SWITCH_MSG: {
1624                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1625                break;
1626            }
1627            case USER_SWITCH_TIMEOUT_MSG: {
1628                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1629                break;
1630            }
1631            case IMMERSIVE_MODE_LOCK_MSG: {
1632                final boolean nextState = (msg.arg1 != 0);
1633                if (mUpdateLock.isHeld() != nextState) {
1634                    if (DEBUG_IMMERSIVE) {
1635                        final ActivityRecord r = (ActivityRecord) msg.obj;
1636                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1637                    }
1638                    if (nextState) {
1639                        mUpdateLock.acquire();
1640                    } else {
1641                        mUpdateLock.release();
1642                    }
1643                }
1644                break;
1645            }
1646            case PERSIST_URI_GRANTS_MSG: {
1647                writeGrantedUriPermissions();
1648                break;
1649            }
1650            case REQUEST_ALL_PSS_MSG: {
1651                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1652                break;
1653            }
1654            case START_PROFILES_MSG: {
1655                synchronized (ActivityManagerService.this) {
1656                    startProfilesLocked();
1657                }
1658                break;
1659            }
1660            case UPDATE_TIME: {
1661                synchronized (ActivityManagerService.this) {
1662                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1663                        ProcessRecord r = mLruProcesses.get(i);
1664                        if (r.thread != null) {
1665                            try {
1666                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1667                            } catch (RemoteException ex) {
1668                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1669                            }
1670                        }
1671                    }
1672                }
1673                break;
1674            }
1675            case SYSTEM_USER_START_MSG: {
1676                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1677                        Integer.toString(msg.arg1), msg.arg1);
1678                mSystemServiceManager.startUser(msg.arg1);
1679                break;
1680            }
1681            case SYSTEM_USER_CURRENT_MSG: {
1682                mBatteryStatsService.noteEvent(
1683                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1684                        Integer.toString(msg.arg2), msg.arg2);
1685                mBatteryStatsService.noteEvent(
1686                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1687                        Integer.toString(msg.arg1), msg.arg1);
1688                mSystemServiceManager.switchUser(msg.arg1);
1689                mLockToAppRequest.clearPrompt();
1690                break;
1691            }
1692            case ENTER_ANIMATION_COMPLETE_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1695                    if (r != null && r.app != null && r.app.thread != null) {
1696                        try {
1697                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1698                        } catch (RemoteException e) {
1699                        }
1700                    }
1701                }
1702                break;
1703            }
1704            case FINISH_BOOTING_MSG: {
1705                if (msg.arg1 != 0) {
1706                    finishBooting();
1707                }
1708                if (msg.arg2 != 0) {
1709                    enableScreenAfterBoot();
1710                }
1711                break;
1712            }
1713            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1714                try {
1715                    Locale l = (Locale) msg.obj;
1716                    IBinder service = ServiceManager.getService("mount");
1717                    IMountService mountService = IMountService.Stub.asInterface(service);
1718                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1719                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1720                } catch (RemoteException e) {
1721                    Log.e(TAG, "Error storing locale for decryption UI", e);
1722                }
1723                break;
1724            }
1725            }
1726        }
1727    };
1728
1729    static final int COLLECT_PSS_BG_MSG = 1;
1730
1731    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1732        @Override
1733        public void handleMessage(Message msg) {
1734            switch (msg.what) {
1735            case COLLECT_PSS_BG_MSG: {
1736                long start = SystemClock.uptimeMillis();
1737                MemInfoReader memInfo = null;
1738                synchronized (ActivityManagerService.this) {
1739                    if (mFullPssPending) {
1740                        mFullPssPending = false;
1741                        memInfo = new MemInfoReader();
1742                    }
1743                }
1744                if (memInfo != null) {
1745                    updateCpuStatsNow();
1746                    long nativeTotalPss = 0;
1747                    synchronized (mProcessCpuTracker) {
1748                        final int N = mProcessCpuTracker.countStats();
1749                        for (int j=0; j<N; j++) {
1750                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1751                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1752                                // This is definitely an application process; skip it.
1753                                continue;
1754                            }
1755                            synchronized (mPidsSelfLocked) {
1756                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1757                                    // This is one of our own processes; skip it.
1758                                    continue;
1759                                }
1760                            }
1761                            nativeTotalPss += Debug.getPss(st.pid, null);
1762                        }
1763                    }
1764                    memInfo.readMemInfo();
1765                    synchronized (ActivityManagerService.this) {
1766                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1767                                + (SystemClock.uptimeMillis()-start) + "ms");
1768                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1769                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1770                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1771                    }
1772                }
1773
1774                int i=0, num=0;
1775                long[] tmp = new long[1];
1776                do {
1777                    ProcessRecord proc;
1778                    int procState;
1779                    int pid;
1780                    synchronized (ActivityManagerService.this) {
1781                        if (i >= mPendingPssProcesses.size()) {
1782                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1783                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1784                            mPendingPssProcesses.clear();
1785                            return;
1786                        }
1787                        proc = mPendingPssProcesses.get(i);
1788                        procState = proc.pssProcState;
1789                        if (proc.thread != null && procState == proc.setProcState) {
1790                            pid = proc.pid;
1791                        } else {
1792                            proc = null;
1793                            pid = 0;
1794                        }
1795                        i++;
1796                    }
1797                    if (proc != null) {
1798                        long pss = Debug.getPss(pid, tmp);
1799                        synchronized (ActivityManagerService.this) {
1800                            if (proc.thread != null && proc.setProcState == procState
1801                                    && proc.pid == pid) {
1802                                num++;
1803                                proc.lastPssTime = SystemClock.uptimeMillis();
1804                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1805                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1806                                        + ": " + pss + " lastPss=" + proc.lastPss
1807                                        + " state=" + ProcessList.makeProcStateString(procState));
1808                                if (proc.initialIdlePss == 0) {
1809                                    proc.initialIdlePss = pss;
1810                                }
1811                                proc.lastPss = pss;
1812                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1813                                    proc.lastCachedPss = pss;
1814                                }
1815                            }
1816                        }
1817                    }
1818                } while (true);
1819            }
1820            }
1821        }
1822    };
1823
1824    /**
1825     * Monitor for package changes and update our internal state.
1826     */
1827    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1828        @Override
1829        public void onPackageRemoved(String packageName, int uid) {
1830            // Remove all tasks with activities in the specified package from the list of recent tasks
1831            final int eventUserId = getChangingUserId();
1832            synchronized (ActivityManagerService.this) {
1833                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1834                    TaskRecord tr = mRecentTasks.get(i);
1835                    if (tr.userId != eventUserId) continue;
1836
1837                    ComponentName cn = tr.intent.getComponent();
1838                    if (cn != null && cn.getPackageName().equals(packageName)) {
1839                        // If the package name matches, remove the task and kill the process
1840                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1841                    }
1842                }
1843            }
1844        }
1845
1846        @Override
1847        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1848            onPackageModified(packageName);
1849            return true;
1850        }
1851
1852        @Override
1853        public void onPackageModified(String packageName) {
1854            final int eventUserId = getChangingUserId();
1855            final IPackageManager pm = AppGlobals.getPackageManager();
1856            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1857                    new ArrayList<Pair<Intent, Integer>>();
1858            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1859            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1860            // Copy the list of recent tasks so that we don't hold onto the lock on
1861            // ActivityManagerService for long periods while checking if components exist.
1862            synchronized (ActivityManagerService.this) {
1863                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1864                    TaskRecord tr = mRecentTasks.get(i);
1865                    if (tr.userId != eventUserId) continue;
1866
1867                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1868                }
1869            }
1870            // Check the recent tasks and filter out all tasks with components that no longer exist.
1871            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1872                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1873                ComponentName cn = p.first.getComponent();
1874                if (cn != null && cn.getPackageName().equals(packageName)) {
1875                    if (componentsKnownToExist.contains(cn)) {
1876                        // If we know that the component still exists in the package, then skip
1877                        continue;
1878                    }
1879                    try {
1880                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1881                        if (info != null) {
1882                            componentsKnownToExist.add(cn);
1883                        } else {
1884                            tasksToRemove.add(p.second);
1885                        }
1886                    } catch (RemoteException e) {
1887                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1888                    }
1889                }
1890            }
1891            // Prune all the tasks with removed components from the list of recent tasks
1892            synchronized (ActivityManagerService.this) {
1893                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1894                    // Remove the task but don't kill the process (since other components in that
1895                    // package may still be running and in the background)
1896                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1897                }
1898            }
1899        }
1900
1901        @Override
1902        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1903            // Force stop the specified packages
1904            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1905            if (packages != null) {
1906                for (String pkg : packages) {
1907                    synchronized (ActivityManagerService.this) {
1908                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1909                                userId, "finished booting")) {
1910                            return true;
1911                        }
1912                    }
1913                }
1914            }
1915            return false;
1916        }
1917    };
1918
1919    public void setSystemProcess() {
1920        try {
1921            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1922            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1923            ServiceManager.addService("meminfo", new MemBinder(this));
1924            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1925            ServiceManager.addService("dbinfo", new DbBinder(this));
1926            if (MONITOR_CPU_USAGE) {
1927                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1928            }
1929            ServiceManager.addService("permission", new PermissionController(this));
1930
1931            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1932                    "android", STOCK_PM_FLAGS);
1933            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1934
1935            synchronized (this) {
1936                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1937                app.persistent = true;
1938                app.pid = MY_PID;
1939                app.maxAdj = ProcessList.SYSTEM_ADJ;
1940                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1941                mProcessNames.put(app.processName, app.uid, app);
1942                synchronized (mPidsSelfLocked) {
1943                    mPidsSelfLocked.put(app.pid, app);
1944                }
1945                updateLruProcessLocked(app, false, null);
1946                updateOomAdjLocked();
1947            }
1948        } catch (PackageManager.NameNotFoundException e) {
1949            throw new RuntimeException(
1950                    "Unable to find android system package", e);
1951        }
1952    }
1953
1954    public void setWindowManager(WindowManagerService wm) {
1955        mWindowManager = wm;
1956        mStackSupervisor.setWindowManager(wm);
1957    }
1958
1959    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1960        mUsageStatsService = usageStatsManager;
1961    }
1962
1963    public void startObservingNativeCrashes() {
1964        final NativeCrashListener ncl = new NativeCrashListener(this);
1965        ncl.start();
1966    }
1967
1968    public IAppOpsService getAppOpsService() {
1969        return mAppOpsService;
1970    }
1971
1972    static class MemBinder extends Binder {
1973        ActivityManagerService mActivityManagerService;
1974        MemBinder(ActivityManagerService activityManagerService) {
1975            mActivityManagerService = activityManagerService;
1976        }
1977
1978        @Override
1979        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1980            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1981                    != PackageManager.PERMISSION_GRANTED) {
1982                pw.println("Permission Denial: can't dump meminfo from from pid="
1983                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1984                        + " without permission " + android.Manifest.permission.DUMP);
1985                return;
1986            }
1987
1988            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1989        }
1990    }
1991
1992    static class GraphicsBinder extends Binder {
1993        ActivityManagerService mActivityManagerService;
1994        GraphicsBinder(ActivityManagerService activityManagerService) {
1995            mActivityManagerService = activityManagerService;
1996        }
1997
1998        @Override
1999        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2000            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2001                    != PackageManager.PERMISSION_GRANTED) {
2002                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2003                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2004                        + " without permission " + android.Manifest.permission.DUMP);
2005                return;
2006            }
2007
2008            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2009        }
2010    }
2011
2012    static class DbBinder extends Binder {
2013        ActivityManagerService mActivityManagerService;
2014        DbBinder(ActivityManagerService activityManagerService) {
2015            mActivityManagerService = activityManagerService;
2016        }
2017
2018        @Override
2019        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2020            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2021                    != PackageManager.PERMISSION_GRANTED) {
2022                pw.println("Permission Denial: can't dump dbinfo from from pid="
2023                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2024                        + " without permission " + android.Manifest.permission.DUMP);
2025                return;
2026            }
2027
2028            mActivityManagerService.dumpDbInfo(fd, pw, args);
2029        }
2030    }
2031
2032    static class CpuBinder extends Binder {
2033        ActivityManagerService mActivityManagerService;
2034        CpuBinder(ActivityManagerService activityManagerService) {
2035            mActivityManagerService = activityManagerService;
2036        }
2037
2038        @Override
2039        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2040            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2041                    != PackageManager.PERMISSION_GRANTED) {
2042                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2043                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2044                        + " without permission " + android.Manifest.permission.DUMP);
2045                return;
2046            }
2047
2048            synchronized (mActivityManagerService.mProcessCpuTracker) {
2049                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2050                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2051                        SystemClock.uptimeMillis()));
2052            }
2053        }
2054    }
2055
2056    public static final class Lifecycle extends SystemService {
2057        private final ActivityManagerService mService;
2058
2059        public Lifecycle(Context context) {
2060            super(context);
2061            mService = new ActivityManagerService(context);
2062        }
2063
2064        @Override
2065        public void onStart() {
2066            mService.start();
2067        }
2068
2069        public ActivityManagerService getService() {
2070            return mService;
2071        }
2072    }
2073
2074    // Note: This method is invoked on the main thread but may need to attach various
2075    // handlers to other threads.  So take care to be explicit about the looper.
2076    public ActivityManagerService(Context systemContext) {
2077        mContext = systemContext;
2078        mFactoryTest = FactoryTest.getMode();
2079        mSystemThread = ActivityThread.currentActivityThread();
2080
2081        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2082
2083        mHandlerThread = new ServiceThread(TAG,
2084                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2085        mHandlerThread.start();
2086        mHandler = new MainHandler(mHandlerThread.getLooper());
2087
2088        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2089                "foreground", BROADCAST_FG_TIMEOUT, false);
2090        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2091                "background", BROADCAST_BG_TIMEOUT, true);
2092        mBroadcastQueues[0] = mFgBroadcastQueue;
2093        mBroadcastQueues[1] = mBgBroadcastQueue;
2094
2095        mServices = new ActiveServices(this);
2096        mProviderMap = new ProviderMap(this);
2097
2098        // TODO: Move creation of battery stats service outside of activity manager service.
2099        File dataDir = Environment.getDataDirectory();
2100        File systemDir = new File(dataDir, "system");
2101        systemDir.mkdirs();
2102        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2103        mBatteryStatsService.getActiveStatistics().readLocked();
2104        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2105        mOnBattery = DEBUG_POWER ? true
2106                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2107        mBatteryStatsService.getActiveStatistics().setCallback(this);
2108
2109        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2110
2111        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2112
2113        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2114
2115        // User 0 is the first and only user that runs at boot.
2116        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2117        mUserLru.add(Integer.valueOf(0));
2118        updateStartedUserArrayLocked();
2119
2120        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2121            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2122
2123        mConfiguration.setToDefaults();
2124        mConfiguration.setLocale(Locale.getDefault());
2125
2126        mConfigurationSeq = mConfiguration.seq = 1;
2127        mProcessCpuTracker.init();
2128
2129        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2130        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2131        mStackSupervisor = new ActivityStackSupervisor(this);
2132        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2133
2134        mProcessCpuThread = new Thread("CpuTracker") {
2135            @Override
2136            public void run() {
2137                while (true) {
2138                    try {
2139                        try {
2140                            synchronized(this) {
2141                                final long now = SystemClock.uptimeMillis();
2142                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2143                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2144                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2145                                //        + ", write delay=" + nextWriteDelay);
2146                                if (nextWriteDelay < nextCpuDelay) {
2147                                    nextCpuDelay = nextWriteDelay;
2148                                }
2149                                if (nextCpuDelay > 0) {
2150                                    mProcessCpuMutexFree.set(true);
2151                                    this.wait(nextCpuDelay);
2152                                }
2153                            }
2154                        } catch (InterruptedException e) {
2155                        }
2156                        updateCpuStatsNow();
2157                    } catch (Exception e) {
2158                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2159                    }
2160                }
2161            }
2162        };
2163
2164        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2165
2166        Watchdog.getInstance().addMonitor(this);
2167        Watchdog.getInstance().addThread(mHandler);
2168    }
2169
2170    public void setSystemServiceManager(SystemServiceManager mgr) {
2171        mSystemServiceManager = mgr;
2172    }
2173
2174    private void start() {
2175        Process.removeAllProcessGroups();
2176        mProcessCpuThread.start();
2177
2178        mBatteryStatsService.publish(mContext);
2179        mAppOpsService.publish(mContext);
2180        Slog.d("AppOps", "AppOpsService published");
2181        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2182    }
2183
2184    public void initPowerManagement() {
2185        mStackSupervisor.initPowerManagement();
2186        mBatteryStatsService.initPowerManagement();
2187    }
2188
2189    @Override
2190    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2191            throws RemoteException {
2192        if (code == SYSPROPS_TRANSACTION) {
2193            // We need to tell all apps about the system property change.
2194            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2195            synchronized(this) {
2196                final int NP = mProcessNames.getMap().size();
2197                for (int ip=0; ip<NP; ip++) {
2198                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2199                    final int NA = apps.size();
2200                    for (int ia=0; ia<NA; ia++) {
2201                        ProcessRecord app = apps.valueAt(ia);
2202                        if (app.thread != null) {
2203                            procs.add(app.thread.asBinder());
2204                        }
2205                    }
2206                }
2207            }
2208
2209            int N = procs.size();
2210            for (int i=0; i<N; i++) {
2211                Parcel data2 = Parcel.obtain();
2212                try {
2213                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2214                } catch (RemoteException e) {
2215                }
2216                data2.recycle();
2217            }
2218        }
2219        try {
2220            return super.onTransact(code, data, reply, flags);
2221        } catch (RuntimeException e) {
2222            // The activity manager only throws security exceptions, so let's
2223            // log all others.
2224            if (!(e instanceof SecurityException)) {
2225                Slog.wtf(TAG, "Activity Manager Crash", e);
2226            }
2227            throw e;
2228        }
2229    }
2230
2231    void updateCpuStats() {
2232        final long now = SystemClock.uptimeMillis();
2233        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2234            return;
2235        }
2236        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2237            synchronized (mProcessCpuThread) {
2238                mProcessCpuThread.notify();
2239            }
2240        }
2241    }
2242
2243    void updateCpuStatsNow() {
2244        synchronized (mProcessCpuTracker) {
2245            mProcessCpuMutexFree.set(false);
2246            final long now = SystemClock.uptimeMillis();
2247            boolean haveNewCpuStats = false;
2248
2249            if (MONITOR_CPU_USAGE &&
2250                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2251                mLastCpuTime.set(now);
2252                haveNewCpuStats = true;
2253                mProcessCpuTracker.update();
2254                //Slog.i(TAG, mProcessCpu.printCurrentState());
2255                //Slog.i(TAG, "Total CPU usage: "
2256                //        + mProcessCpu.getTotalCpuPercent() + "%");
2257
2258                // Slog the cpu usage if the property is set.
2259                if ("true".equals(SystemProperties.get("events.cpu"))) {
2260                    int user = mProcessCpuTracker.getLastUserTime();
2261                    int system = mProcessCpuTracker.getLastSystemTime();
2262                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2263                    int irq = mProcessCpuTracker.getLastIrqTime();
2264                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2265                    int idle = mProcessCpuTracker.getLastIdleTime();
2266
2267                    int total = user + system + iowait + irq + softIrq + idle;
2268                    if (total == 0) total = 1;
2269
2270                    EventLog.writeEvent(EventLogTags.CPU,
2271                            ((user+system+iowait+irq+softIrq) * 100) / total,
2272                            (user * 100) / total,
2273                            (system * 100) / total,
2274                            (iowait * 100) / total,
2275                            (irq * 100) / total,
2276                            (softIrq * 100) / total);
2277                }
2278            }
2279
2280            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2281            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2282            synchronized(bstats) {
2283                synchronized(mPidsSelfLocked) {
2284                    if (haveNewCpuStats) {
2285                        if (mOnBattery) {
2286                            int perc = bstats.startAddingCpuLocked();
2287                            int totalUTime = 0;
2288                            int totalSTime = 0;
2289                            final int N = mProcessCpuTracker.countStats();
2290                            for (int i=0; i<N; i++) {
2291                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2292                                if (!st.working) {
2293                                    continue;
2294                                }
2295                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2296                                int otherUTime = (st.rel_utime*perc)/100;
2297                                int otherSTime = (st.rel_stime*perc)/100;
2298                                totalUTime += otherUTime;
2299                                totalSTime += otherSTime;
2300                                if (pr != null) {
2301                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2302                                    if (ps == null || !ps.isActive()) {
2303                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2304                                                pr.info.uid, pr.processName);
2305                                    }
2306                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2307                                            st.rel_stime-otherSTime);
2308                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2309                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2310                                } else {
2311                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2312                                    if (ps == null || !ps.isActive()) {
2313                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2314                                                bstats.mapUid(st.uid), st.name);
2315                                    }
2316                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2317                                            st.rel_stime-otherSTime);
2318                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2319                                }
2320                            }
2321                            bstats.finishAddingCpuLocked(perc, totalUTime,
2322                                    totalSTime, cpuSpeedTimes);
2323                        }
2324                    }
2325                }
2326
2327                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2328                    mLastWriteTime = now;
2329                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2330                }
2331            }
2332        }
2333    }
2334
2335    @Override
2336    public void batteryNeedsCpuUpdate() {
2337        updateCpuStatsNow();
2338    }
2339
2340    @Override
2341    public void batteryPowerChanged(boolean onBattery) {
2342        // When plugging in, update the CPU stats first before changing
2343        // the plug state.
2344        updateCpuStatsNow();
2345        synchronized (this) {
2346            synchronized(mPidsSelfLocked) {
2347                mOnBattery = DEBUG_POWER ? true : onBattery;
2348            }
2349        }
2350    }
2351
2352    /**
2353     * Initialize the application bind args. These are passed to each
2354     * process when the bindApplication() IPC is sent to the process. They're
2355     * lazily setup to make sure the services are running when they're asked for.
2356     */
2357    private HashMap<String, IBinder> getCommonServicesLocked() {
2358        if (mAppBindArgs == null) {
2359            mAppBindArgs = new HashMap<String, IBinder>();
2360
2361            // Setup the application init args
2362            mAppBindArgs.put("package", ServiceManager.getService("package"));
2363            mAppBindArgs.put("window", ServiceManager.getService("window"));
2364            mAppBindArgs.put(Context.ALARM_SERVICE,
2365                    ServiceManager.getService(Context.ALARM_SERVICE));
2366        }
2367        return mAppBindArgs;
2368    }
2369
2370    final void setFocusedActivityLocked(ActivityRecord r) {
2371        if (mFocusedActivity != r) {
2372            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2373            mFocusedActivity = r;
2374            if (r.task != null && r.task.voiceInteractor != null) {
2375                startRunningVoiceLocked();
2376            } else {
2377                finishRunningVoiceLocked();
2378            }
2379            mStackSupervisor.setFocusedStack(r);
2380            if (r != null) {
2381                mWindowManager.setFocusedApp(r.appToken, true);
2382            }
2383            applyUpdateLockStateLocked(r);
2384        }
2385    }
2386
2387    final void clearFocusedActivity(ActivityRecord r) {
2388        if (mFocusedActivity == r) {
2389            mFocusedActivity = null;
2390        }
2391    }
2392
2393    @Override
2394    public void setFocusedStack(int stackId) {
2395        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2396        synchronized (ActivityManagerService.this) {
2397            ActivityStack stack = mStackSupervisor.getStack(stackId);
2398            if (stack != null) {
2399                ActivityRecord r = stack.topRunningActivityLocked(null);
2400                if (r != null) {
2401                    setFocusedActivityLocked(r);
2402                }
2403            }
2404        }
2405    }
2406
2407    @Override
2408    public void notifyActivityDrawn(IBinder token) {
2409        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2410        synchronized (this) {
2411            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2412            if (r != null) {
2413                r.task.stack.notifyActivityDrawnLocked(r);
2414            }
2415        }
2416    }
2417
2418    final void applyUpdateLockStateLocked(ActivityRecord r) {
2419        // Modifications to the UpdateLock state are done on our handler, outside
2420        // the activity manager's locks.  The new state is determined based on the
2421        // state *now* of the relevant activity record.  The object is passed to
2422        // the handler solely for logging detail, not to be consulted/modified.
2423        final boolean nextState = r != null && r.immersive;
2424        mHandler.sendMessage(
2425                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2426    }
2427
2428    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2429        Message msg = Message.obtain();
2430        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2431        msg.obj = r.task.askedCompatMode ? null : r;
2432        mHandler.sendMessage(msg);
2433    }
2434
2435    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2436            String what, Object obj, ProcessRecord srcApp) {
2437        app.lastActivityTime = now;
2438
2439        if (app.activities.size() > 0) {
2440            // Don't want to touch dependent processes that are hosting activities.
2441            return index;
2442        }
2443
2444        int lrui = mLruProcesses.lastIndexOf(app);
2445        if (lrui < 0) {
2446            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2447                    + what + " " + obj + " from " + srcApp);
2448            return index;
2449        }
2450
2451        if (lrui >= index) {
2452            // Don't want to cause this to move dependent processes *back* in the
2453            // list as if they were less frequently used.
2454            return index;
2455        }
2456
2457        if (lrui >= mLruProcessActivityStart) {
2458            // Don't want to touch dependent processes that are hosting activities.
2459            return index;
2460        }
2461
2462        mLruProcesses.remove(lrui);
2463        if (index > 0) {
2464            index--;
2465        }
2466        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2467                + " in LRU list: " + app);
2468        mLruProcesses.add(index, app);
2469        return index;
2470    }
2471
2472    final void removeLruProcessLocked(ProcessRecord app) {
2473        int lrui = mLruProcesses.lastIndexOf(app);
2474        if (lrui >= 0) {
2475            if (!app.killed) {
2476                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2477                Process.killProcessQuiet(app.pid);
2478                Process.killProcessGroup(app.info.uid, app.pid);
2479            }
2480            if (lrui <= mLruProcessActivityStart) {
2481                mLruProcessActivityStart--;
2482            }
2483            if (lrui <= mLruProcessServiceStart) {
2484                mLruProcessServiceStart--;
2485            }
2486            mLruProcesses.remove(lrui);
2487        }
2488    }
2489
2490    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2491            ProcessRecord client) {
2492        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2493                || app.treatLikeActivity;
2494        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2495        if (!activityChange && hasActivity) {
2496            // The process has activities, so we are only allowing activity-based adjustments
2497            // to move it.  It should be kept in the front of the list with other
2498            // processes that have activities, and we don't want those to change their
2499            // order except due to activity operations.
2500            return;
2501        }
2502
2503        mLruSeq++;
2504        final long now = SystemClock.uptimeMillis();
2505        app.lastActivityTime = now;
2506
2507        // First a quick reject: if the app is already at the position we will
2508        // put it, then there is nothing to do.
2509        if (hasActivity) {
2510            final int N = mLruProcesses.size();
2511            if (N > 0 && mLruProcesses.get(N-1) == app) {
2512                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2513                return;
2514            }
2515        } else {
2516            if (mLruProcessServiceStart > 0
2517                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2518                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2519                return;
2520            }
2521        }
2522
2523        int lrui = mLruProcesses.lastIndexOf(app);
2524
2525        if (app.persistent && lrui >= 0) {
2526            // We don't care about the position of persistent processes, as long as
2527            // they are in the list.
2528            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2529            return;
2530        }
2531
2532        /* In progress: compute new position first, so we can avoid doing work
2533           if the process is not actually going to move.  Not yet working.
2534        int addIndex;
2535        int nextIndex;
2536        boolean inActivity = false, inService = false;
2537        if (hasActivity) {
2538            // Process has activities, put it at the very tipsy-top.
2539            addIndex = mLruProcesses.size();
2540            nextIndex = mLruProcessServiceStart;
2541            inActivity = true;
2542        } else if (hasService) {
2543            // Process has services, put it at the top of the service list.
2544            addIndex = mLruProcessActivityStart;
2545            nextIndex = mLruProcessServiceStart;
2546            inActivity = true;
2547            inService = true;
2548        } else  {
2549            // Process not otherwise of interest, it goes to the top of the non-service area.
2550            addIndex = mLruProcessServiceStart;
2551            if (client != null) {
2552                int clientIndex = mLruProcesses.lastIndexOf(client);
2553                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2554                        + app);
2555                if (clientIndex >= 0 && addIndex > clientIndex) {
2556                    addIndex = clientIndex;
2557                }
2558            }
2559            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2560        }
2561
2562        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2563                + mLruProcessActivityStart + "): " + app);
2564        */
2565
2566        if (lrui >= 0) {
2567            if (lrui < mLruProcessActivityStart) {
2568                mLruProcessActivityStart--;
2569            }
2570            if (lrui < mLruProcessServiceStart) {
2571                mLruProcessServiceStart--;
2572            }
2573            /*
2574            if (addIndex > lrui) {
2575                addIndex--;
2576            }
2577            if (nextIndex > lrui) {
2578                nextIndex--;
2579            }
2580            */
2581            mLruProcesses.remove(lrui);
2582        }
2583
2584        /*
2585        mLruProcesses.add(addIndex, app);
2586        if (inActivity) {
2587            mLruProcessActivityStart++;
2588        }
2589        if (inService) {
2590            mLruProcessActivityStart++;
2591        }
2592        */
2593
2594        int nextIndex;
2595        if (hasActivity) {
2596            final int N = mLruProcesses.size();
2597            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2598                // Process doesn't have activities, but has clients with
2599                // activities...  move it up, but one below the top (the top
2600                // should always have a real activity).
2601                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2602                mLruProcesses.add(N-1, app);
2603                // To keep it from spamming the LRU list (by making a bunch of clients),
2604                // we will push down any other entries owned by the app.
2605                final int uid = app.info.uid;
2606                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2607                    ProcessRecord subProc = mLruProcesses.get(i);
2608                    if (subProc.info.uid == uid) {
2609                        // We want to push this one down the list.  If the process after
2610                        // it is for the same uid, however, don't do so, because we don't
2611                        // want them internally to be re-ordered.
2612                        if (mLruProcesses.get(i-1).info.uid != uid) {
2613                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2614                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2615                            ProcessRecord tmp = mLruProcesses.get(i);
2616                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2617                            mLruProcesses.set(i-1, tmp);
2618                            i--;
2619                        }
2620                    } else {
2621                        // A gap, we can stop here.
2622                        break;
2623                    }
2624                }
2625            } else {
2626                // Process has activities, put it at the very tipsy-top.
2627                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2628                mLruProcesses.add(app);
2629            }
2630            nextIndex = mLruProcessServiceStart;
2631        } else if (hasService) {
2632            // Process has services, put it at the top of the service list.
2633            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2634            mLruProcesses.add(mLruProcessActivityStart, app);
2635            nextIndex = mLruProcessServiceStart;
2636            mLruProcessActivityStart++;
2637        } else  {
2638            // Process not otherwise of interest, it goes to the top of the non-service area.
2639            int index = mLruProcessServiceStart;
2640            if (client != null) {
2641                // If there is a client, don't allow the process to be moved up higher
2642                // in the list than that client.
2643                int clientIndex = mLruProcesses.lastIndexOf(client);
2644                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2645                        + " when updating " + app);
2646                if (clientIndex <= lrui) {
2647                    // Don't allow the client index restriction to push it down farther in the
2648                    // list than it already is.
2649                    clientIndex = lrui;
2650                }
2651                if (clientIndex >= 0 && index > clientIndex) {
2652                    index = clientIndex;
2653                }
2654            }
2655            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2656            mLruProcesses.add(index, app);
2657            nextIndex = index-1;
2658            mLruProcessActivityStart++;
2659            mLruProcessServiceStart++;
2660        }
2661
2662        // If the app is currently using a content provider or service,
2663        // bump those processes as well.
2664        for (int j=app.connections.size()-1; j>=0; j--) {
2665            ConnectionRecord cr = app.connections.valueAt(j);
2666            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2667                    && cr.binding.service.app != null
2668                    && cr.binding.service.app.lruSeq != mLruSeq
2669                    && !cr.binding.service.app.persistent) {
2670                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2671                        "service connection", cr, app);
2672            }
2673        }
2674        for (int j=app.conProviders.size()-1; j>=0; j--) {
2675            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2676            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2677                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2678                        "provider reference", cpr, app);
2679            }
2680        }
2681    }
2682
2683    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2684        if (uid == Process.SYSTEM_UID) {
2685            // The system gets to run in any process.  If there are multiple
2686            // processes with the same uid, just pick the first (this
2687            // should never happen).
2688            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2689            if (procs == null) return null;
2690            final int N = procs.size();
2691            for (int i = 0; i < N; i++) {
2692                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2693            }
2694        }
2695        ProcessRecord proc = mProcessNames.get(processName, uid);
2696        if (false && proc != null && !keepIfLarge
2697                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2698                && proc.lastCachedPss >= 4000) {
2699            // Turn this condition on to cause killing to happen regularly, for testing.
2700            if (proc.baseProcessTracker != null) {
2701                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2702            }
2703            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2704        } else if (proc != null && !keepIfLarge
2705                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2706                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2707            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2708            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2709                if (proc.baseProcessTracker != null) {
2710                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2711                }
2712                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2713            }
2714        }
2715        return proc;
2716    }
2717
2718    void ensurePackageDexOpt(String packageName) {
2719        IPackageManager pm = AppGlobals.getPackageManager();
2720        try {
2721            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2722                mDidDexOpt = true;
2723            }
2724        } catch (RemoteException e) {
2725        }
2726    }
2727
2728    boolean isNextTransitionForward() {
2729        int transit = mWindowManager.getPendingAppTransition();
2730        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2731                || transit == AppTransition.TRANSIT_TASK_OPEN
2732                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2733    }
2734
2735    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2736            String processName, String abiOverride, int uid, Runnable crashHandler) {
2737        synchronized(this) {
2738            ApplicationInfo info = new ApplicationInfo();
2739            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2740            // For isolated processes, the former contains the parent's uid and the latter the
2741            // actual uid of the isolated process.
2742            // In the special case introduced by this method (which is, starting an isolated
2743            // process directly from the SystemServer without an actual parent app process) the
2744            // closest thing to a parent's uid is SYSTEM_UID.
2745            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2746            // the |isolated| logic in the ProcessRecord constructor.
2747            info.uid = Process.SYSTEM_UID;
2748            info.processName = processName;
2749            info.className = entryPoint;
2750            info.packageName = "android";
2751            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2752                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2753                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2754                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2755                    crashHandler);
2756            return proc != null ? proc.pid : 0;
2757        }
2758    }
2759
2760    final ProcessRecord startProcessLocked(String processName,
2761            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2762            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2763            boolean isolated, boolean keepIfLarge) {
2764        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2765                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2766                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2767                null /* crashHandler */);
2768    }
2769
2770    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2771            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2772            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2773            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2774        long startTime = SystemClock.elapsedRealtime();
2775        ProcessRecord app;
2776        if (!isolated) {
2777            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2778            checkTime(startTime, "startProcess: after getProcessRecord");
2779        } else {
2780            // If this is an isolated process, it can't re-use an existing process.
2781            app = null;
2782        }
2783        // We don't have to do anything more if:
2784        // (1) There is an existing application record; and
2785        // (2) The caller doesn't think it is dead, OR there is no thread
2786        //     object attached to it so we know it couldn't have crashed; and
2787        // (3) There is a pid assigned to it, so it is either starting or
2788        //     already running.
2789        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2790                + " app=" + app + " knownToBeDead=" + knownToBeDead
2791                + " thread=" + (app != null ? app.thread : null)
2792                + " pid=" + (app != null ? app.pid : -1));
2793        if (app != null && app.pid > 0) {
2794            if (!knownToBeDead || app.thread == null) {
2795                // We already have the app running, or are waiting for it to
2796                // come up (we have a pid but not yet its thread), so keep it.
2797                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2798                // If this is a new package in the process, add the package to the list
2799                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2800                checkTime(startTime, "startProcess: done, added package to proc");
2801                return app;
2802            }
2803
2804            // An application record is attached to a previous process,
2805            // clean it up now.
2806            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2807            checkTime(startTime, "startProcess: bad proc running, killing");
2808            Process.killProcessGroup(app.info.uid, app.pid);
2809            handleAppDiedLocked(app, true, true);
2810            checkTime(startTime, "startProcess: done killing old proc");
2811        }
2812
2813        String hostingNameStr = hostingName != null
2814                ? hostingName.flattenToShortString() : null;
2815
2816        if (!isolated) {
2817            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2818                // If we are in the background, then check to see if this process
2819                // is bad.  If so, we will just silently fail.
2820                if (mBadProcesses.get(info.processName, info.uid) != null) {
2821                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2822                            + "/" + info.processName);
2823                    return null;
2824                }
2825            } else {
2826                // When the user is explicitly starting a process, then clear its
2827                // crash count so that we won't make it bad until they see at
2828                // least one crash dialog again, and make the process good again
2829                // if it had been bad.
2830                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2831                        + "/" + info.processName);
2832                mProcessCrashTimes.remove(info.processName, info.uid);
2833                if (mBadProcesses.get(info.processName, info.uid) != null) {
2834                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2835                            UserHandle.getUserId(info.uid), info.uid,
2836                            info.processName);
2837                    mBadProcesses.remove(info.processName, info.uid);
2838                    if (app != null) {
2839                        app.bad = false;
2840                    }
2841                }
2842            }
2843        }
2844
2845        if (app == null) {
2846            checkTime(startTime, "startProcess: creating new process record");
2847            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2848            app.crashHandler = crashHandler;
2849            if (app == null) {
2850                Slog.w(TAG, "Failed making new process record for "
2851                        + processName + "/" + info.uid + " isolated=" + isolated);
2852                return null;
2853            }
2854            mProcessNames.put(processName, app.uid, app);
2855            if (isolated) {
2856                mIsolatedProcesses.put(app.uid, app);
2857            }
2858            checkTime(startTime, "startProcess: done creating new process record");
2859        } else {
2860            // If this is a new package in the process, add the package to the list
2861            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2862            checkTime(startTime, "startProcess: added package to existing proc");
2863        }
2864
2865        // If the system is not ready yet, then hold off on starting this
2866        // process until it is.
2867        if (!mProcessesReady
2868                && !isAllowedWhileBooting(info)
2869                && !allowWhileBooting) {
2870            if (!mProcessesOnHold.contains(app)) {
2871                mProcessesOnHold.add(app);
2872            }
2873            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2874            checkTime(startTime, "startProcess: returning with proc on hold");
2875            return app;
2876        }
2877
2878        checkTime(startTime, "startProcess: stepping in to startProcess");
2879        startProcessLocked(
2880                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2881        checkTime(startTime, "startProcess: done starting proc!");
2882        return (app.pid != 0) ? app : null;
2883    }
2884
2885    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2886        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2887    }
2888
2889    private final void startProcessLocked(ProcessRecord app,
2890            String hostingType, String hostingNameStr) {
2891        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2892                null /* entryPoint */, null /* entryPointArgs */);
2893    }
2894
2895    private final void startProcessLocked(ProcessRecord app, String hostingType,
2896            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2897        long startTime = SystemClock.elapsedRealtime();
2898        if (app.pid > 0 && app.pid != MY_PID) {
2899            checkTime(startTime, "startProcess: removing from pids map");
2900            synchronized (mPidsSelfLocked) {
2901                mPidsSelfLocked.remove(app.pid);
2902                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2903            }
2904            checkTime(startTime, "startProcess: done removing from pids map");
2905            app.setPid(0);
2906        }
2907
2908        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2909                "startProcessLocked removing on hold: " + app);
2910        mProcessesOnHold.remove(app);
2911
2912        checkTime(startTime, "startProcess: starting to update cpu stats");
2913        updateCpuStats();
2914        checkTime(startTime, "startProcess: done updating cpu stats");
2915
2916        try {
2917            int uid = app.uid;
2918
2919            int[] gids = null;
2920            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2921            if (!app.isolated) {
2922                int[] permGids = null;
2923                try {
2924                    checkTime(startTime, "startProcess: getting gids from package manager");
2925                    final PackageManager pm = mContext.getPackageManager();
2926                    permGids = pm.getPackageGids(app.info.packageName);
2927
2928                    if (Environment.isExternalStorageEmulated()) {
2929                        checkTime(startTime, "startProcess: checking external storage perm");
2930                        if (pm.checkPermission(
2931                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2932                                app.info.packageName) == PERMISSION_GRANTED) {
2933                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2934                        } else {
2935                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2936                        }
2937                    }
2938                } catch (PackageManager.NameNotFoundException e) {
2939                    Slog.w(TAG, "Unable to retrieve gids", e);
2940                }
2941
2942                /*
2943                 * Add shared application and profile GIDs so applications can share some
2944                 * resources like shared libraries and access user-wide resources
2945                 */
2946                if (permGids == null) {
2947                    gids = new int[2];
2948                } else {
2949                    gids = new int[permGids.length + 2];
2950                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2951                }
2952                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2953                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2954            }
2955            checkTime(startTime, "startProcess: building args");
2956            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2957                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2958                        && mTopComponent != null
2959                        && app.processName.equals(mTopComponent.getPackageName())) {
2960                    uid = 0;
2961                }
2962                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2963                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2964                    uid = 0;
2965                }
2966            }
2967            int debugFlags = 0;
2968            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2969                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2970                // Also turn on CheckJNI for debuggable apps. It's quite
2971                // awkward to turn on otherwise.
2972                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2973            }
2974            // Run the app in safe mode if its manifest requests so or the
2975            // system is booted in safe mode.
2976            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2977                mSafeMode == true) {
2978                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2979            }
2980            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2981                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2982            }
2983            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2984                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2985            }
2986            if ("1".equals(SystemProperties.get("debug.assert"))) {
2987                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2988            }
2989
2990            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2991            if (requiredAbi == null) {
2992                requiredAbi = Build.SUPPORTED_ABIS[0];
2993            }
2994
2995            String instructionSet = null;
2996            if (app.info.primaryCpuAbi != null) {
2997                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2998            }
2999
3000            // Start the process.  It will either succeed and return a result containing
3001            // the PID of the new process, or else throw a RuntimeException.
3002            boolean isActivityProcess = (entryPoint == null);
3003            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3004            checkTime(startTime, "startProcess: asking zygote to start proc");
3005            Process.ProcessStartResult startResult = Process.start(entryPoint,
3006                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3007                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3008                    app.info.dataDir, entryPointArgs);
3009            checkTime(startTime, "startProcess: returned from zygote!");
3010
3011            if (app.isolated) {
3012                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3013            }
3014            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3015            checkTime(startTime, "startProcess: done updating battery stats");
3016
3017            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3018                    UserHandle.getUserId(uid), startResult.pid, uid,
3019                    app.processName, hostingType,
3020                    hostingNameStr != null ? hostingNameStr : "");
3021
3022            if (app.persistent) {
3023                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3024            }
3025
3026            checkTime(startTime, "startProcess: building log message");
3027            StringBuilder buf = mStringBuilder;
3028            buf.setLength(0);
3029            buf.append("Start proc ");
3030            buf.append(app.processName);
3031            if (!isActivityProcess) {
3032                buf.append(" [");
3033                buf.append(entryPoint);
3034                buf.append("]");
3035            }
3036            buf.append(" for ");
3037            buf.append(hostingType);
3038            if (hostingNameStr != null) {
3039                buf.append(" ");
3040                buf.append(hostingNameStr);
3041            }
3042            buf.append(": pid=");
3043            buf.append(startResult.pid);
3044            buf.append(" uid=");
3045            buf.append(uid);
3046            buf.append(" gids={");
3047            if (gids != null) {
3048                for (int gi=0; gi<gids.length; gi++) {
3049                    if (gi != 0) buf.append(", ");
3050                    buf.append(gids[gi]);
3051
3052                }
3053            }
3054            buf.append("}");
3055            if (requiredAbi != null) {
3056                buf.append(" abi=");
3057                buf.append(requiredAbi);
3058            }
3059            Slog.i(TAG, buf.toString());
3060            app.setPid(startResult.pid);
3061            app.usingWrapper = startResult.usingWrapper;
3062            app.removed = false;
3063            app.killed = false;
3064            app.killedByAm = false;
3065            checkTime(startTime, "startProcess: starting to update pids map");
3066            synchronized (mPidsSelfLocked) {
3067                this.mPidsSelfLocked.put(startResult.pid, app);
3068                if (isActivityProcess) {
3069                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3070                    msg.obj = app;
3071                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3072                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3073                }
3074            }
3075            checkTime(startTime, "startProcess: done updating pids map");
3076        } catch (RuntimeException e) {
3077            // XXX do better error recovery.
3078            app.setPid(0);
3079            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3080            if (app.isolated) {
3081                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3082            }
3083            Slog.e(TAG, "Failure starting process " + app.processName, e);
3084        }
3085    }
3086
3087    void updateUsageStats(ActivityRecord component, boolean resumed) {
3088        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3089        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3090        if (resumed) {
3091            if (mUsageStatsService != null) {
3092                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3093                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3094            }
3095            synchronized (stats) {
3096                stats.noteActivityResumedLocked(component.app.uid);
3097            }
3098        } else {
3099            if (mUsageStatsService != null) {
3100                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3101                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3102            }
3103            synchronized (stats) {
3104                stats.noteActivityPausedLocked(component.app.uid);
3105            }
3106        }
3107    }
3108
3109    Intent getHomeIntent() {
3110        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3111        intent.setComponent(mTopComponent);
3112        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3113            intent.addCategory(Intent.CATEGORY_HOME);
3114        }
3115        return intent;
3116    }
3117
3118    boolean startHomeActivityLocked(int userId) {
3119        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3120                && mTopAction == null) {
3121            // We are running in factory test mode, but unable to find
3122            // the factory test app, so just sit around displaying the
3123            // error message and don't try to start anything.
3124            return false;
3125        }
3126        Intent intent = getHomeIntent();
3127        ActivityInfo aInfo =
3128            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3129        if (aInfo != null) {
3130            intent.setComponent(new ComponentName(
3131                    aInfo.applicationInfo.packageName, aInfo.name));
3132            // Don't do this if the home app is currently being
3133            // instrumented.
3134            aInfo = new ActivityInfo(aInfo);
3135            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3136            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3137                    aInfo.applicationInfo.uid, true);
3138            if (app == null || app.instrumentationClass == null) {
3139                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3140                mStackSupervisor.startHomeActivity(intent, aInfo);
3141            }
3142        }
3143
3144        return true;
3145    }
3146
3147    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3148        ActivityInfo ai = null;
3149        ComponentName comp = intent.getComponent();
3150        try {
3151            if (comp != null) {
3152                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3153            } else {
3154                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3155                        intent,
3156                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3157                            flags, userId);
3158
3159                if (info != null) {
3160                    ai = info.activityInfo;
3161                }
3162            }
3163        } catch (RemoteException e) {
3164            // ignore
3165        }
3166
3167        return ai;
3168    }
3169
3170    /**
3171     * Starts the "new version setup screen" if appropriate.
3172     */
3173    void startSetupActivityLocked() {
3174        // Only do this once per boot.
3175        if (mCheckedForSetup) {
3176            return;
3177        }
3178
3179        // We will show this screen if the current one is a different
3180        // version than the last one shown, and we are not running in
3181        // low-level factory test mode.
3182        final ContentResolver resolver = mContext.getContentResolver();
3183        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3184                Settings.Global.getInt(resolver,
3185                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3186            mCheckedForSetup = true;
3187
3188            // See if we should be showing the platform update setup UI.
3189            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3190            List<ResolveInfo> ris = mContext.getPackageManager()
3191                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3192
3193            // We don't allow third party apps to replace this.
3194            ResolveInfo ri = null;
3195            for (int i=0; ris != null && i<ris.size(); i++) {
3196                if ((ris.get(i).activityInfo.applicationInfo.flags
3197                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3198                    ri = ris.get(i);
3199                    break;
3200                }
3201            }
3202
3203            if (ri != null) {
3204                String vers = ri.activityInfo.metaData != null
3205                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3206                        : null;
3207                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3208                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3209                            Intent.METADATA_SETUP_VERSION);
3210                }
3211                String lastVers = Settings.Secure.getString(
3212                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3213                if (vers != null && !vers.equals(lastVers)) {
3214                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3215                    intent.setComponent(new ComponentName(
3216                            ri.activityInfo.packageName, ri.activityInfo.name));
3217                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3218                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3219                            null);
3220                }
3221            }
3222        }
3223    }
3224
3225    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3226        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3227    }
3228
3229    void enforceNotIsolatedCaller(String caller) {
3230        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3231            throw new SecurityException("Isolated process not allowed to call " + caller);
3232        }
3233    }
3234
3235    void enforceShellRestriction(String restriction, int userHandle) {
3236        if (Binder.getCallingUid() == Process.SHELL_UID) {
3237            if (userHandle < 0
3238                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3239                throw new SecurityException("Shell does not have permission to access user "
3240                        + userHandle);
3241            }
3242        }
3243    }
3244
3245    @Override
3246    public int getFrontActivityScreenCompatMode() {
3247        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3248        synchronized (this) {
3249            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3250        }
3251    }
3252
3253    @Override
3254    public void setFrontActivityScreenCompatMode(int mode) {
3255        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3256                "setFrontActivityScreenCompatMode");
3257        synchronized (this) {
3258            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3259        }
3260    }
3261
3262    @Override
3263    public int getPackageScreenCompatMode(String packageName) {
3264        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3265        synchronized (this) {
3266            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3267        }
3268    }
3269
3270    @Override
3271    public void setPackageScreenCompatMode(String packageName, int mode) {
3272        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3273                "setPackageScreenCompatMode");
3274        synchronized (this) {
3275            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3276        }
3277    }
3278
3279    @Override
3280    public boolean getPackageAskScreenCompat(String packageName) {
3281        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3282        synchronized (this) {
3283            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3284        }
3285    }
3286
3287    @Override
3288    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3289        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3290                "setPackageAskScreenCompat");
3291        synchronized (this) {
3292            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3293        }
3294    }
3295
3296    private void dispatchProcessesChanged() {
3297        int N;
3298        synchronized (this) {
3299            N = mPendingProcessChanges.size();
3300            if (mActiveProcessChanges.length < N) {
3301                mActiveProcessChanges = new ProcessChangeItem[N];
3302            }
3303            mPendingProcessChanges.toArray(mActiveProcessChanges);
3304            mAvailProcessChanges.addAll(mPendingProcessChanges);
3305            mPendingProcessChanges.clear();
3306            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3307        }
3308
3309        int i = mProcessObservers.beginBroadcast();
3310        while (i > 0) {
3311            i--;
3312            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3313            if (observer != null) {
3314                try {
3315                    for (int j=0; j<N; j++) {
3316                        ProcessChangeItem item = mActiveProcessChanges[j];
3317                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3318                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3319                                    + item.pid + " uid=" + item.uid + ": "
3320                                    + item.foregroundActivities);
3321                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3322                                    item.foregroundActivities);
3323                        }
3324                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3325                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3326                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3327                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3328                        }
3329                    }
3330                } catch (RemoteException e) {
3331                }
3332            }
3333        }
3334        mProcessObservers.finishBroadcast();
3335    }
3336
3337    private void dispatchProcessDied(int pid, int uid) {
3338        int i = mProcessObservers.beginBroadcast();
3339        while (i > 0) {
3340            i--;
3341            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3342            if (observer != null) {
3343                try {
3344                    observer.onProcessDied(pid, uid);
3345                } catch (RemoteException e) {
3346                }
3347            }
3348        }
3349        mProcessObservers.finishBroadcast();
3350    }
3351
3352    @Override
3353    public final int startActivity(IApplicationThread caller, String callingPackage,
3354            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3355            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3356        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3357            resultWho, requestCode, startFlags, profilerInfo, options,
3358            UserHandle.getCallingUserId());
3359    }
3360
3361    @Override
3362    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3363            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3364            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3365        enforceNotIsolatedCaller("startActivity");
3366        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3367                false, ALLOW_FULL_ONLY, "startActivity", null);
3368        // TODO: Switch to user app stacks here.
3369        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3370                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3371                profilerInfo, null, null, options, userId, null, null);
3372    }
3373
3374    @Override
3375    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3376            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3377            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3378
3379        // This is very dangerous -- it allows you to perform a start activity (including
3380        // permission grants) as any app that may launch one of your own activities.  So
3381        // we will only allow this to be done from activities that are part of the core framework,
3382        // and then only when they are running as the system.
3383        final ActivityRecord sourceRecord;
3384        final int targetUid;
3385        final String targetPackage;
3386        synchronized (this) {
3387            if (resultTo == null) {
3388                throw new SecurityException("Must be called from an activity");
3389            }
3390            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3391            if (sourceRecord == null) {
3392                throw new SecurityException("Called with bad activity token: " + resultTo);
3393            }
3394            if (!sourceRecord.info.packageName.equals("android")) {
3395                throw new SecurityException(
3396                        "Must be called from an activity that is declared in the android package");
3397            }
3398            if (sourceRecord.app == null) {
3399                throw new SecurityException("Called without a process attached to activity");
3400            }
3401            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3402                // This is still okay, as long as this activity is running under the
3403                // uid of the original calling activity.
3404                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3405                    throw new SecurityException(
3406                            "Calling activity in uid " + sourceRecord.app.uid
3407                                    + " must be system uid or original calling uid "
3408                                    + sourceRecord.launchedFromUid);
3409                }
3410            }
3411            targetUid = sourceRecord.launchedFromUid;
3412            targetPackage = sourceRecord.launchedFromPackage;
3413        }
3414
3415        if (userId == UserHandle.USER_NULL) {
3416            userId = UserHandle.getUserId(sourceRecord.app.uid);
3417        }
3418
3419        // TODO: Switch to user app stacks here.
3420        try {
3421            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3422                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3423                    null, null, options, userId, null, null);
3424            return ret;
3425        } catch (SecurityException e) {
3426            // XXX need to figure out how to propagate to original app.
3427            // A SecurityException here is generally actually a fault of the original
3428            // calling activity (such as a fairly granting permissions), so propagate it
3429            // back to them.
3430            /*
3431            StringBuilder msg = new StringBuilder();
3432            msg.append("While launching");
3433            msg.append(intent.toString());
3434            msg.append(": ");
3435            msg.append(e.getMessage());
3436            */
3437            throw e;
3438        }
3439    }
3440
3441    @Override
3442    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3443            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3444            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3445        enforceNotIsolatedCaller("startActivityAndWait");
3446        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3447                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3448        WaitResult res = new WaitResult();
3449        // TODO: Switch to user app stacks here.
3450        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3451                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3452                options, userId, null, null);
3453        return res;
3454    }
3455
3456    @Override
3457    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3458            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3459            int startFlags, Configuration config, Bundle options, int userId) {
3460        enforceNotIsolatedCaller("startActivityWithConfig");
3461        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3462                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3463        // TODO: Switch to user app stacks here.
3464        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3465                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3466                null, null, config, options, userId, null, null);
3467        return ret;
3468    }
3469
3470    @Override
3471    public int startActivityIntentSender(IApplicationThread caller,
3472            IntentSender intent, Intent fillInIntent, String resolvedType,
3473            IBinder resultTo, String resultWho, int requestCode,
3474            int flagsMask, int flagsValues, Bundle options) {
3475        enforceNotIsolatedCaller("startActivityIntentSender");
3476        // Refuse possible leaked file descriptors
3477        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3478            throw new IllegalArgumentException("File descriptors passed in Intent");
3479        }
3480
3481        IIntentSender sender = intent.getTarget();
3482        if (!(sender instanceof PendingIntentRecord)) {
3483            throw new IllegalArgumentException("Bad PendingIntent object");
3484        }
3485
3486        PendingIntentRecord pir = (PendingIntentRecord)sender;
3487
3488        synchronized (this) {
3489            // If this is coming from the currently resumed activity, it is
3490            // effectively saying that app switches are allowed at this point.
3491            final ActivityStack stack = getFocusedStack();
3492            if (stack.mResumedActivity != null &&
3493                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3494                mAppSwitchesAllowedTime = 0;
3495            }
3496        }
3497        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3498                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3499        return ret;
3500    }
3501
3502    @Override
3503    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3504            Intent intent, String resolvedType, IVoiceInteractionSession session,
3505            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3506            Bundle options, int userId) {
3507        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3508                != PackageManager.PERMISSION_GRANTED) {
3509            String msg = "Permission Denial: startVoiceActivity() from pid="
3510                    + Binder.getCallingPid()
3511                    + ", uid=" + Binder.getCallingUid()
3512                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3513            Slog.w(TAG, msg);
3514            throw new SecurityException(msg);
3515        }
3516        if (session == null || interactor == null) {
3517            throw new NullPointerException("null session or interactor");
3518        }
3519        userId = handleIncomingUser(callingPid, callingUid, userId,
3520                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3521        // TODO: Switch to user app stacks here.
3522        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3523                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3524                null, options, userId, null, null);
3525    }
3526
3527    @Override
3528    public boolean startNextMatchingActivity(IBinder callingActivity,
3529            Intent intent, Bundle options) {
3530        // Refuse possible leaked file descriptors
3531        if (intent != null && intent.hasFileDescriptors() == true) {
3532            throw new IllegalArgumentException("File descriptors passed in Intent");
3533        }
3534
3535        synchronized (this) {
3536            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3537            if (r == null) {
3538                ActivityOptions.abort(options);
3539                return false;
3540            }
3541            if (r.app == null || r.app.thread == null) {
3542                // The caller is not running...  d'oh!
3543                ActivityOptions.abort(options);
3544                return false;
3545            }
3546            intent = new Intent(intent);
3547            // The caller is not allowed to change the data.
3548            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3549            // And we are resetting to find the next component...
3550            intent.setComponent(null);
3551
3552            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3553
3554            ActivityInfo aInfo = null;
3555            try {
3556                List<ResolveInfo> resolves =
3557                    AppGlobals.getPackageManager().queryIntentActivities(
3558                            intent, r.resolvedType,
3559                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3560                            UserHandle.getCallingUserId());
3561
3562                // Look for the original activity in the list...
3563                final int N = resolves != null ? resolves.size() : 0;
3564                for (int i=0; i<N; i++) {
3565                    ResolveInfo rInfo = resolves.get(i);
3566                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3567                            && rInfo.activityInfo.name.equals(r.info.name)) {
3568                        // We found the current one...  the next matching is
3569                        // after it.
3570                        i++;
3571                        if (i<N) {
3572                            aInfo = resolves.get(i).activityInfo;
3573                        }
3574                        if (debug) {
3575                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3576                                    + "/" + r.info.name);
3577                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3578                                    + "/" + aInfo.name);
3579                        }
3580                        break;
3581                    }
3582                }
3583            } catch (RemoteException e) {
3584            }
3585
3586            if (aInfo == null) {
3587                // Nobody who is next!
3588                ActivityOptions.abort(options);
3589                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3590                return false;
3591            }
3592
3593            intent.setComponent(new ComponentName(
3594                    aInfo.applicationInfo.packageName, aInfo.name));
3595            intent.setFlags(intent.getFlags()&~(
3596                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3597                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3598                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3599                    Intent.FLAG_ACTIVITY_NEW_TASK));
3600
3601            // Okay now we need to start the new activity, replacing the
3602            // currently running activity.  This is a little tricky because
3603            // we want to start the new one as if the current one is finished,
3604            // but not finish the current one first so that there is no flicker.
3605            // And thus...
3606            final boolean wasFinishing = r.finishing;
3607            r.finishing = true;
3608
3609            // Propagate reply information over to the new activity.
3610            final ActivityRecord resultTo = r.resultTo;
3611            final String resultWho = r.resultWho;
3612            final int requestCode = r.requestCode;
3613            r.resultTo = null;
3614            if (resultTo != null) {
3615                resultTo.removeResultsLocked(r, resultWho, requestCode);
3616            }
3617
3618            final long origId = Binder.clearCallingIdentity();
3619            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3620                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3621                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3622                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3623            Binder.restoreCallingIdentity(origId);
3624
3625            r.finishing = wasFinishing;
3626            if (res != ActivityManager.START_SUCCESS) {
3627                return false;
3628            }
3629            return true;
3630        }
3631    }
3632
3633    @Override
3634    public final int startActivityFromRecents(int taskId, Bundle options) {
3635        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3636            String msg = "Permission Denial: startActivityFromRecents called without " +
3637                    START_TASKS_FROM_RECENTS;
3638            Slog.w(TAG, msg);
3639            throw new SecurityException(msg);
3640        }
3641        return startActivityFromRecentsInner(taskId, options);
3642    }
3643
3644    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3645        final TaskRecord task;
3646        final int callingUid;
3647        final String callingPackage;
3648        final Intent intent;
3649        final int userId;
3650        synchronized (this) {
3651            task = recentTaskForIdLocked(taskId);
3652            if (task == null) {
3653                throw new IllegalArgumentException("Task " + taskId + " not found.");
3654            }
3655            callingUid = task.mCallingUid;
3656            callingPackage = task.mCallingPackage;
3657            intent = task.intent;
3658            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3659            userId = task.userId;
3660        }
3661        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3662                options, userId, null, task);
3663    }
3664
3665    final int startActivityInPackage(int uid, String callingPackage,
3666            Intent intent, String resolvedType, IBinder resultTo,
3667            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3668            IActivityContainer container, TaskRecord inTask) {
3669
3670        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3671                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3672
3673        // TODO: Switch to user app stacks here.
3674        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3675                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3676                null, null, null, options, userId, container, inTask);
3677        return ret;
3678    }
3679
3680    @Override
3681    public final int startActivities(IApplicationThread caller, String callingPackage,
3682            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3683            int userId) {
3684        enforceNotIsolatedCaller("startActivities");
3685        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3686                false, ALLOW_FULL_ONLY, "startActivity", null);
3687        // TODO: Switch to user app stacks here.
3688        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3689                resolvedTypes, resultTo, options, userId);
3690        return ret;
3691    }
3692
3693    final int startActivitiesInPackage(int uid, String callingPackage,
3694            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3695            Bundle options, int userId) {
3696
3697        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3698                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3699        // TODO: Switch to user app stacks here.
3700        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3701                resultTo, options, userId);
3702        return ret;
3703    }
3704
3705    //explicitly remove thd old information in mRecentTasks when removing existing user.
3706    private void removeRecentTasksForUserLocked(int userId) {
3707        if(userId <= 0) {
3708            Slog.i(TAG, "Can't remove recent task on user " + userId);
3709            return;
3710        }
3711
3712        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3713            TaskRecord tr = mRecentTasks.get(i);
3714            if (tr.userId == userId) {
3715                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3716                        + " when finishing user" + userId);
3717                mRecentTasks.remove(i);
3718                tr.removedFromRecents(mTaskPersister);
3719            }
3720        }
3721
3722        // Remove tasks from persistent storage.
3723        mTaskPersister.wakeup(null, true);
3724    }
3725
3726    // Sort by taskId
3727    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3728        @Override
3729        public int compare(TaskRecord lhs, TaskRecord rhs) {
3730            return rhs.taskId - lhs.taskId;
3731        }
3732    };
3733
3734    // Extract the affiliates of the chain containing mRecentTasks[start].
3735    private int processNextAffiliateChain(int start) {
3736        final TaskRecord startTask = mRecentTasks.get(start);
3737        final int affiliateId = startTask.mAffiliatedTaskId;
3738
3739        // Quick identification of isolated tasks. I.e. those not launched behind.
3740        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3741                startTask.mNextAffiliate == null) {
3742            // There is still a slim chance that there are other tasks that point to this task
3743            // and that the chain is so messed up that this task no longer points to them but
3744            // the gain of this optimization outweighs the risk.
3745            startTask.inRecents = true;
3746            return start + 1;
3747        }
3748
3749        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3750        mTmpRecents.clear();
3751        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3752            final TaskRecord task = mRecentTasks.get(i);
3753            if (task.mAffiliatedTaskId == affiliateId) {
3754                mRecentTasks.remove(i);
3755                mTmpRecents.add(task);
3756            }
3757        }
3758
3759        // Sort them all by taskId. That is the order they were create in and that order will
3760        // always be correct.
3761        Collections.sort(mTmpRecents, mTaskRecordComparator);
3762
3763        // Go through and fix up the linked list.
3764        // The first one is the end of the chain and has no next.
3765        final TaskRecord first = mTmpRecents.get(0);
3766        first.inRecents = true;
3767        if (first.mNextAffiliate != null) {
3768            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3769            first.setNextAffiliate(null);
3770            mTaskPersister.wakeup(first, false);
3771        }
3772        // Everything in the middle is doubly linked from next to prev.
3773        final int tmpSize = mTmpRecents.size();
3774        for (int i = 0; i < tmpSize - 1; ++i) {
3775            final TaskRecord next = mTmpRecents.get(i);
3776            final TaskRecord prev = mTmpRecents.get(i + 1);
3777            if (next.mPrevAffiliate != prev) {
3778                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3779                        " setting prev=" + prev);
3780                next.setPrevAffiliate(prev);
3781                mTaskPersister.wakeup(next, false);
3782            }
3783            if (prev.mNextAffiliate != next) {
3784                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3785                        " setting next=" + next);
3786                prev.setNextAffiliate(next);
3787                mTaskPersister.wakeup(prev, false);
3788            }
3789            prev.inRecents = true;
3790        }
3791        // The last one is the beginning of the list and has no prev.
3792        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3793        if (last.mPrevAffiliate != null) {
3794            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3795            last.setPrevAffiliate(null);
3796            mTaskPersister.wakeup(last, false);
3797        }
3798
3799        // Insert the group back into mRecentTasks at start.
3800        mRecentTasks.addAll(start, mTmpRecents);
3801
3802        // Let the caller know where we left off.
3803        return start + tmpSize;
3804    }
3805
3806    /**
3807     * Update the recent tasks lists: make sure tasks should still be here (their
3808     * applications / activities still exist), update their availability, fixup ordering
3809     * of affiliations.
3810     */
3811    void cleanupRecentTasksLocked(int userId) {
3812        if (mRecentTasks == null) {
3813            // Happens when called from the packagemanager broadcast before boot.
3814            return;
3815        }
3816
3817        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3818        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3819        final IPackageManager pm = AppGlobals.getPackageManager();
3820        final ActivityInfo dummyAct = new ActivityInfo();
3821        final ApplicationInfo dummyApp = new ApplicationInfo();
3822
3823        int N = mRecentTasks.size();
3824
3825        int[] users = userId == UserHandle.USER_ALL
3826                ? getUsersLocked() : new int[] { userId };
3827        for (int user : users) {
3828            for (int i = 0; i < N; i++) {
3829                TaskRecord task = mRecentTasks.get(i);
3830                if (task.userId != user) {
3831                    // Only look at tasks for the user ID of interest.
3832                    continue;
3833                }
3834                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3835                    // This situation is broken, and we should just get rid of it now.
3836                    mRecentTasks.remove(i);
3837                    task.removedFromRecents(mTaskPersister);
3838                    i--;
3839                    N--;
3840                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3841                    continue;
3842                }
3843                // Check whether this activity is currently available.
3844                if (task.realActivity != null) {
3845                    ActivityInfo ai = availActCache.get(task.realActivity);
3846                    if (ai == null) {
3847                        try {
3848                            ai = pm.getActivityInfo(task.realActivity,
3849                                    PackageManager.GET_UNINSTALLED_PACKAGES
3850                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3851                        } catch (RemoteException e) {
3852                            // Will never happen.
3853                            continue;
3854                        }
3855                        if (ai == null) {
3856                            ai = dummyAct;
3857                        }
3858                        availActCache.put(task.realActivity, ai);
3859                    }
3860                    if (ai == dummyAct) {
3861                        // This could be either because the activity no longer exists, or the
3862                        // app is temporarily gone.  For the former we want to remove the recents
3863                        // entry; for the latter we want to mark it as unavailable.
3864                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3865                        if (app == null) {
3866                            try {
3867                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3868                                        PackageManager.GET_UNINSTALLED_PACKAGES
3869                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3870                            } catch (RemoteException e) {
3871                                // Will never happen.
3872                                continue;
3873                            }
3874                            if (app == null) {
3875                                app = dummyApp;
3876                            }
3877                            availAppCache.put(task.realActivity.getPackageName(), app);
3878                        }
3879                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3880                            // Doesn't exist any more!  Good-bye.
3881                            mRecentTasks.remove(i);
3882                            task.removedFromRecents(mTaskPersister);
3883                            i--;
3884                            N--;
3885                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3886                            continue;
3887                        } else {
3888                            // Otherwise just not available for now.
3889                            if (task.isAvailable) {
3890                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3891                                        + task);
3892                            }
3893                            task.isAvailable = false;
3894                        }
3895                    } else {
3896                        if (!ai.enabled || !ai.applicationInfo.enabled
3897                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3898                            if (task.isAvailable) {
3899                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3900                                        + task + " (enabled=" + ai.enabled + "/"
3901                                        + ai.applicationInfo.enabled +  " flags="
3902                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3903                            }
3904                            task.isAvailable = false;
3905                        } else {
3906                            if (!task.isAvailable) {
3907                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3908                                        + task);
3909                            }
3910                            task.isAvailable = true;
3911                        }
3912                    }
3913                }
3914            }
3915        }
3916
3917        // Verify the affiliate chain for each task.
3918        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3919        }
3920
3921        mTmpRecents.clear();
3922        // mRecentTasks is now in sorted, affiliated order.
3923    }
3924
3925    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3926        int N = mRecentTasks.size();
3927        TaskRecord top = task;
3928        int topIndex = taskIndex;
3929        while (top.mNextAffiliate != null && topIndex > 0) {
3930            top = top.mNextAffiliate;
3931            topIndex--;
3932        }
3933        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3934                + topIndex + " from intial " + taskIndex);
3935        // Find the end of the chain, doing a sanity check along the way.
3936        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3937        int endIndex = topIndex;
3938        TaskRecord prev = top;
3939        while (endIndex < N) {
3940            TaskRecord cur = mRecentTasks.get(endIndex);
3941            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3942                    + endIndex + " " + cur);
3943            if (cur == top) {
3944                // Verify start of the chain.
3945                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3946                    Slog.wtf(TAG, "Bad chain @" + endIndex
3947                            + ": first task has next affiliate: " + prev);
3948                    sane = false;
3949                    break;
3950                }
3951            } else {
3952                // Verify middle of the chain's next points back to the one before.
3953                if (cur.mNextAffiliate != prev
3954                        || cur.mNextAffiliateTaskId != prev.taskId) {
3955                    Slog.wtf(TAG, "Bad chain @" + endIndex
3956                            + ": middle task " + cur + " @" + endIndex
3957                            + " has bad next affiliate "
3958                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3959                            + ", expected " + prev);
3960                    sane = false;
3961                    break;
3962                }
3963            }
3964            if (cur.mPrevAffiliateTaskId == -1) {
3965                // Chain ends here.
3966                if (cur.mPrevAffiliate != null) {
3967                    Slog.wtf(TAG, "Bad chain @" + endIndex
3968                            + ": last task " + cur + " has previous affiliate "
3969                            + cur.mPrevAffiliate);
3970                    sane = false;
3971                }
3972                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3973                break;
3974            } else {
3975                // Verify middle of the chain's prev points to a valid item.
3976                if (cur.mPrevAffiliate == null) {
3977                    Slog.wtf(TAG, "Bad chain @" + endIndex
3978                            + ": task " + cur + " has previous affiliate "
3979                            + cur.mPrevAffiliate + " but should be id "
3980                            + cur.mPrevAffiliate);
3981                    sane = false;
3982                    break;
3983                }
3984            }
3985            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3986                Slog.wtf(TAG, "Bad chain @" + endIndex
3987                        + ": task " + cur + " has affiliated id "
3988                        + cur.mAffiliatedTaskId + " but should be "
3989                        + task.mAffiliatedTaskId);
3990                sane = false;
3991                break;
3992            }
3993            prev = cur;
3994            endIndex++;
3995            if (endIndex >= N) {
3996                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3997                        + ": last task " + prev);
3998                sane = false;
3999                break;
4000            }
4001        }
4002        if (sane) {
4003            if (endIndex < taskIndex) {
4004                Slog.wtf(TAG, "Bad chain @" + endIndex
4005                        + ": did not extend to task " + task + " @" + taskIndex);
4006                sane = false;
4007            }
4008        }
4009        if (sane) {
4010            // All looks good, we can just move all of the affiliated tasks
4011            // to the top.
4012            for (int i=topIndex; i<=endIndex; i++) {
4013                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4014                        + " from " + i + " to " + (i-topIndex));
4015                TaskRecord cur = mRecentTasks.remove(i);
4016                mRecentTasks.add(i-topIndex, cur);
4017            }
4018            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4019                    + " to " + endIndex);
4020            return true;
4021        }
4022
4023        // Whoops, couldn't do it.
4024        return false;
4025    }
4026
4027    final void addRecentTaskLocked(TaskRecord task) {
4028        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4029                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4030
4031        int N = mRecentTasks.size();
4032        // Quick case: check if the top-most recent task is the same.
4033        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4034            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4035            return;
4036        }
4037        // Another quick case: check if this is part of a set of affiliated
4038        // tasks that are at the top.
4039        if (isAffiliated && N > 0 && task.inRecents
4040                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4041            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4042                    + " at top when adding " + task);
4043            return;
4044        }
4045        // Another quick case: never add voice sessions.
4046        if (task.voiceSession != null) {
4047            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4048            return;
4049        }
4050
4051        boolean needAffiliationFix = false;
4052
4053        // Slightly less quick case: the task is already in recents, so all we need
4054        // to do is move it.
4055        if (task.inRecents) {
4056            int taskIndex = mRecentTasks.indexOf(task);
4057            if (taskIndex >= 0) {
4058                if (!isAffiliated) {
4059                    // Simple case: this is not an affiliated task, so we just move it to the front.
4060                    mRecentTasks.remove(taskIndex);
4061                    mRecentTasks.add(0, task);
4062                    notifyTaskPersisterLocked(task, false);
4063                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4064                            + " from " + taskIndex);
4065                    return;
4066                } else {
4067                    // More complicated: need to keep all affiliated tasks together.
4068                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4069                        // All went well.
4070                        return;
4071                    }
4072
4073                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4074                    // everything and then go through our general path of adding a new task.
4075                    needAffiliationFix = true;
4076                }
4077            } else {
4078                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4079                needAffiliationFix = true;
4080            }
4081        }
4082
4083        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4084        trimRecentsForTask(task, true);
4085
4086        N = mRecentTasks.size();
4087        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4088            final TaskRecord tr = mRecentTasks.remove(N - 1);
4089            tr.removedFromRecents(mTaskPersister);
4090            N--;
4091        }
4092        task.inRecents = true;
4093        if (!isAffiliated || needAffiliationFix) {
4094            // If this is a simple non-affiliated task, or we had some failure trying to
4095            // handle it as part of an affilated task, then just place it at the top.
4096            mRecentTasks.add(0, task);
4097        } else if (isAffiliated) {
4098            // If this is a new affiliated task, then move all of the affiliated tasks
4099            // to the front and insert this new one.
4100            TaskRecord other = task.mNextAffiliate;
4101            if (other == null) {
4102                other = task.mPrevAffiliate;
4103            }
4104            if (other != null) {
4105                int otherIndex = mRecentTasks.indexOf(other);
4106                if (otherIndex >= 0) {
4107                    // Insert new task at appropriate location.
4108                    int taskIndex;
4109                    if (other == task.mNextAffiliate) {
4110                        // We found the index of our next affiliation, which is who is
4111                        // before us in the list, so add after that point.
4112                        taskIndex = otherIndex+1;
4113                    } else {
4114                        // We found the index of our previous affiliation, which is who is
4115                        // after us in the list, so add at their position.
4116                        taskIndex = otherIndex;
4117                    }
4118                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4119                            + taskIndex + ": " + task);
4120                    mRecentTasks.add(taskIndex, task);
4121
4122                    // Now move everything to the front.
4123                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4124                        // All went well.
4125                        return;
4126                    }
4127
4128                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4129                    // everything and then go through our general path of adding a new task.
4130                    needAffiliationFix = true;
4131                } else {
4132                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4133                            + other);
4134                    needAffiliationFix = true;
4135                }
4136            } else {
4137                if (DEBUG_RECENTS) Slog.d(TAG,
4138                        "addRecent: adding affiliated task without next/prev:" + task);
4139                needAffiliationFix = true;
4140            }
4141        }
4142        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4143
4144        if (needAffiliationFix) {
4145            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4146            cleanupRecentTasksLocked(task.userId);
4147        }
4148    }
4149
4150    /**
4151     * If needed, remove oldest existing entries in recents that are for the same kind
4152     * of task as the given one.
4153     */
4154    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4155        int N = mRecentTasks.size();
4156        final Intent intent = task.intent;
4157        final boolean document = intent != null && intent.isDocument();
4158
4159        int maxRecents = task.maxRecents - 1;
4160        for (int i=0; i<N; i++) {
4161            final TaskRecord tr = mRecentTasks.get(i);
4162            if (task != tr) {
4163                if (task.userId != tr.userId) {
4164                    continue;
4165                }
4166                if (i > MAX_RECENT_BITMAPS) {
4167                    tr.freeLastThumbnail();
4168                }
4169                final Intent trIntent = tr.intent;
4170                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4171                    (intent == null || !intent.filterEquals(trIntent))) {
4172                    continue;
4173                }
4174                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4175                if (document && trIsDocument) {
4176                    // These are the same document activity (not necessarily the same doc).
4177                    if (maxRecents > 0) {
4178                        --maxRecents;
4179                        continue;
4180                    }
4181                    // Hit the maximum number of documents for this task. Fall through
4182                    // and remove this document from recents.
4183                } else if (document || trIsDocument) {
4184                    // Only one of these is a document. Not the droid we're looking for.
4185                    continue;
4186                }
4187            }
4188
4189            if (!doTrim) {
4190                // If the caller is not actually asking for a trim, just tell them we reached
4191                // a point where the trim would happen.
4192                return i;
4193            }
4194
4195            // Either task and tr are the same or, their affinities match or their intents match
4196            // and neither of them is a document, or they are documents using the same activity
4197            // and their maxRecents has been reached.
4198            tr.disposeThumbnail();
4199            mRecentTasks.remove(i);
4200            if (task != tr) {
4201                tr.removedFromRecents(mTaskPersister);
4202            }
4203            i--;
4204            N--;
4205            if (task.intent == null) {
4206                // If the new recent task we are adding is not fully
4207                // specified, then replace it with the existing recent task.
4208                task = tr;
4209            }
4210            notifyTaskPersisterLocked(tr, false);
4211        }
4212
4213        return -1;
4214    }
4215
4216    @Override
4217    public void reportActivityFullyDrawn(IBinder token) {
4218        synchronized (this) {
4219            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4220            if (r == null) {
4221                return;
4222            }
4223            r.reportFullyDrawnLocked();
4224        }
4225    }
4226
4227    @Override
4228    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4229        synchronized (this) {
4230            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4231            if (r == null) {
4232                return;
4233            }
4234            final long origId = Binder.clearCallingIdentity();
4235            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4236            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4237                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4238            if (config != null) {
4239                r.frozenBeforeDestroy = true;
4240                if (!updateConfigurationLocked(config, r, false, false)) {
4241                    mStackSupervisor.resumeTopActivitiesLocked();
4242                }
4243            }
4244            Binder.restoreCallingIdentity(origId);
4245        }
4246    }
4247
4248    @Override
4249    public int getRequestedOrientation(IBinder token) {
4250        synchronized (this) {
4251            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4252            if (r == null) {
4253                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4254            }
4255            return mWindowManager.getAppOrientation(r.appToken);
4256        }
4257    }
4258
4259    /**
4260     * This is the internal entry point for handling Activity.finish().
4261     *
4262     * @param token The Binder token referencing the Activity we want to finish.
4263     * @param resultCode Result code, if any, from this Activity.
4264     * @param resultData Result data (Intent), if any, from this Activity.
4265     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4266     *            the root Activity in the task.
4267     *
4268     * @return Returns true if the activity successfully finished, or false if it is still running.
4269     */
4270    @Override
4271    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4272            boolean finishTask) {
4273        // Refuse possible leaked file descriptors
4274        if (resultData != null && resultData.hasFileDescriptors() == true) {
4275            throw new IllegalArgumentException("File descriptors passed in Intent");
4276        }
4277
4278        synchronized(this) {
4279            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4280            if (r == null) {
4281                return true;
4282            }
4283            // Keep track of the root activity of the task before we finish it
4284            TaskRecord tr = r.task;
4285            ActivityRecord rootR = tr.getRootActivity();
4286            // Do not allow task to finish in Lock Task mode.
4287            if (tr == mStackSupervisor.mLockTaskModeTask) {
4288                if (rootR == r) {
4289                    mStackSupervisor.showLockTaskToast();
4290                    return false;
4291                }
4292            }
4293            if (mController != null) {
4294                // Find the first activity that is not finishing.
4295                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4296                if (next != null) {
4297                    // ask watcher if this is allowed
4298                    boolean resumeOK = true;
4299                    try {
4300                        resumeOK = mController.activityResuming(next.packageName);
4301                    } catch (RemoteException e) {
4302                        mController = null;
4303                        Watchdog.getInstance().setActivityController(null);
4304                    }
4305
4306                    if (!resumeOK) {
4307                        return false;
4308                    }
4309                }
4310            }
4311            final long origId = Binder.clearCallingIdentity();
4312            try {
4313                boolean res;
4314                if (finishTask && r == rootR) {
4315                    // If requested, remove the task that is associated to this activity only if it
4316                    // was the root activity in the task.  The result code and data is ignored because
4317                    // we don't support returning them across task boundaries.
4318                    res = removeTaskByIdLocked(tr.taskId, 0);
4319                } else {
4320                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4321                            resultData, "app-request", true);
4322                }
4323                return res;
4324            } finally {
4325                Binder.restoreCallingIdentity(origId);
4326            }
4327        }
4328    }
4329
4330    @Override
4331    public final void finishHeavyWeightApp() {
4332        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4333                != PackageManager.PERMISSION_GRANTED) {
4334            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4335                    + Binder.getCallingPid()
4336                    + ", uid=" + Binder.getCallingUid()
4337                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4338            Slog.w(TAG, msg);
4339            throw new SecurityException(msg);
4340        }
4341
4342        synchronized(this) {
4343            if (mHeavyWeightProcess == null) {
4344                return;
4345            }
4346
4347            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4348                    mHeavyWeightProcess.activities);
4349            for (int i=0; i<activities.size(); i++) {
4350                ActivityRecord r = activities.get(i);
4351                if (!r.finishing) {
4352                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4353                            null, "finish-heavy", true);
4354                }
4355            }
4356
4357            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4358                    mHeavyWeightProcess.userId, 0));
4359            mHeavyWeightProcess = null;
4360        }
4361    }
4362
4363    @Override
4364    public void crashApplication(int uid, int initialPid, String packageName,
4365            String message) {
4366        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4367                != PackageManager.PERMISSION_GRANTED) {
4368            String msg = "Permission Denial: crashApplication() from pid="
4369                    + Binder.getCallingPid()
4370                    + ", uid=" + Binder.getCallingUid()
4371                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4372            Slog.w(TAG, msg);
4373            throw new SecurityException(msg);
4374        }
4375
4376        synchronized(this) {
4377            ProcessRecord proc = null;
4378
4379            // Figure out which process to kill.  We don't trust that initialPid
4380            // still has any relation to current pids, so must scan through the
4381            // list.
4382            synchronized (mPidsSelfLocked) {
4383                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4384                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4385                    if (p.uid != uid) {
4386                        continue;
4387                    }
4388                    if (p.pid == initialPid) {
4389                        proc = p;
4390                        break;
4391                    }
4392                    if (p.pkgList.containsKey(packageName)) {
4393                        proc = p;
4394                    }
4395                }
4396            }
4397
4398            if (proc == null) {
4399                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4400                        + " initialPid=" + initialPid
4401                        + " packageName=" + packageName);
4402                return;
4403            }
4404
4405            if (proc.thread != null) {
4406                if (proc.pid == Process.myPid()) {
4407                    Log.w(TAG, "crashApplication: trying to crash self!");
4408                    return;
4409                }
4410                long ident = Binder.clearCallingIdentity();
4411                try {
4412                    proc.thread.scheduleCrash(message);
4413                } catch (RemoteException e) {
4414                }
4415                Binder.restoreCallingIdentity(ident);
4416            }
4417        }
4418    }
4419
4420    @Override
4421    public final void finishSubActivity(IBinder token, String resultWho,
4422            int requestCode) {
4423        synchronized(this) {
4424            final long origId = Binder.clearCallingIdentity();
4425            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4426            if (r != null) {
4427                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4428            }
4429            Binder.restoreCallingIdentity(origId);
4430        }
4431    }
4432
4433    @Override
4434    public boolean finishActivityAffinity(IBinder token) {
4435        synchronized(this) {
4436            final long origId = Binder.clearCallingIdentity();
4437            try {
4438                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4439
4440                ActivityRecord rootR = r.task.getRootActivity();
4441                // Do not allow task to finish in Lock Task mode.
4442                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4443                    if (rootR == r) {
4444                        mStackSupervisor.showLockTaskToast();
4445                        return false;
4446                    }
4447                }
4448                boolean res = false;
4449                if (r != null) {
4450                    res = r.task.stack.finishActivityAffinityLocked(r);
4451                }
4452                return res;
4453            } finally {
4454                Binder.restoreCallingIdentity(origId);
4455            }
4456        }
4457    }
4458
4459    @Override
4460    public void finishVoiceTask(IVoiceInteractionSession session) {
4461        synchronized(this) {
4462            final long origId = Binder.clearCallingIdentity();
4463            try {
4464                mStackSupervisor.finishVoiceTask(session);
4465            } finally {
4466                Binder.restoreCallingIdentity(origId);
4467            }
4468        }
4469
4470    }
4471
4472    @Override
4473    public boolean releaseActivityInstance(IBinder token) {
4474        synchronized(this) {
4475            final long origId = Binder.clearCallingIdentity();
4476            try {
4477                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4478                if (r.task == null || r.task.stack == null) {
4479                    return false;
4480                }
4481                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4482            } finally {
4483                Binder.restoreCallingIdentity(origId);
4484            }
4485        }
4486    }
4487
4488    @Override
4489    public void releaseSomeActivities(IApplicationThread appInt) {
4490        synchronized(this) {
4491            final long origId = Binder.clearCallingIdentity();
4492            try {
4493                ProcessRecord app = getRecordForAppLocked(appInt);
4494                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4495            } finally {
4496                Binder.restoreCallingIdentity(origId);
4497            }
4498        }
4499    }
4500
4501    @Override
4502    public boolean willActivityBeVisible(IBinder token) {
4503        synchronized(this) {
4504            ActivityStack stack = ActivityRecord.getStackLocked(token);
4505            if (stack != null) {
4506                return stack.willActivityBeVisibleLocked(token);
4507            }
4508            return false;
4509        }
4510    }
4511
4512    @Override
4513    public void overridePendingTransition(IBinder token, String packageName,
4514            int enterAnim, int exitAnim) {
4515        synchronized(this) {
4516            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4517            if (self == null) {
4518                return;
4519            }
4520
4521            final long origId = Binder.clearCallingIdentity();
4522
4523            if (self.state == ActivityState.RESUMED
4524                    || self.state == ActivityState.PAUSING) {
4525                mWindowManager.overridePendingAppTransition(packageName,
4526                        enterAnim, exitAnim, null);
4527            }
4528
4529            Binder.restoreCallingIdentity(origId);
4530        }
4531    }
4532
4533    /**
4534     * Main function for removing an existing process from the activity manager
4535     * as a result of that process going away.  Clears out all connections
4536     * to the process.
4537     */
4538    private final void handleAppDiedLocked(ProcessRecord app,
4539            boolean restarting, boolean allowRestart) {
4540        int pid = app.pid;
4541        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4542        if (!kept && !restarting) {
4543            removeLruProcessLocked(app);
4544            if (pid > 0) {
4545                ProcessList.remove(pid);
4546            }
4547        }
4548
4549        if (mProfileProc == app) {
4550            clearProfilerLocked();
4551        }
4552
4553        // Remove this application's activities from active lists.
4554        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4555
4556        app.activities.clear();
4557
4558        if (app.instrumentationClass != null) {
4559            Slog.w(TAG, "Crash of app " + app.processName
4560                  + " running instrumentation " + app.instrumentationClass);
4561            Bundle info = new Bundle();
4562            info.putString("shortMsg", "Process crashed.");
4563            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4564        }
4565
4566        if (!restarting) {
4567            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4568                // If there was nothing to resume, and we are not already
4569                // restarting this process, but there is a visible activity that
4570                // is hosted by the process...  then make sure all visible
4571                // activities are running, taking care of restarting this
4572                // process.
4573                if (hasVisibleActivities) {
4574                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4575                }
4576            }
4577        }
4578    }
4579
4580    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4581        IBinder threadBinder = thread.asBinder();
4582        // Find the application record.
4583        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4584            ProcessRecord rec = mLruProcesses.get(i);
4585            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4586                return i;
4587            }
4588        }
4589        return -1;
4590    }
4591
4592    final ProcessRecord getRecordForAppLocked(
4593            IApplicationThread thread) {
4594        if (thread == null) {
4595            return null;
4596        }
4597
4598        int appIndex = getLRURecordIndexForAppLocked(thread);
4599        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4600    }
4601
4602    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4603        // If there are no longer any background processes running,
4604        // and the app that died was not running instrumentation,
4605        // then tell everyone we are now low on memory.
4606        boolean haveBg = false;
4607        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4608            ProcessRecord rec = mLruProcesses.get(i);
4609            if (rec.thread != null
4610                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4611                haveBg = true;
4612                break;
4613            }
4614        }
4615
4616        if (!haveBg) {
4617            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4618            if (doReport) {
4619                long now = SystemClock.uptimeMillis();
4620                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4621                    doReport = false;
4622                } else {
4623                    mLastMemUsageReportTime = now;
4624                }
4625            }
4626            final ArrayList<ProcessMemInfo> memInfos
4627                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4628            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4629            long now = SystemClock.uptimeMillis();
4630            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4631                ProcessRecord rec = mLruProcesses.get(i);
4632                if (rec == dyingProc || rec.thread == null) {
4633                    continue;
4634                }
4635                if (doReport) {
4636                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4637                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4638                }
4639                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4640                    // The low memory report is overriding any current
4641                    // state for a GC request.  Make sure to do
4642                    // heavy/important/visible/foreground processes first.
4643                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4644                        rec.lastRequestedGc = 0;
4645                    } else {
4646                        rec.lastRequestedGc = rec.lastLowMemory;
4647                    }
4648                    rec.reportLowMemory = true;
4649                    rec.lastLowMemory = now;
4650                    mProcessesToGc.remove(rec);
4651                    addProcessToGcListLocked(rec);
4652                }
4653            }
4654            if (doReport) {
4655                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4656                mHandler.sendMessage(msg);
4657            }
4658            scheduleAppGcsLocked();
4659        }
4660    }
4661
4662    final void appDiedLocked(ProcessRecord app) {
4663       appDiedLocked(app, app.pid, app.thread);
4664    }
4665
4666    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4667        // First check if this ProcessRecord is actually active for the pid.
4668        synchronized (mPidsSelfLocked) {
4669            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4670            if (curProc != app) {
4671                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4672                return;
4673            }
4674        }
4675
4676        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4677        synchronized (stats) {
4678            stats.noteProcessDiedLocked(app.info.uid, pid);
4679        }
4680
4681        Process.killProcessQuiet(pid);
4682        Process.killProcessGroup(app.info.uid, pid);
4683        app.killed = true;
4684
4685        // Clean up already done if the process has been re-started.
4686        if (app.pid == pid && app.thread != null &&
4687                app.thread.asBinder() == thread.asBinder()) {
4688            boolean doLowMem = app.instrumentationClass == null;
4689            boolean doOomAdj = doLowMem;
4690            if (!app.killedByAm) {
4691                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4692                        + ") has died");
4693                mAllowLowerMemLevel = true;
4694            } else {
4695                // Note that we always want to do oom adj to update our state with the
4696                // new number of procs.
4697                mAllowLowerMemLevel = false;
4698                doLowMem = false;
4699            }
4700            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4701            if (DEBUG_CLEANUP) Slog.v(
4702                TAG, "Dying app: " + app + ", pid: " + pid
4703                + ", thread: " + thread.asBinder());
4704            handleAppDiedLocked(app, false, true);
4705
4706            if (doOomAdj) {
4707                updateOomAdjLocked();
4708            }
4709            if (doLowMem) {
4710                doLowMemReportIfNeededLocked(app);
4711            }
4712        } else if (app.pid != pid) {
4713            // A new process has already been started.
4714            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4715                    + ") has died and restarted (pid " + app.pid + ").");
4716            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4717        } else if (DEBUG_PROCESSES) {
4718            Slog.d(TAG, "Received spurious death notification for thread "
4719                    + thread.asBinder());
4720        }
4721    }
4722
4723    /**
4724     * If a stack trace dump file is configured, dump process stack traces.
4725     * @param clearTraces causes the dump file to be erased prior to the new
4726     *    traces being written, if true; when false, the new traces will be
4727     *    appended to any existing file content.
4728     * @param firstPids of dalvik VM processes to dump stack traces for first
4729     * @param lastPids of dalvik VM processes to dump stack traces for last
4730     * @param nativeProcs optional list of native process names to dump stack crawls
4731     * @return file containing stack traces, or null if no dump file is configured
4732     */
4733    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4734            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4735        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4736        if (tracesPath == null || tracesPath.length() == 0) {
4737            return null;
4738        }
4739
4740        File tracesFile = new File(tracesPath);
4741        try {
4742            File tracesDir = tracesFile.getParentFile();
4743            if (!tracesDir.exists()) {
4744                tracesDir.mkdirs();
4745                if (!SELinux.restorecon(tracesDir)) {
4746                    return null;
4747                }
4748            }
4749            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4750
4751            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4752            tracesFile.createNewFile();
4753            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4754        } catch (IOException e) {
4755            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4756            return null;
4757        }
4758
4759        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4760        return tracesFile;
4761    }
4762
4763    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4764            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4765        // Use a FileObserver to detect when traces finish writing.
4766        // The order of traces is considered important to maintain for legibility.
4767        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4768            @Override
4769            public synchronized void onEvent(int event, String path) { notify(); }
4770        };
4771
4772        try {
4773            observer.startWatching();
4774
4775            // First collect all of the stacks of the most important pids.
4776            if (firstPids != null) {
4777                try {
4778                    int num = firstPids.size();
4779                    for (int i = 0; i < num; i++) {
4780                        synchronized (observer) {
4781                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4782                            observer.wait(200);  // Wait for write-close, give up after 200msec
4783                        }
4784                    }
4785                } catch (InterruptedException e) {
4786                    Slog.wtf(TAG, e);
4787                }
4788            }
4789
4790            // Next collect the stacks of the native pids
4791            if (nativeProcs != null) {
4792                int[] pids = Process.getPidsForCommands(nativeProcs);
4793                if (pids != null) {
4794                    for (int pid : pids) {
4795                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4796                    }
4797                }
4798            }
4799
4800            // Lastly, measure CPU usage.
4801            if (processCpuTracker != null) {
4802                processCpuTracker.init();
4803                System.gc();
4804                processCpuTracker.update();
4805                try {
4806                    synchronized (processCpuTracker) {
4807                        processCpuTracker.wait(500); // measure over 1/2 second.
4808                    }
4809                } catch (InterruptedException e) {
4810                }
4811                processCpuTracker.update();
4812
4813                // We'll take the stack crawls of just the top apps using CPU.
4814                final int N = processCpuTracker.countWorkingStats();
4815                int numProcs = 0;
4816                for (int i=0; i<N && numProcs<5; i++) {
4817                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4818                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4819                        numProcs++;
4820                        try {
4821                            synchronized (observer) {
4822                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4823                                observer.wait(200);  // Wait for write-close, give up after 200msec
4824                            }
4825                        } catch (InterruptedException e) {
4826                            Slog.wtf(TAG, e);
4827                        }
4828
4829                    }
4830                }
4831            }
4832        } finally {
4833            observer.stopWatching();
4834        }
4835    }
4836
4837    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4838        if (true || IS_USER_BUILD) {
4839            return;
4840        }
4841        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4842        if (tracesPath == null || tracesPath.length() == 0) {
4843            return;
4844        }
4845
4846        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4847        StrictMode.allowThreadDiskWrites();
4848        try {
4849            final File tracesFile = new File(tracesPath);
4850            final File tracesDir = tracesFile.getParentFile();
4851            final File tracesTmp = new File(tracesDir, "__tmp__");
4852            try {
4853                if (!tracesDir.exists()) {
4854                    tracesDir.mkdirs();
4855                    if (!SELinux.restorecon(tracesDir.getPath())) {
4856                        return;
4857                    }
4858                }
4859                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4860
4861                if (tracesFile.exists()) {
4862                    tracesTmp.delete();
4863                    tracesFile.renameTo(tracesTmp);
4864                }
4865                StringBuilder sb = new StringBuilder();
4866                Time tobj = new Time();
4867                tobj.set(System.currentTimeMillis());
4868                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4869                sb.append(": ");
4870                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4871                sb.append(" since ");
4872                sb.append(msg);
4873                FileOutputStream fos = new FileOutputStream(tracesFile);
4874                fos.write(sb.toString().getBytes());
4875                if (app == null) {
4876                    fos.write("\n*** No application process!".getBytes());
4877                }
4878                fos.close();
4879                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4880            } catch (IOException e) {
4881                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4882                return;
4883            }
4884
4885            if (app != null) {
4886                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4887                firstPids.add(app.pid);
4888                dumpStackTraces(tracesPath, firstPids, null, null, null);
4889            }
4890
4891            File lastTracesFile = null;
4892            File curTracesFile = null;
4893            for (int i=9; i>=0; i--) {
4894                String name = String.format(Locale.US, "slow%02d.txt", i);
4895                curTracesFile = new File(tracesDir, name);
4896                if (curTracesFile.exists()) {
4897                    if (lastTracesFile != null) {
4898                        curTracesFile.renameTo(lastTracesFile);
4899                    } else {
4900                        curTracesFile.delete();
4901                    }
4902                }
4903                lastTracesFile = curTracesFile;
4904            }
4905            tracesFile.renameTo(curTracesFile);
4906            if (tracesTmp.exists()) {
4907                tracesTmp.renameTo(tracesFile);
4908            }
4909        } finally {
4910            StrictMode.setThreadPolicy(oldPolicy);
4911        }
4912    }
4913
4914    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4915            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4916        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4917        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4918
4919        if (mController != null) {
4920            try {
4921                // 0 == continue, -1 = kill process immediately
4922                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4923                if (res < 0 && app.pid != MY_PID) {
4924                    app.kill("anr", true);
4925                }
4926            } catch (RemoteException e) {
4927                mController = null;
4928                Watchdog.getInstance().setActivityController(null);
4929            }
4930        }
4931
4932        long anrTime = SystemClock.uptimeMillis();
4933        if (MONITOR_CPU_USAGE) {
4934            updateCpuStatsNow();
4935        }
4936
4937        synchronized (this) {
4938            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4939            if (mShuttingDown) {
4940                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4941                return;
4942            } else if (app.notResponding) {
4943                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4944                return;
4945            } else if (app.crashing) {
4946                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4947                return;
4948            }
4949
4950            // In case we come through here for the same app before completing
4951            // this one, mark as anring now so we will bail out.
4952            app.notResponding = true;
4953
4954            // Log the ANR to the event log.
4955            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4956                    app.processName, app.info.flags, annotation);
4957
4958            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4959            firstPids.add(app.pid);
4960
4961            int parentPid = app.pid;
4962            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4963            if (parentPid != app.pid) firstPids.add(parentPid);
4964
4965            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4966
4967            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4968                ProcessRecord r = mLruProcesses.get(i);
4969                if (r != null && r.thread != null) {
4970                    int pid = r.pid;
4971                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4972                        if (r.persistent) {
4973                            firstPids.add(pid);
4974                        } else {
4975                            lastPids.put(pid, Boolean.TRUE);
4976                        }
4977                    }
4978                }
4979            }
4980        }
4981
4982        // Log the ANR to the main log.
4983        StringBuilder info = new StringBuilder();
4984        info.setLength(0);
4985        info.append("ANR in ").append(app.processName);
4986        if (activity != null && activity.shortComponentName != null) {
4987            info.append(" (").append(activity.shortComponentName).append(")");
4988        }
4989        info.append("\n");
4990        info.append("PID: ").append(app.pid).append("\n");
4991        if (annotation != null) {
4992            info.append("Reason: ").append(annotation).append("\n");
4993        }
4994        if (parent != null && parent != activity) {
4995            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4996        }
4997
4998        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4999
5000        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5001                NATIVE_STACKS_OF_INTEREST);
5002
5003        String cpuInfo = null;
5004        if (MONITOR_CPU_USAGE) {
5005            updateCpuStatsNow();
5006            synchronized (mProcessCpuTracker) {
5007                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5008            }
5009            info.append(processCpuTracker.printCurrentLoad());
5010            info.append(cpuInfo);
5011        }
5012
5013        info.append(processCpuTracker.printCurrentState(anrTime));
5014
5015        Slog.e(TAG, info.toString());
5016        if (tracesFile == null) {
5017            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5018            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5019        }
5020
5021        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5022                cpuInfo, tracesFile, null);
5023
5024        if (mController != null) {
5025            try {
5026                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5027                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5028                if (res != 0) {
5029                    if (res < 0 && app.pid != MY_PID) {
5030                        app.kill("anr", true);
5031                    } else {
5032                        synchronized (this) {
5033                            mServices.scheduleServiceTimeoutLocked(app);
5034                        }
5035                    }
5036                    return;
5037                }
5038            } catch (RemoteException e) {
5039                mController = null;
5040                Watchdog.getInstance().setActivityController(null);
5041            }
5042        }
5043
5044        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5045        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5046                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5047
5048        synchronized (this) {
5049            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5050                app.kill("bg anr", true);
5051                return;
5052            }
5053
5054            // Set the app's notResponding state, and look up the errorReportReceiver
5055            makeAppNotRespondingLocked(app,
5056                    activity != null ? activity.shortComponentName : null,
5057                    annotation != null ? "ANR " + annotation : "ANR",
5058                    info.toString());
5059
5060            // Bring up the infamous App Not Responding dialog
5061            Message msg = Message.obtain();
5062            HashMap<String, Object> map = new HashMap<String, Object>();
5063            msg.what = SHOW_NOT_RESPONDING_MSG;
5064            msg.obj = map;
5065            msg.arg1 = aboveSystem ? 1 : 0;
5066            map.put("app", app);
5067            if (activity != null) {
5068                map.put("activity", activity);
5069            }
5070
5071            mHandler.sendMessage(msg);
5072        }
5073    }
5074
5075    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5076        if (!mLaunchWarningShown) {
5077            mLaunchWarningShown = true;
5078            mHandler.post(new Runnable() {
5079                @Override
5080                public void run() {
5081                    synchronized (ActivityManagerService.this) {
5082                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5083                        d.show();
5084                        mHandler.postDelayed(new Runnable() {
5085                            @Override
5086                            public void run() {
5087                                synchronized (ActivityManagerService.this) {
5088                                    d.dismiss();
5089                                    mLaunchWarningShown = false;
5090                                }
5091                            }
5092                        }, 4000);
5093                    }
5094                }
5095            });
5096        }
5097    }
5098
5099    @Override
5100    public boolean clearApplicationUserData(final String packageName,
5101            final IPackageDataObserver observer, int userId) {
5102        enforceNotIsolatedCaller("clearApplicationUserData");
5103        int uid = Binder.getCallingUid();
5104        int pid = Binder.getCallingPid();
5105        userId = handleIncomingUser(pid, uid,
5106                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5107        long callingId = Binder.clearCallingIdentity();
5108        try {
5109            IPackageManager pm = AppGlobals.getPackageManager();
5110            int pkgUid = -1;
5111            synchronized(this) {
5112                try {
5113                    pkgUid = pm.getPackageUid(packageName, userId);
5114                } catch (RemoteException e) {
5115                }
5116                if (pkgUid == -1) {
5117                    Slog.w(TAG, "Invalid packageName: " + packageName);
5118                    if (observer != null) {
5119                        try {
5120                            observer.onRemoveCompleted(packageName, false);
5121                        } catch (RemoteException e) {
5122                            Slog.i(TAG, "Observer no longer exists.");
5123                        }
5124                    }
5125                    return false;
5126                }
5127                if (uid == pkgUid || checkComponentPermission(
5128                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5129                        pid, uid, -1, true)
5130                        == PackageManager.PERMISSION_GRANTED) {
5131                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5132                } else {
5133                    throw new SecurityException("PID " + pid + " does not have permission "
5134                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5135                                    + " of package " + packageName);
5136                }
5137
5138                // Remove all tasks match the cleared application package and user
5139                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5140                    final TaskRecord tr = mRecentTasks.get(i);
5141                    final String taskPackageName =
5142                            tr.getBaseIntent().getComponent().getPackageName();
5143                    if (tr.userId != userId) continue;
5144                    if (!taskPackageName.equals(packageName)) continue;
5145                    removeTaskByIdLocked(tr.taskId, 0);
5146                }
5147            }
5148
5149            try {
5150                // Clear application user data
5151                pm.clearApplicationUserData(packageName, observer, userId);
5152
5153                synchronized(this) {
5154                    // Remove all permissions granted from/to this package
5155                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5156                }
5157
5158                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5159                        Uri.fromParts("package", packageName, null));
5160                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5161                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5162                        null, null, 0, null, null, null, false, false, userId);
5163            } catch (RemoteException e) {
5164            }
5165        } finally {
5166            Binder.restoreCallingIdentity(callingId);
5167        }
5168        return true;
5169    }
5170
5171    @Override
5172    public void killBackgroundProcesses(final String packageName, int userId) {
5173        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5174                != PackageManager.PERMISSION_GRANTED &&
5175                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5176                        != PackageManager.PERMISSION_GRANTED) {
5177            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5178                    + Binder.getCallingPid()
5179                    + ", uid=" + Binder.getCallingUid()
5180                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5181            Slog.w(TAG, msg);
5182            throw new SecurityException(msg);
5183        }
5184
5185        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5186                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5187        long callingId = Binder.clearCallingIdentity();
5188        try {
5189            IPackageManager pm = AppGlobals.getPackageManager();
5190            synchronized(this) {
5191                int appId = -1;
5192                try {
5193                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5194                } catch (RemoteException e) {
5195                }
5196                if (appId == -1) {
5197                    Slog.w(TAG, "Invalid packageName: " + packageName);
5198                    return;
5199                }
5200                killPackageProcessesLocked(packageName, appId, userId,
5201                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5202            }
5203        } finally {
5204            Binder.restoreCallingIdentity(callingId);
5205        }
5206    }
5207
5208    @Override
5209    public void killAllBackgroundProcesses() {
5210        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5211                != PackageManager.PERMISSION_GRANTED) {
5212            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5213                    + Binder.getCallingPid()
5214                    + ", uid=" + Binder.getCallingUid()
5215                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5216            Slog.w(TAG, msg);
5217            throw new SecurityException(msg);
5218        }
5219
5220        long callingId = Binder.clearCallingIdentity();
5221        try {
5222            synchronized(this) {
5223                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5224                final int NP = mProcessNames.getMap().size();
5225                for (int ip=0; ip<NP; ip++) {
5226                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5227                    final int NA = apps.size();
5228                    for (int ia=0; ia<NA; ia++) {
5229                        ProcessRecord app = apps.valueAt(ia);
5230                        if (app.persistent) {
5231                            // we don't kill persistent processes
5232                            continue;
5233                        }
5234                        if (app.removed) {
5235                            procs.add(app);
5236                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5237                            app.removed = true;
5238                            procs.add(app);
5239                        }
5240                    }
5241                }
5242
5243                int N = procs.size();
5244                for (int i=0; i<N; i++) {
5245                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5246                }
5247                mAllowLowerMemLevel = true;
5248                updateOomAdjLocked();
5249                doLowMemReportIfNeededLocked(null);
5250            }
5251        } finally {
5252            Binder.restoreCallingIdentity(callingId);
5253        }
5254    }
5255
5256    @Override
5257    public void forceStopPackage(final String packageName, int userId) {
5258        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5259                != PackageManager.PERMISSION_GRANTED) {
5260            String msg = "Permission Denial: forceStopPackage() from pid="
5261                    + Binder.getCallingPid()
5262                    + ", uid=" + Binder.getCallingUid()
5263                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5264            Slog.w(TAG, msg);
5265            throw new SecurityException(msg);
5266        }
5267        final int callingPid = Binder.getCallingPid();
5268        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5269                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5270        long callingId = Binder.clearCallingIdentity();
5271        try {
5272            IPackageManager pm = AppGlobals.getPackageManager();
5273            synchronized(this) {
5274                int[] users = userId == UserHandle.USER_ALL
5275                        ? getUsersLocked() : new int[] { userId };
5276                for (int user : users) {
5277                    int pkgUid = -1;
5278                    try {
5279                        pkgUid = pm.getPackageUid(packageName, user);
5280                    } catch (RemoteException e) {
5281                    }
5282                    if (pkgUid == -1) {
5283                        Slog.w(TAG, "Invalid packageName: " + packageName);
5284                        continue;
5285                    }
5286                    try {
5287                        pm.setPackageStoppedState(packageName, true, user);
5288                    } catch (RemoteException e) {
5289                    } catch (IllegalArgumentException e) {
5290                        Slog.w(TAG, "Failed trying to unstop package "
5291                                + packageName + ": " + e);
5292                    }
5293                    if (isUserRunningLocked(user, false)) {
5294                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5295                    }
5296                }
5297            }
5298        } finally {
5299            Binder.restoreCallingIdentity(callingId);
5300        }
5301    }
5302
5303    @Override
5304    public void addPackageDependency(String packageName) {
5305        synchronized (this) {
5306            int callingPid = Binder.getCallingPid();
5307            if (callingPid == Process.myPid()) {
5308                //  Yeah, um, no.
5309                Slog.w(TAG, "Can't addPackageDependency on system process");
5310                return;
5311            }
5312            ProcessRecord proc;
5313            synchronized (mPidsSelfLocked) {
5314                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5315            }
5316            if (proc != null) {
5317                if (proc.pkgDeps == null) {
5318                    proc.pkgDeps = new ArraySet<String>(1);
5319                }
5320                proc.pkgDeps.add(packageName);
5321            }
5322        }
5323    }
5324
5325    /*
5326     * The pkg name and app id have to be specified.
5327     */
5328    @Override
5329    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5330        if (pkg == null) {
5331            return;
5332        }
5333        // Make sure the uid is valid.
5334        if (appid < 0) {
5335            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5336            return;
5337        }
5338        int callerUid = Binder.getCallingUid();
5339        // Only the system server can kill an application
5340        if (callerUid == Process.SYSTEM_UID) {
5341            // Post an aysnc message to kill the application
5342            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5343            msg.arg1 = appid;
5344            msg.arg2 = 0;
5345            Bundle bundle = new Bundle();
5346            bundle.putString("pkg", pkg);
5347            bundle.putString("reason", reason);
5348            msg.obj = bundle;
5349            mHandler.sendMessage(msg);
5350        } else {
5351            throw new SecurityException(callerUid + " cannot kill pkg: " +
5352                    pkg);
5353        }
5354    }
5355
5356    @Override
5357    public void closeSystemDialogs(String reason) {
5358        enforceNotIsolatedCaller("closeSystemDialogs");
5359
5360        final int pid = Binder.getCallingPid();
5361        final int uid = Binder.getCallingUid();
5362        final long origId = Binder.clearCallingIdentity();
5363        try {
5364            synchronized (this) {
5365                // Only allow this from foreground processes, so that background
5366                // applications can't abuse it to prevent system UI from being shown.
5367                if (uid >= Process.FIRST_APPLICATION_UID) {
5368                    ProcessRecord proc;
5369                    synchronized (mPidsSelfLocked) {
5370                        proc = mPidsSelfLocked.get(pid);
5371                    }
5372                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5373                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5374                                + " from background process " + proc);
5375                        return;
5376                    }
5377                }
5378                closeSystemDialogsLocked(reason);
5379            }
5380        } finally {
5381            Binder.restoreCallingIdentity(origId);
5382        }
5383    }
5384
5385    void closeSystemDialogsLocked(String reason) {
5386        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5387        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5388                | Intent.FLAG_RECEIVER_FOREGROUND);
5389        if (reason != null) {
5390            intent.putExtra("reason", reason);
5391        }
5392        mWindowManager.closeSystemDialogs(reason);
5393
5394        mStackSupervisor.closeSystemDialogsLocked();
5395
5396        broadcastIntentLocked(null, null, intent, null,
5397                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5398                Process.SYSTEM_UID, UserHandle.USER_ALL);
5399    }
5400
5401    @Override
5402    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5403        enforceNotIsolatedCaller("getProcessMemoryInfo");
5404        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5405        for (int i=pids.length-1; i>=0; i--) {
5406            ProcessRecord proc;
5407            int oomAdj;
5408            synchronized (this) {
5409                synchronized (mPidsSelfLocked) {
5410                    proc = mPidsSelfLocked.get(pids[i]);
5411                    oomAdj = proc != null ? proc.setAdj : 0;
5412                }
5413            }
5414            infos[i] = new Debug.MemoryInfo();
5415            Debug.getMemoryInfo(pids[i], infos[i]);
5416            if (proc != null) {
5417                synchronized (this) {
5418                    if (proc.thread != null && proc.setAdj == oomAdj) {
5419                        // Record this for posterity if the process has been stable.
5420                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5421                                infos[i].getTotalUss(), false, proc.pkgList);
5422                    }
5423                }
5424            }
5425        }
5426        return infos;
5427    }
5428
5429    @Override
5430    public long[] getProcessPss(int[] pids) {
5431        enforceNotIsolatedCaller("getProcessPss");
5432        long[] pss = new long[pids.length];
5433        for (int i=pids.length-1; i>=0; i--) {
5434            ProcessRecord proc;
5435            int oomAdj;
5436            synchronized (this) {
5437                synchronized (mPidsSelfLocked) {
5438                    proc = mPidsSelfLocked.get(pids[i]);
5439                    oomAdj = proc != null ? proc.setAdj : 0;
5440                }
5441            }
5442            long[] tmpUss = new long[1];
5443            pss[i] = Debug.getPss(pids[i], tmpUss);
5444            if (proc != null) {
5445                synchronized (this) {
5446                    if (proc.thread != null && proc.setAdj == oomAdj) {
5447                        // Record this for posterity if the process has been stable.
5448                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5449                    }
5450                }
5451            }
5452        }
5453        return pss;
5454    }
5455
5456    @Override
5457    public void killApplicationProcess(String processName, int uid) {
5458        if (processName == null) {
5459            return;
5460        }
5461
5462        int callerUid = Binder.getCallingUid();
5463        // Only the system server can kill an application
5464        if (callerUid == Process.SYSTEM_UID) {
5465            synchronized (this) {
5466                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5467                if (app != null && app.thread != null) {
5468                    try {
5469                        app.thread.scheduleSuicide();
5470                    } catch (RemoteException e) {
5471                        // If the other end already died, then our work here is done.
5472                    }
5473                } else {
5474                    Slog.w(TAG, "Process/uid not found attempting kill of "
5475                            + processName + " / " + uid);
5476                }
5477            }
5478        } else {
5479            throw new SecurityException(callerUid + " cannot kill app process: " +
5480                    processName);
5481        }
5482    }
5483
5484    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5485        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5486                false, true, false, false, UserHandle.getUserId(uid), reason);
5487        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5488                Uri.fromParts("package", packageName, null));
5489        if (!mProcessesReady) {
5490            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5491                    | Intent.FLAG_RECEIVER_FOREGROUND);
5492        }
5493        intent.putExtra(Intent.EXTRA_UID, uid);
5494        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5495        broadcastIntentLocked(null, null, intent,
5496                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5497                false, false,
5498                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5499    }
5500
5501    private void forceStopUserLocked(int userId, String reason) {
5502        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5503        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5504        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5505                | Intent.FLAG_RECEIVER_FOREGROUND);
5506        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5507        broadcastIntentLocked(null, null, intent,
5508                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5509                false, false,
5510                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5511    }
5512
5513    private final boolean killPackageProcessesLocked(String packageName, int appId,
5514            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5515            boolean doit, boolean evenPersistent, String reason) {
5516        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5517
5518        // Remove all processes this package may have touched: all with the
5519        // same UID (except for the system or root user), and all whose name
5520        // matches the package name.
5521        final int NP = mProcessNames.getMap().size();
5522        for (int ip=0; ip<NP; ip++) {
5523            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5524            final int NA = apps.size();
5525            for (int ia=0; ia<NA; ia++) {
5526                ProcessRecord app = apps.valueAt(ia);
5527                if (app.persistent && !evenPersistent) {
5528                    // we don't kill persistent processes
5529                    continue;
5530                }
5531                if (app.removed) {
5532                    if (doit) {
5533                        procs.add(app);
5534                    }
5535                    continue;
5536                }
5537
5538                // Skip process if it doesn't meet our oom adj requirement.
5539                if (app.setAdj < minOomAdj) {
5540                    continue;
5541                }
5542
5543                // If no package is specified, we call all processes under the
5544                // give user id.
5545                if (packageName == null) {
5546                    if (app.userId != userId) {
5547                        continue;
5548                    }
5549                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5550                        continue;
5551                    }
5552                // Package has been specified, we want to hit all processes
5553                // that match it.  We need to qualify this by the processes
5554                // that are running under the specified app and user ID.
5555                } else {
5556                    final boolean isDep = app.pkgDeps != null
5557                            && app.pkgDeps.contains(packageName);
5558                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5559                        continue;
5560                    }
5561                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5562                        continue;
5563                    }
5564                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5565                        continue;
5566                    }
5567                }
5568
5569                // Process has passed all conditions, kill it!
5570                if (!doit) {
5571                    return true;
5572                }
5573                app.removed = true;
5574                procs.add(app);
5575            }
5576        }
5577
5578        int N = procs.size();
5579        for (int i=0; i<N; i++) {
5580            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5581        }
5582        updateOomAdjLocked();
5583        return N > 0;
5584    }
5585
5586    private final boolean forceStopPackageLocked(String name, int appId,
5587            boolean callerWillRestart, boolean purgeCache, boolean doit,
5588            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5589        int i;
5590        int N;
5591
5592        if (userId == UserHandle.USER_ALL && name == null) {
5593            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5594        }
5595
5596        if (appId < 0 && name != null) {
5597            try {
5598                appId = UserHandle.getAppId(
5599                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5600            } catch (RemoteException e) {
5601            }
5602        }
5603
5604        if (doit) {
5605            if (name != null) {
5606                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5607                        + " user=" + userId + ": " + reason);
5608            } else {
5609                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5610            }
5611
5612            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5613            for (int ip=pmap.size()-1; ip>=0; ip--) {
5614                SparseArray<Long> ba = pmap.valueAt(ip);
5615                for (i=ba.size()-1; i>=0; i--) {
5616                    boolean remove = false;
5617                    final int entUid = ba.keyAt(i);
5618                    if (name != null) {
5619                        if (userId == UserHandle.USER_ALL) {
5620                            if (UserHandle.getAppId(entUid) == appId) {
5621                                remove = true;
5622                            }
5623                        } else {
5624                            if (entUid == UserHandle.getUid(userId, appId)) {
5625                                remove = true;
5626                            }
5627                        }
5628                    } else if (UserHandle.getUserId(entUid) == userId) {
5629                        remove = true;
5630                    }
5631                    if (remove) {
5632                        ba.removeAt(i);
5633                    }
5634                }
5635                if (ba.size() == 0) {
5636                    pmap.removeAt(ip);
5637                }
5638            }
5639        }
5640
5641        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5642                -100, callerWillRestart, true, doit, evenPersistent,
5643                name == null ? ("stop user " + userId) : ("stop " + name));
5644
5645        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5646            if (!doit) {
5647                return true;
5648            }
5649            didSomething = true;
5650        }
5651
5652        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5653            if (!doit) {
5654                return true;
5655            }
5656            didSomething = true;
5657        }
5658
5659        if (name == null) {
5660            // Remove all sticky broadcasts from this user.
5661            mStickyBroadcasts.remove(userId);
5662        }
5663
5664        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5665        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5666                userId, providers)) {
5667            if (!doit) {
5668                return true;
5669            }
5670            didSomething = true;
5671        }
5672        N = providers.size();
5673        for (i=0; i<N; i++) {
5674            removeDyingProviderLocked(null, providers.get(i), true);
5675        }
5676
5677        // Remove transient permissions granted from/to this package/user
5678        removeUriPermissionsForPackageLocked(name, userId, false);
5679
5680        if (name == null || uninstalling) {
5681            // Remove pending intents.  For now we only do this when force
5682            // stopping users, because we have some problems when doing this
5683            // for packages -- app widgets are not currently cleaned up for
5684            // such packages, so they can be left with bad pending intents.
5685            if (mIntentSenderRecords.size() > 0) {
5686                Iterator<WeakReference<PendingIntentRecord>> it
5687                        = mIntentSenderRecords.values().iterator();
5688                while (it.hasNext()) {
5689                    WeakReference<PendingIntentRecord> wpir = it.next();
5690                    if (wpir == null) {
5691                        it.remove();
5692                        continue;
5693                    }
5694                    PendingIntentRecord pir = wpir.get();
5695                    if (pir == null) {
5696                        it.remove();
5697                        continue;
5698                    }
5699                    if (name == null) {
5700                        // Stopping user, remove all objects for the user.
5701                        if (pir.key.userId != userId) {
5702                            // Not the same user, skip it.
5703                            continue;
5704                        }
5705                    } else {
5706                        if (UserHandle.getAppId(pir.uid) != appId) {
5707                            // Different app id, skip it.
5708                            continue;
5709                        }
5710                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5711                            // Different user, skip it.
5712                            continue;
5713                        }
5714                        if (!pir.key.packageName.equals(name)) {
5715                            // Different package, skip it.
5716                            continue;
5717                        }
5718                    }
5719                    if (!doit) {
5720                        return true;
5721                    }
5722                    didSomething = true;
5723                    it.remove();
5724                    pir.canceled = true;
5725                    if (pir.key.activity != null) {
5726                        pir.key.activity.pendingResults.remove(pir.ref);
5727                    }
5728                }
5729            }
5730        }
5731
5732        if (doit) {
5733            if (purgeCache && name != null) {
5734                AttributeCache ac = AttributeCache.instance();
5735                if (ac != null) {
5736                    ac.removePackage(name);
5737                }
5738            }
5739            if (mBooted) {
5740                mStackSupervisor.resumeTopActivitiesLocked();
5741                mStackSupervisor.scheduleIdleLocked();
5742            }
5743        }
5744
5745        return didSomething;
5746    }
5747
5748    private final boolean removeProcessLocked(ProcessRecord app,
5749            boolean callerWillRestart, boolean allowRestart, String reason) {
5750        final String name = app.processName;
5751        final int uid = app.uid;
5752        if (DEBUG_PROCESSES) Slog.d(
5753            TAG, "Force removing proc " + app.toShortString() + " (" + name
5754            + "/" + uid + ")");
5755
5756        mProcessNames.remove(name, uid);
5757        mIsolatedProcesses.remove(app.uid);
5758        if (mHeavyWeightProcess == app) {
5759            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5760                    mHeavyWeightProcess.userId, 0));
5761            mHeavyWeightProcess = null;
5762        }
5763        boolean needRestart = false;
5764        if (app.pid > 0 && app.pid != MY_PID) {
5765            int pid = app.pid;
5766            synchronized (mPidsSelfLocked) {
5767                mPidsSelfLocked.remove(pid);
5768                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5769            }
5770            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5771            if (app.isolated) {
5772                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5773            }
5774            app.kill(reason, true);
5775            handleAppDiedLocked(app, true, allowRestart);
5776            removeLruProcessLocked(app);
5777
5778            if (app.persistent && !app.isolated) {
5779                if (!callerWillRestart) {
5780                    addAppLocked(app.info, false, null /* ABI override */);
5781                } else {
5782                    needRestart = true;
5783                }
5784            }
5785        } else {
5786            mRemovedProcesses.add(app);
5787        }
5788
5789        return needRestart;
5790    }
5791
5792    private final void processStartTimedOutLocked(ProcessRecord app) {
5793        final int pid = app.pid;
5794        boolean gone = false;
5795        synchronized (mPidsSelfLocked) {
5796            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5797            if (knownApp != null && knownApp.thread == null) {
5798                mPidsSelfLocked.remove(pid);
5799                gone = true;
5800            }
5801        }
5802
5803        if (gone) {
5804            Slog.w(TAG, "Process " + app + " failed to attach");
5805            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5806                    pid, app.uid, app.processName);
5807            mProcessNames.remove(app.processName, app.uid);
5808            mIsolatedProcesses.remove(app.uid);
5809            if (mHeavyWeightProcess == app) {
5810                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5811                        mHeavyWeightProcess.userId, 0));
5812                mHeavyWeightProcess = null;
5813            }
5814            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5815            if (app.isolated) {
5816                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5817            }
5818            // Take care of any launching providers waiting for this process.
5819            checkAppInLaunchingProvidersLocked(app, true);
5820            // Take care of any services that are waiting for the process.
5821            mServices.processStartTimedOutLocked(app);
5822            app.kill("start timeout", true);
5823            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5824                Slog.w(TAG, "Unattached app died before backup, skipping");
5825                try {
5826                    IBackupManager bm = IBackupManager.Stub.asInterface(
5827                            ServiceManager.getService(Context.BACKUP_SERVICE));
5828                    bm.agentDisconnected(app.info.packageName);
5829                } catch (RemoteException e) {
5830                    // Can't happen; the backup manager is local
5831                }
5832            }
5833            if (isPendingBroadcastProcessLocked(pid)) {
5834                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5835                skipPendingBroadcastLocked(pid);
5836            }
5837        } else {
5838            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5839        }
5840    }
5841
5842    private final boolean attachApplicationLocked(IApplicationThread thread,
5843            int pid) {
5844
5845        // Find the application record that is being attached...  either via
5846        // the pid if we are running in multiple processes, or just pull the
5847        // next app record if we are emulating process with anonymous threads.
5848        ProcessRecord app;
5849        if (pid != MY_PID && pid >= 0) {
5850            synchronized (mPidsSelfLocked) {
5851                app = mPidsSelfLocked.get(pid);
5852            }
5853        } else {
5854            app = null;
5855        }
5856
5857        if (app == null) {
5858            Slog.w(TAG, "No pending application record for pid " + pid
5859                    + " (IApplicationThread " + thread + "); dropping process");
5860            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5861            if (pid > 0 && pid != MY_PID) {
5862                Process.killProcessQuiet(pid);
5863                //TODO: Process.killProcessGroup(app.info.uid, pid);
5864            } else {
5865                try {
5866                    thread.scheduleExit();
5867                } catch (Exception e) {
5868                    // Ignore exceptions.
5869                }
5870            }
5871            return false;
5872        }
5873
5874        // If this application record is still attached to a previous
5875        // process, clean it up now.
5876        if (app.thread != null) {
5877            handleAppDiedLocked(app, true, true);
5878        }
5879
5880        // Tell the process all about itself.
5881
5882        if (localLOGV) Slog.v(
5883                TAG, "Binding process pid " + pid + " to record " + app);
5884
5885        final String processName = app.processName;
5886        try {
5887            AppDeathRecipient adr = new AppDeathRecipient(
5888                    app, pid, thread);
5889            thread.asBinder().linkToDeath(adr, 0);
5890            app.deathRecipient = adr;
5891        } catch (RemoteException e) {
5892            app.resetPackageList(mProcessStats);
5893            startProcessLocked(app, "link fail", processName);
5894            return false;
5895        }
5896
5897        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5898
5899        app.makeActive(thread, mProcessStats);
5900        app.curAdj = app.setAdj = -100;
5901        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5902        app.forcingToForeground = null;
5903        updateProcessForegroundLocked(app, false, false);
5904        app.hasShownUi = false;
5905        app.debugging = false;
5906        app.cached = false;
5907
5908        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5909
5910        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5911        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5912
5913        if (!normalMode) {
5914            Slog.i(TAG, "Launching preboot mode app: " + app);
5915        }
5916
5917        if (localLOGV) Slog.v(
5918            TAG, "New app record " + app
5919            + " thread=" + thread.asBinder() + " pid=" + pid);
5920        try {
5921            int testMode = IApplicationThread.DEBUG_OFF;
5922            if (mDebugApp != null && mDebugApp.equals(processName)) {
5923                testMode = mWaitForDebugger
5924                    ? IApplicationThread.DEBUG_WAIT
5925                    : IApplicationThread.DEBUG_ON;
5926                app.debugging = true;
5927                if (mDebugTransient) {
5928                    mDebugApp = mOrigDebugApp;
5929                    mWaitForDebugger = mOrigWaitForDebugger;
5930                }
5931            }
5932            String profileFile = app.instrumentationProfileFile;
5933            ParcelFileDescriptor profileFd = null;
5934            int samplingInterval = 0;
5935            boolean profileAutoStop = false;
5936            if (mProfileApp != null && mProfileApp.equals(processName)) {
5937                mProfileProc = app;
5938                profileFile = mProfileFile;
5939                profileFd = mProfileFd;
5940                samplingInterval = mSamplingInterval;
5941                profileAutoStop = mAutoStopProfiler;
5942            }
5943            boolean enableOpenGlTrace = false;
5944            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5945                enableOpenGlTrace = true;
5946                mOpenGlTraceApp = null;
5947            }
5948
5949            // If the app is being launched for restore or full backup, set it up specially
5950            boolean isRestrictedBackupMode = false;
5951            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5952                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5953                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5954                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5955            }
5956
5957            ensurePackageDexOpt(app.instrumentationInfo != null
5958                    ? app.instrumentationInfo.packageName
5959                    : app.info.packageName);
5960            if (app.instrumentationClass != null) {
5961                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5962            }
5963            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5964                    + processName + " with config " + mConfiguration);
5965            ApplicationInfo appInfo = app.instrumentationInfo != null
5966                    ? app.instrumentationInfo : app.info;
5967            app.compat = compatibilityInfoForPackageLocked(appInfo);
5968            if (profileFd != null) {
5969                profileFd = profileFd.dup();
5970            }
5971            ProfilerInfo profilerInfo = profileFile == null ? null
5972                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5973            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5974                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5975                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5976                    isRestrictedBackupMode || !normalMode, app.persistent,
5977                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5978                    mCoreSettingsObserver.getCoreSettingsLocked());
5979            updateLruProcessLocked(app, false, null);
5980            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5981        } catch (Exception e) {
5982            // todo: Yikes!  What should we do?  For now we will try to
5983            // start another process, but that could easily get us in
5984            // an infinite loop of restarting processes...
5985            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5986
5987            app.resetPackageList(mProcessStats);
5988            app.unlinkDeathRecipient();
5989            startProcessLocked(app, "bind fail", processName);
5990            return false;
5991        }
5992
5993        // Remove this record from the list of starting applications.
5994        mPersistentStartingProcesses.remove(app);
5995        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5996                "Attach application locked removing on hold: " + app);
5997        mProcessesOnHold.remove(app);
5998
5999        boolean badApp = false;
6000        boolean didSomething = false;
6001
6002        // See if the top visible activity is waiting to run in this process...
6003        if (normalMode) {
6004            try {
6005                if (mStackSupervisor.attachApplicationLocked(app)) {
6006                    didSomething = true;
6007                }
6008            } catch (Exception e) {
6009                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6010                badApp = true;
6011            }
6012        }
6013
6014        // Find any services that should be running in this process...
6015        if (!badApp) {
6016            try {
6017                didSomething |= mServices.attachApplicationLocked(app, processName);
6018            } catch (Exception e) {
6019                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6020                badApp = true;
6021            }
6022        }
6023
6024        // Check if a next-broadcast receiver is in this process...
6025        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6026            try {
6027                didSomething |= sendPendingBroadcastsLocked(app);
6028            } catch (Exception e) {
6029                // If the app died trying to launch the receiver we declare it 'bad'
6030                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6031                badApp = true;
6032            }
6033        }
6034
6035        // Check whether the next backup agent is in this process...
6036        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6037            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6038            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6039            try {
6040                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6041                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6042                        mBackupTarget.backupMode);
6043            } catch (Exception e) {
6044                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6045                badApp = true;
6046            }
6047        }
6048
6049        if (badApp) {
6050            app.kill("error during init", true);
6051            handleAppDiedLocked(app, false, true);
6052            return false;
6053        }
6054
6055        if (!didSomething) {
6056            updateOomAdjLocked();
6057        }
6058
6059        return true;
6060    }
6061
6062    @Override
6063    public final void attachApplication(IApplicationThread thread) {
6064        synchronized (this) {
6065            int callingPid = Binder.getCallingPid();
6066            final long origId = Binder.clearCallingIdentity();
6067            attachApplicationLocked(thread, callingPid);
6068            Binder.restoreCallingIdentity(origId);
6069        }
6070    }
6071
6072    @Override
6073    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6074        final long origId = Binder.clearCallingIdentity();
6075        synchronized (this) {
6076            ActivityStack stack = ActivityRecord.getStackLocked(token);
6077            if (stack != null) {
6078                ActivityRecord r =
6079                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6080                if (stopProfiling) {
6081                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6082                        try {
6083                            mProfileFd.close();
6084                        } catch (IOException e) {
6085                        }
6086                        clearProfilerLocked();
6087                    }
6088                }
6089            }
6090        }
6091        Binder.restoreCallingIdentity(origId);
6092    }
6093
6094    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6095        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6096                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6097    }
6098
6099    void enableScreenAfterBoot() {
6100        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6101                SystemClock.uptimeMillis());
6102        mWindowManager.enableScreenAfterBoot();
6103
6104        synchronized (this) {
6105            updateEventDispatchingLocked();
6106        }
6107    }
6108
6109    @Override
6110    public void showBootMessage(final CharSequence msg, final boolean always) {
6111        enforceNotIsolatedCaller("showBootMessage");
6112        mWindowManager.showBootMessage(msg, always);
6113    }
6114
6115    @Override
6116    public void keyguardWaitingForActivityDrawn() {
6117        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6118        final long token = Binder.clearCallingIdentity();
6119        try {
6120            synchronized (this) {
6121                if (DEBUG_LOCKSCREEN) logLockScreen("");
6122                mWindowManager.keyguardWaitingForActivityDrawn();
6123                if (mLockScreenShown) {
6124                    mLockScreenShown = false;
6125                    comeOutOfSleepIfNeededLocked();
6126                }
6127            }
6128        } finally {
6129            Binder.restoreCallingIdentity(token);
6130        }
6131    }
6132
6133    final void finishBooting() {
6134        synchronized (this) {
6135            if (!mBootAnimationComplete) {
6136                mCallFinishBooting = true;
6137                return;
6138            }
6139            mCallFinishBooting = false;
6140        }
6141
6142        // Register receivers to handle package update events
6143        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6144
6145        // Let system services know.
6146        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6147
6148        synchronized (this) {
6149            // Ensure that any processes we had put on hold are now started
6150            // up.
6151            final int NP = mProcessesOnHold.size();
6152            if (NP > 0) {
6153                ArrayList<ProcessRecord> procs =
6154                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6155                for (int ip=0; ip<NP; ip++) {
6156                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6157                            + procs.get(ip));
6158                    startProcessLocked(procs.get(ip), "on-hold", null);
6159                }
6160            }
6161
6162            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6163                // Start looking for apps that are abusing wake locks.
6164                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6165                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6166                // Tell anyone interested that we are done booting!
6167                SystemProperties.set("sys.boot_completed", "1");
6168
6169                // And trigger dev.bootcomplete if we are not showing encryption progress
6170                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6171                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6172                    SystemProperties.set("dev.bootcomplete", "1");
6173                }
6174                for (int i=0; i<mStartedUsers.size(); i++) {
6175                    UserStartedState uss = mStartedUsers.valueAt(i);
6176                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6177                        uss.mState = UserStartedState.STATE_RUNNING;
6178                        final int userId = mStartedUsers.keyAt(i);
6179                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6180                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6181                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6182                        broadcastIntentLocked(null, null, intent, null,
6183                                new IIntentReceiver.Stub() {
6184                                    @Override
6185                                    public void performReceive(Intent intent, int resultCode,
6186                                            String data, Bundle extras, boolean ordered,
6187                                            boolean sticky, int sendingUser) {
6188                                        synchronized (ActivityManagerService.this) {
6189                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6190                                                    true, false);
6191                                        }
6192                                    }
6193                                },
6194                                0, null, null,
6195                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6196                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6197                                userId);
6198                    }
6199                }
6200                scheduleStartProfilesLocked();
6201            }
6202        }
6203    }
6204
6205    @Override
6206    public void bootAnimationComplete() {
6207        final boolean callFinishBooting;
6208        synchronized (this) {
6209            callFinishBooting = mCallFinishBooting;
6210            mBootAnimationComplete = true;
6211        }
6212        if (callFinishBooting) {
6213            finishBooting();
6214        }
6215    }
6216
6217    final void ensureBootCompleted() {
6218        boolean booting;
6219        boolean enableScreen;
6220        synchronized (this) {
6221            booting = mBooting;
6222            mBooting = false;
6223            enableScreen = !mBooted;
6224            mBooted = true;
6225        }
6226
6227        if (booting) {
6228            finishBooting();
6229        }
6230
6231        if (enableScreen) {
6232            enableScreenAfterBoot();
6233        }
6234    }
6235
6236    @Override
6237    public final void activityResumed(IBinder token) {
6238        final long origId = Binder.clearCallingIdentity();
6239        synchronized(this) {
6240            ActivityStack stack = ActivityRecord.getStackLocked(token);
6241            if (stack != null) {
6242                ActivityRecord.activityResumedLocked(token);
6243            }
6244        }
6245        Binder.restoreCallingIdentity(origId);
6246    }
6247
6248    @Override
6249    public final void activityPaused(IBinder token) {
6250        final long origId = Binder.clearCallingIdentity();
6251        synchronized(this) {
6252            ActivityStack stack = ActivityRecord.getStackLocked(token);
6253            if (stack != null) {
6254                stack.activityPausedLocked(token, false);
6255            }
6256        }
6257        Binder.restoreCallingIdentity(origId);
6258    }
6259
6260    @Override
6261    public final void activityStopped(IBinder token, Bundle icicle,
6262            PersistableBundle persistentState, CharSequence description) {
6263        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6264
6265        // Refuse possible leaked file descriptors
6266        if (icicle != null && icicle.hasFileDescriptors()) {
6267            throw new IllegalArgumentException("File descriptors passed in Bundle");
6268        }
6269
6270        final long origId = Binder.clearCallingIdentity();
6271
6272        synchronized (this) {
6273            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6274            if (r != null) {
6275                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6276            }
6277        }
6278
6279        trimApplications();
6280
6281        Binder.restoreCallingIdentity(origId);
6282    }
6283
6284    @Override
6285    public final void activityDestroyed(IBinder token) {
6286        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6287        synchronized (this) {
6288            ActivityStack stack = ActivityRecord.getStackLocked(token);
6289            if (stack != null) {
6290                stack.activityDestroyedLocked(token);
6291            }
6292        }
6293    }
6294
6295    @Override
6296    public final void backgroundResourcesReleased(IBinder token) {
6297        final long origId = Binder.clearCallingIdentity();
6298        try {
6299            synchronized (this) {
6300                ActivityStack stack = ActivityRecord.getStackLocked(token);
6301                if (stack != null) {
6302                    stack.backgroundResourcesReleased(token);
6303                }
6304            }
6305        } finally {
6306            Binder.restoreCallingIdentity(origId);
6307        }
6308    }
6309
6310    @Override
6311    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6312        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6313    }
6314
6315    @Override
6316    public final void notifyEnterAnimationComplete(IBinder token) {
6317        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6318    }
6319
6320    @Override
6321    public String getCallingPackage(IBinder token) {
6322        synchronized (this) {
6323            ActivityRecord r = getCallingRecordLocked(token);
6324            return r != null ? r.info.packageName : null;
6325        }
6326    }
6327
6328    @Override
6329    public ComponentName getCallingActivity(IBinder token) {
6330        synchronized (this) {
6331            ActivityRecord r = getCallingRecordLocked(token);
6332            return r != null ? r.intent.getComponent() : null;
6333        }
6334    }
6335
6336    private ActivityRecord getCallingRecordLocked(IBinder token) {
6337        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6338        if (r == null) {
6339            return null;
6340        }
6341        return r.resultTo;
6342    }
6343
6344    @Override
6345    public ComponentName getActivityClassForToken(IBinder token) {
6346        synchronized(this) {
6347            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6348            if (r == null) {
6349                return null;
6350            }
6351            return r.intent.getComponent();
6352        }
6353    }
6354
6355    @Override
6356    public String getPackageForToken(IBinder token) {
6357        synchronized(this) {
6358            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6359            if (r == null) {
6360                return null;
6361            }
6362            return r.packageName;
6363        }
6364    }
6365
6366    @Override
6367    public IIntentSender getIntentSender(int type,
6368            String packageName, IBinder token, String resultWho,
6369            int requestCode, Intent[] intents, String[] resolvedTypes,
6370            int flags, Bundle options, int userId) {
6371        enforceNotIsolatedCaller("getIntentSender");
6372        // Refuse possible leaked file descriptors
6373        if (intents != null) {
6374            if (intents.length < 1) {
6375                throw new IllegalArgumentException("Intents array length must be >= 1");
6376            }
6377            for (int i=0; i<intents.length; i++) {
6378                Intent intent = intents[i];
6379                if (intent != null) {
6380                    if (intent.hasFileDescriptors()) {
6381                        throw new IllegalArgumentException("File descriptors passed in Intent");
6382                    }
6383                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6384                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6385                        throw new IllegalArgumentException(
6386                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6387                    }
6388                    intents[i] = new Intent(intent);
6389                }
6390            }
6391            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6392                throw new IllegalArgumentException(
6393                        "Intent array length does not match resolvedTypes length");
6394            }
6395        }
6396        if (options != null) {
6397            if (options.hasFileDescriptors()) {
6398                throw new IllegalArgumentException("File descriptors passed in options");
6399            }
6400        }
6401
6402        synchronized(this) {
6403            int callingUid = Binder.getCallingUid();
6404            int origUserId = userId;
6405            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6406                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6407                    ALLOW_NON_FULL, "getIntentSender", null);
6408            if (origUserId == UserHandle.USER_CURRENT) {
6409                // We don't want to evaluate this until the pending intent is
6410                // actually executed.  However, we do want to always do the
6411                // security checking for it above.
6412                userId = UserHandle.USER_CURRENT;
6413            }
6414            try {
6415                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6416                    int uid = AppGlobals.getPackageManager()
6417                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6418                    if (!UserHandle.isSameApp(callingUid, uid)) {
6419                        String msg = "Permission Denial: getIntentSender() from pid="
6420                            + Binder.getCallingPid()
6421                            + ", uid=" + Binder.getCallingUid()
6422                            + ", (need uid=" + uid + ")"
6423                            + " is not allowed to send as package " + packageName;
6424                        Slog.w(TAG, msg);
6425                        throw new SecurityException(msg);
6426                    }
6427                }
6428
6429                return getIntentSenderLocked(type, packageName, callingUid, userId,
6430                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6431
6432            } catch (RemoteException e) {
6433                throw new SecurityException(e);
6434            }
6435        }
6436    }
6437
6438    IIntentSender getIntentSenderLocked(int type, String packageName,
6439            int callingUid, int userId, IBinder token, String resultWho,
6440            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6441            Bundle options) {
6442        if (DEBUG_MU)
6443            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6444        ActivityRecord activity = null;
6445        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6446            activity = ActivityRecord.isInStackLocked(token);
6447            if (activity == null) {
6448                return null;
6449            }
6450            if (activity.finishing) {
6451                return null;
6452            }
6453        }
6454
6455        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6456        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6457        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6458        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6459                |PendingIntent.FLAG_UPDATE_CURRENT);
6460
6461        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6462                type, packageName, activity, resultWho,
6463                requestCode, intents, resolvedTypes, flags, options, userId);
6464        WeakReference<PendingIntentRecord> ref;
6465        ref = mIntentSenderRecords.get(key);
6466        PendingIntentRecord rec = ref != null ? ref.get() : null;
6467        if (rec != null) {
6468            if (!cancelCurrent) {
6469                if (updateCurrent) {
6470                    if (rec.key.requestIntent != null) {
6471                        rec.key.requestIntent.replaceExtras(intents != null ?
6472                                intents[intents.length - 1] : null);
6473                    }
6474                    if (intents != null) {
6475                        intents[intents.length-1] = rec.key.requestIntent;
6476                        rec.key.allIntents = intents;
6477                        rec.key.allResolvedTypes = resolvedTypes;
6478                    } else {
6479                        rec.key.allIntents = null;
6480                        rec.key.allResolvedTypes = null;
6481                    }
6482                }
6483                return rec;
6484            }
6485            rec.canceled = true;
6486            mIntentSenderRecords.remove(key);
6487        }
6488        if (noCreate) {
6489            return rec;
6490        }
6491        rec = new PendingIntentRecord(this, key, callingUid);
6492        mIntentSenderRecords.put(key, rec.ref);
6493        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6494            if (activity.pendingResults == null) {
6495                activity.pendingResults
6496                        = new HashSet<WeakReference<PendingIntentRecord>>();
6497            }
6498            activity.pendingResults.add(rec.ref);
6499        }
6500        return rec;
6501    }
6502
6503    @Override
6504    public void cancelIntentSender(IIntentSender sender) {
6505        if (!(sender instanceof PendingIntentRecord)) {
6506            return;
6507        }
6508        synchronized(this) {
6509            PendingIntentRecord rec = (PendingIntentRecord)sender;
6510            try {
6511                int uid = AppGlobals.getPackageManager()
6512                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6513                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6514                    String msg = "Permission Denial: cancelIntentSender() from pid="
6515                        + Binder.getCallingPid()
6516                        + ", uid=" + Binder.getCallingUid()
6517                        + " is not allowed to cancel packges "
6518                        + rec.key.packageName;
6519                    Slog.w(TAG, msg);
6520                    throw new SecurityException(msg);
6521                }
6522            } catch (RemoteException e) {
6523                throw new SecurityException(e);
6524            }
6525            cancelIntentSenderLocked(rec, true);
6526        }
6527    }
6528
6529    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6530        rec.canceled = true;
6531        mIntentSenderRecords.remove(rec.key);
6532        if (cleanActivity && rec.key.activity != null) {
6533            rec.key.activity.pendingResults.remove(rec.ref);
6534        }
6535    }
6536
6537    @Override
6538    public String getPackageForIntentSender(IIntentSender pendingResult) {
6539        if (!(pendingResult instanceof PendingIntentRecord)) {
6540            return null;
6541        }
6542        try {
6543            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6544            return res.key.packageName;
6545        } catch (ClassCastException e) {
6546        }
6547        return null;
6548    }
6549
6550    @Override
6551    public int getUidForIntentSender(IIntentSender sender) {
6552        if (sender instanceof PendingIntentRecord) {
6553            try {
6554                PendingIntentRecord res = (PendingIntentRecord)sender;
6555                return res.uid;
6556            } catch (ClassCastException e) {
6557            }
6558        }
6559        return -1;
6560    }
6561
6562    @Override
6563    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6564        if (!(pendingResult instanceof PendingIntentRecord)) {
6565            return false;
6566        }
6567        try {
6568            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6569            if (res.key.allIntents == null) {
6570                return false;
6571            }
6572            for (int i=0; i<res.key.allIntents.length; i++) {
6573                Intent intent = res.key.allIntents[i];
6574                if (intent.getPackage() != null && intent.getComponent() != null) {
6575                    return false;
6576                }
6577            }
6578            return true;
6579        } catch (ClassCastException e) {
6580        }
6581        return false;
6582    }
6583
6584    @Override
6585    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6586        if (!(pendingResult instanceof PendingIntentRecord)) {
6587            return false;
6588        }
6589        try {
6590            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6591            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6592                return true;
6593            }
6594            return false;
6595        } catch (ClassCastException e) {
6596        }
6597        return false;
6598    }
6599
6600    @Override
6601    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6602        if (!(pendingResult instanceof PendingIntentRecord)) {
6603            return null;
6604        }
6605        try {
6606            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6607            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6608        } catch (ClassCastException e) {
6609        }
6610        return null;
6611    }
6612
6613    @Override
6614    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6615        if (!(pendingResult instanceof PendingIntentRecord)) {
6616            return null;
6617        }
6618        try {
6619            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6620            Intent intent = res.key.requestIntent;
6621            if (intent != null) {
6622                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6623                        || res.lastTagPrefix.equals(prefix))) {
6624                    return res.lastTag;
6625                }
6626                res.lastTagPrefix = prefix;
6627                StringBuilder sb = new StringBuilder(128);
6628                if (prefix != null) {
6629                    sb.append(prefix);
6630                }
6631                if (intent.getAction() != null) {
6632                    sb.append(intent.getAction());
6633                } else if (intent.getComponent() != null) {
6634                    intent.getComponent().appendShortString(sb);
6635                } else {
6636                    sb.append("?");
6637                }
6638                return res.lastTag = sb.toString();
6639            }
6640        } catch (ClassCastException e) {
6641        }
6642        return null;
6643    }
6644
6645    @Override
6646    public void setProcessLimit(int max) {
6647        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6648                "setProcessLimit()");
6649        synchronized (this) {
6650            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6651            mProcessLimitOverride = max;
6652        }
6653        trimApplications();
6654    }
6655
6656    @Override
6657    public int getProcessLimit() {
6658        synchronized (this) {
6659            return mProcessLimitOverride;
6660        }
6661    }
6662
6663    void foregroundTokenDied(ForegroundToken token) {
6664        synchronized (ActivityManagerService.this) {
6665            synchronized (mPidsSelfLocked) {
6666                ForegroundToken cur
6667                    = mForegroundProcesses.get(token.pid);
6668                if (cur != token) {
6669                    return;
6670                }
6671                mForegroundProcesses.remove(token.pid);
6672                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6673                if (pr == null) {
6674                    return;
6675                }
6676                pr.forcingToForeground = null;
6677                updateProcessForegroundLocked(pr, false, false);
6678            }
6679            updateOomAdjLocked();
6680        }
6681    }
6682
6683    @Override
6684    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6685        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6686                "setProcessForeground()");
6687        synchronized(this) {
6688            boolean changed = false;
6689
6690            synchronized (mPidsSelfLocked) {
6691                ProcessRecord pr = mPidsSelfLocked.get(pid);
6692                if (pr == null && isForeground) {
6693                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6694                    return;
6695                }
6696                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6697                if (oldToken != null) {
6698                    oldToken.token.unlinkToDeath(oldToken, 0);
6699                    mForegroundProcesses.remove(pid);
6700                    if (pr != null) {
6701                        pr.forcingToForeground = null;
6702                    }
6703                    changed = true;
6704                }
6705                if (isForeground && token != null) {
6706                    ForegroundToken newToken = new ForegroundToken() {
6707                        @Override
6708                        public void binderDied() {
6709                            foregroundTokenDied(this);
6710                        }
6711                    };
6712                    newToken.pid = pid;
6713                    newToken.token = token;
6714                    try {
6715                        token.linkToDeath(newToken, 0);
6716                        mForegroundProcesses.put(pid, newToken);
6717                        pr.forcingToForeground = token;
6718                        changed = true;
6719                    } catch (RemoteException e) {
6720                        // If the process died while doing this, we will later
6721                        // do the cleanup with the process death link.
6722                    }
6723                }
6724            }
6725
6726            if (changed) {
6727                updateOomAdjLocked();
6728            }
6729        }
6730    }
6731
6732    // =========================================================
6733    // PERMISSIONS
6734    // =========================================================
6735
6736    static class PermissionController extends IPermissionController.Stub {
6737        ActivityManagerService mActivityManagerService;
6738        PermissionController(ActivityManagerService activityManagerService) {
6739            mActivityManagerService = activityManagerService;
6740        }
6741
6742        @Override
6743        public boolean checkPermission(String permission, int pid, int uid) {
6744            return mActivityManagerService.checkPermission(permission, pid,
6745                    uid) == PackageManager.PERMISSION_GRANTED;
6746        }
6747    }
6748
6749    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6750        @Override
6751        public int checkComponentPermission(String permission, int pid, int uid,
6752                int owningUid, boolean exported) {
6753            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6754                    owningUid, exported);
6755        }
6756
6757        @Override
6758        public Object getAMSLock() {
6759            return ActivityManagerService.this;
6760        }
6761    }
6762
6763    /**
6764     * This can be called with or without the global lock held.
6765     */
6766    int checkComponentPermission(String permission, int pid, int uid,
6767            int owningUid, boolean exported) {
6768        // We might be performing an operation on behalf of an indirect binder
6769        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6770        // client identity accordingly before proceeding.
6771        Identity tlsIdentity = sCallerIdentity.get();
6772        if (tlsIdentity != null) {
6773            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6774                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6775            uid = tlsIdentity.uid;
6776            pid = tlsIdentity.pid;
6777        }
6778
6779        if (pid == MY_PID) {
6780            return PackageManager.PERMISSION_GRANTED;
6781        }
6782
6783        return ActivityManager.checkComponentPermission(permission, uid,
6784                owningUid, exported);
6785    }
6786
6787    /**
6788     * As the only public entry point for permissions checking, this method
6789     * can enforce the semantic that requesting a check on a null global
6790     * permission is automatically denied.  (Internally a null permission
6791     * string is used when calling {@link #checkComponentPermission} in cases
6792     * when only uid-based security is needed.)
6793     *
6794     * This can be called with or without the global lock held.
6795     */
6796    @Override
6797    public int checkPermission(String permission, int pid, int uid) {
6798        if (permission == null) {
6799            return PackageManager.PERMISSION_DENIED;
6800        }
6801        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6802    }
6803
6804    /**
6805     * Binder IPC calls go through the public entry point.
6806     * This can be called with or without the global lock held.
6807     */
6808    int checkCallingPermission(String permission) {
6809        return checkPermission(permission,
6810                Binder.getCallingPid(),
6811                UserHandle.getAppId(Binder.getCallingUid()));
6812    }
6813
6814    /**
6815     * This can be called with or without the global lock held.
6816     */
6817    void enforceCallingPermission(String permission, String func) {
6818        if (checkCallingPermission(permission)
6819                == PackageManager.PERMISSION_GRANTED) {
6820            return;
6821        }
6822
6823        String msg = "Permission Denial: " + func + " from pid="
6824                + Binder.getCallingPid()
6825                + ", uid=" + Binder.getCallingUid()
6826                + " requires " + permission;
6827        Slog.w(TAG, msg);
6828        throw new SecurityException(msg);
6829    }
6830
6831    /**
6832     * Determine if UID is holding permissions required to access {@link Uri} in
6833     * the given {@link ProviderInfo}. Final permission checking is always done
6834     * in {@link ContentProvider}.
6835     */
6836    private final boolean checkHoldingPermissionsLocked(
6837            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6838        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6839                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6840        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6841            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6842                    != PERMISSION_GRANTED) {
6843                return false;
6844            }
6845        }
6846        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6847    }
6848
6849    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6850            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6851        if (pi.applicationInfo.uid == uid) {
6852            return true;
6853        } else if (!pi.exported) {
6854            return false;
6855        }
6856
6857        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6858        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6859        try {
6860            // check if target holds top-level <provider> permissions
6861            if (!readMet && pi.readPermission != null && considerUidPermissions
6862                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6863                readMet = true;
6864            }
6865            if (!writeMet && pi.writePermission != null && considerUidPermissions
6866                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6867                writeMet = true;
6868            }
6869
6870            // track if unprotected read/write is allowed; any denied
6871            // <path-permission> below removes this ability
6872            boolean allowDefaultRead = pi.readPermission == null;
6873            boolean allowDefaultWrite = pi.writePermission == null;
6874
6875            // check if target holds any <path-permission> that match uri
6876            final PathPermission[] pps = pi.pathPermissions;
6877            if (pps != null) {
6878                final String path = grantUri.uri.getPath();
6879                int i = pps.length;
6880                while (i > 0 && (!readMet || !writeMet)) {
6881                    i--;
6882                    PathPermission pp = pps[i];
6883                    if (pp.match(path)) {
6884                        if (!readMet) {
6885                            final String pprperm = pp.getReadPermission();
6886                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6887                                    + pprperm + " for " + pp.getPath()
6888                                    + ": match=" + pp.match(path)
6889                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6890                            if (pprperm != null) {
6891                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6892                                        == PERMISSION_GRANTED) {
6893                                    readMet = true;
6894                                } else {
6895                                    allowDefaultRead = false;
6896                                }
6897                            }
6898                        }
6899                        if (!writeMet) {
6900                            final String ppwperm = pp.getWritePermission();
6901                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6902                                    + ppwperm + " for " + pp.getPath()
6903                                    + ": match=" + pp.match(path)
6904                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6905                            if (ppwperm != null) {
6906                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6907                                        == PERMISSION_GRANTED) {
6908                                    writeMet = true;
6909                                } else {
6910                                    allowDefaultWrite = false;
6911                                }
6912                            }
6913                        }
6914                    }
6915                }
6916            }
6917
6918            // grant unprotected <provider> read/write, if not blocked by
6919            // <path-permission> above
6920            if (allowDefaultRead) readMet = true;
6921            if (allowDefaultWrite) writeMet = true;
6922
6923        } catch (RemoteException e) {
6924            return false;
6925        }
6926
6927        return readMet && writeMet;
6928    }
6929
6930    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6931        ProviderInfo pi = null;
6932        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6933        if (cpr != null) {
6934            pi = cpr.info;
6935        } else {
6936            try {
6937                pi = AppGlobals.getPackageManager().resolveContentProvider(
6938                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6939            } catch (RemoteException ex) {
6940            }
6941        }
6942        return pi;
6943    }
6944
6945    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6946        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6947        if (targetUris != null) {
6948            return targetUris.get(grantUri);
6949        }
6950        return null;
6951    }
6952
6953    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6954            String targetPkg, int targetUid, GrantUri grantUri) {
6955        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6956        if (targetUris == null) {
6957            targetUris = Maps.newArrayMap();
6958            mGrantedUriPermissions.put(targetUid, targetUris);
6959        }
6960
6961        UriPermission perm = targetUris.get(grantUri);
6962        if (perm == null) {
6963            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6964            targetUris.put(grantUri, perm);
6965        }
6966
6967        return perm;
6968    }
6969
6970    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6971            final int modeFlags) {
6972        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6973        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6974                : UriPermission.STRENGTH_OWNED;
6975
6976        // Root gets to do everything.
6977        if (uid == 0) {
6978            return true;
6979        }
6980
6981        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6982        if (perms == null) return false;
6983
6984        // First look for exact match
6985        final UriPermission exactPerm = perms.get(grantUri);
6986        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6987            return true;
6988        }
6989
6990        // No exact match, look for prefixes
6991        final int N = perms.size();
6992        for (int i = 0; i < N; i++) {
6993            final UriPermission perm = perms.valueAt(i);
6994            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6995                    && perm.getStrength(modeFlags) >= minStrength) {
6996                return true;
6997            }
6998        }
6999
7000        return false;
7001    }
7002
7003    /**
7004     * @param uri This uri must NOT contain an embedded userId.
7005     * @param userId The userId in which the uri is to be resolved.
7006     */
7007    @Override
7008    public int checkUriPermission(Uri uri, int pid, int uid,
7009            final int modeFlags, int userId) {
7010        enforceNotIsolatedCaller("checkUriPermission");
7011
7012        // Another redirected-binder-call permissions check as in
7013        // {@link checkComponentPermission}.
7014        Identity tlsIdentity = sCallerIdentity.get();
7015        if (tlsIdentity != null) {
7016            uid = tlsIdentity.uid;
7017            pid = tlsIdentity.pid;
7018        }
7019
7020        // Our own process gets to do everything.
7021        if (pid == MY_PID) {
7022            return PackageManager.PERMISSION_GRANTED;
7023        }
7024        synchronized (this) {
7025            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7026                    ? PackageManager.PERMISSION_GRANTED
7027                    : PackageManager.PERMISSION_DENIED;
7028        }
7029    }
7030
7031    /**
7032     * Check if the targetPkg can be granted permission to access uri by
7033     * the callingUid using the given modeFlags.  Throws a security exception
7034     * if callingUid is not allowed to do this.  Returns the uid of the target
7035     * if the URI permission grant should be performed; returns -1 if it is not
7036     * needed (for example targetPkg already has permission to access the URI).
7037     * If you already know the uid of the target, you can supply it in
7038     * lastTargetUid else set that to -1.
7039     */
7040    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7041            final int modeFlags, int lastTargetUid) {
7042        if (!Intent.isAccessUriMode(modeFlags)) {
7043            return -1;
7044        }
7045
7046        if (targetPkg != null) {
7047            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7048                    "Checking grant " + targetPkg + " permission to " + grantUri);
7049        }
7050
7051        final IPackageManager pm = AppGlobals.getPackageManager();
7052
7053        // If this is not a content: uri, we can't do anything with it.
7054        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7055            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7056                    "Can't grant URI permission for non-content URI: " + grantUri);
7057            return -1;
7058        }
7059
7060        final String authority = grantUri.uri.getAuthority();
7061        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7062        if (pi == null) {
7063            Slog.w(TAG, "No content provider found for permission check: " +
7064                    grantUri.uri.toSafeString());
7065            return -1;
7066        }
7067
7068        int targetUid = lastTargetUid;
7069        if (targetUid < 0 && targetPkg != null) {
7070            try {
7071                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7072                if (targetUid < 0) {
7073                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7074                            "Can't grant URI permission no uid for: " + targetPkg);
7075                    return -1;
7076                }
7077            } catch (RemoteException ex) {
7078                return -1;
7079            }
7080        }
7081
7082        if (targetUid >= 0) {
7083            // First...  does the target actually need this permission?
7084            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7085                // No need to grant the target this permission.
7086                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7087                        "Target " + targetPkg + " already has full permission to " + grantUri);
7088                return -1;
7089            }
7090        } else {
7091            // First...  there is no target package, so can anyone access it?
7092            boolean allowed = pi.exported;
7093            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7094                if (pi.readPermission != null) {
7095                    allowed = false;
7096                }
7097            }
7098            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7099                if (pi.writePermission != null) {
7100                    allowed = false;
7101                }
7102            }
7103            if (allowed) {
7104                return -1;
7105            }
7106        }
7107
7108        /* There is a special cross user grant if:
7109         * - The target is on another user.
7110         * - Apps on the current user can access the uri without any uid permissions.
7111         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7112         * grant uri permissions.
7113         */
7114        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7115                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7116                modeFlags, false /*without considering the uid permissions*/);
7117
7118        // Second...  is the provider allowing granting of URI permissions?
7119        if (!specialCrossUserGrant) {
7120            if (!pi.grantUriPermissions) {
7121                throw new SecurityException("Provider " + pi.packageName
7122                        + "/" + pi.name
7123                        + " does not allow granting of Uri permissions (uri "
7124                        + grantUri + ")");
7125            }
7126            if (pi.uriPermissionPatterns != null) {
7127                final int N = pi.uriPermissionPatterns.length;
7128                boolean allowed = false;
7129                for (int i=0; i<N; i++) {
7130                    if (pi.uriPermissionPatterns[i] != null
7131                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7132                        allowed = true;
7133                        break;
7134                    }
7135                }
7136                if (!allowed) {
7137                    throw new SecurityException("Provider " + pi.packageName
7138                            + "/" + pi.name
7139                            + " does not allow granting of permission to path of Uri "
7140                            + grantUri);
7141                }
7142            }
7143        }
7144
7145        // Third...  does the caller itself have permission to access
7146        // this uri?
7147        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7148            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7149                // Require they hold a strong enough Uri permission
7150                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7151                    throw new SecurityException("Uid " + callingUid
7152                            + " does not have permission to uri " + grantUri);
7153                }
7154            }
7155        }
7156        return targetUid;
7157    }
7158
7159    /**
7160     * @param uri This uri must NOT contain an embedded userId.
7161     * @param userId The userId in which the uri is to be resolved.
7162     */
7163    @Override
7164    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7165            final int modeFlags, int userId) {
7166        enforceNotIsolatedCaller("checkGrantUriPermission");
7167        synchronized(this) {
7168            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7169                    new GrantUri(userId, uri, false), modeFlags, -1);
7170        }
7171    }
7172
7173    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7174            final int modeFlags, UriPermissionOwner owner) {
7175        if (!Intent.isAccessUriMode(modeFlags)) {
7176            return;
7177        }
7178
7179        // So here we are: the caller has the assumed permission
7180        // to the uri, and the target doesn't.  Let's now give this to
7181        // the target.
7182
7183        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7184                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7185
7186        final String authority = grantUri.uri.getAuthority();
7187        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7188        if (pi == null) {
7189            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7190            return;
7191        }
7192
7193        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7194            grantUri.prefix = true;
7195        }
7196        final UriPermission perm = findOrCreateUriPermissionLocked(
7197                pi.packageName, targetPkg, targetUid, grantUri);
7198        perm.grantModes(modeFlags, owner);
7199    }
7200
7201    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7202            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7203        if (targetPkg == null) {
7204            throw new NullPointerException("targetPkg");
7205        }
7206        int targetUid;
7207        final IPackageManager pm = AppGlobals.getPackageManager();
7208        try {
7209            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7210        } catch (RemoteException ex) {
7211            return;
7212        }
7213
7214        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7215                targetUid);
7216        if (targetUid < 0) {
7217            return;
7218        }
7219
7220        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7221                owner);
7222    }
7223
7224    static class NeededUriGrants extends ArrayList<GrantUri> {
7225        final String targetPkg;
7226        final int targetUid;
7227        final int flags;
7228
7229        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7230            this.targetPkg = targetPkg;
7231            this.targetUid = targetUid;
7232            this.flags = flags;
7233        }
7234    }
7235
7236    /**
7237     * Like checkGrantUriPermissionLocked, but takes an Intent.
7238     */
7239    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7240            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7241        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7242                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7243                + " clip=" + (intent != null ? intent.getClipData() : null)
7244                + " from " + intent + "; flags=0x"
7245                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7246
7247        if (targetPkg == null) {
7248            throw new NullPointerException("targetPkg");
7249        }
7250
7251        if (intent == null) {
7252            return null;
7253        }
7254        Uri data = intent.getData();
7255        ClipData clip = intent.getClipData();
7256        if (data == null && clip == null) {
7257            return null;
7258        }
7259        // Default userId for uris in the intent (if they don't specify it themselves)
7260        int contentUserHint = intent.getContentUserHint();
7261        if (contentUserHint == UserHandle.USER_CURRENT) {
7262            contentUserHint = UserHandle.getUserId(callingUid);
7263        }
7264        final IPackageManager pm = AppGlobals.getPackageManager();
7265        int targetUid;
7266        if (needed != null) {
7267            targetUid = needed.targetUid;
7268        } else {
7269            try {
7270                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7271            } catch (RemoteException ex) {
7272                return null;
7273            }
7274            if (targetUid < 0) {
7275                if (DEBUG_URI_PERMISSION) {
7276                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7277                            + " on user " + targetUserId);
7278                }
7279                return null;
7280            }
7281        }
7282        if (data != null) {
7283            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7284            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7285                    targetUid);
7286            if (targetUid > 0) {
7287                if (needed == null) {
7288                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7289                }
7290                needed.add(grantUri);
7291            }
7292        }
7293        if (clip != null) {
7294            for (int i=0; i<clip.getItemCount(); i++) {
7295                Uri uri = clip.getItemAt(i).getUri();
7296                if (uri != null) {
7297                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7298                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7299                            targetUid);
7300                    if (targetUid > 0) {
7301                        if (needed == null) {
7302                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7303                        }
7304                        needed.add(grantUri);
7305                    }
7306                } else {
7307                    Intent clipIntent = clip.getItemAt(i).getIntent();
7308                    if (clipIntent != null) {
7309                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7310                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7311                        if (newNeeded != null) {
7312                            needed = newNeeded;
7313                        }
7314                    }
7315                }
7316            }
7317        }
7318
7319        return needed;
7320    }
7321
7322    /**
7323     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7324     */
7325    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7326            UriPermissionOwner owner) {
7327        if (needed != null) {
7328            for (int i=0; i<needed.size(); i++) {
7329                GrantUri grantUri = needed.get(i);
7330                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7331                        grantUri, needed.flags, owner);
7332            }
7333        }
7334    }
7335
7336    void grantUriPermissionFromIntentLocked(int callingUid,
7337            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7338        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7339                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7340        if (needed == null) {
7341            return;
7342        }
7343
7344        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7345    }
7346
7347    /**
7348     * @param uri This uri must NOT contain an embedded userId.
7349     * @param userId The userId in which the uri is to be resolved.
7350     */
7351    @Override
7352    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7353            final int modeFlags, int userId) {
7354        enforceNotIsolatedCaller("grantUriPermission");
7355        GrantUri grantUri = new GrantUri(userId, uri, false);
7356        synchronized(this) {
7357            final ProcessRecord r = getRecordForAppLocked(caller);
7358            if (r == null) {
7359                throw new SecurityException("Unable to find app for caller "
7360                        + caller
7361                        + " when granting permission to uri " + grantUri);
7362            }
7363            if (targetPkg == null) {
7364                throw new IllegalArgumentException("null target");
7365            }
7366            if (grantUri == null) {
7367                throw new IllegalArgumentException("null uri");
7368            }
7369
7370            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7371                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7372                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7373                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7374
7375            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7376                    UserHandle.getUserId(r.uid));
7377        }
7378    }
7379
7380    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7381        if (perm.modeFlags == 0) {
7382            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7383                    perm.targetUid);
7384            if (perms != null) {
7385                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7386                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7387
7388                perms.remove(perm.uri);
7389                if (perms.isEmpty()) {
7390                    mGrantedUriPermissions.remove(perm.targetUid);
7391                }
7392            }
7393        }
7394    }
7395
7396    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7397        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7398
7399        final IPackageManager pm = AppGlobals.getPackageManager();
7400        final String authority = grantUri.uri.getAuthority();
7401        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7402        if (pi == null) {
7403            Slog.w(TAG, "No content provider found for permission revoke: "
7404                    + grantUri.toSafeString());
7405            return;
7406        }
7407
7408        // Does the caller have this permission on the URI?
7409        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7410            // If they don't have direct access to the URI, then revoke any
7411            // ownerless URI permissions that have been granted to them.
7412            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7413            if (perms != null) {
7414                boolean persistChanged = false;
7415                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7416                    final UriPermission perm = it.next();
7417                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7418                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7419                        if (DEBUG_URI_PERMISSION)
7420                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7421                                    " permission to " + perm.uri);
7422                        persistChanged |= perm.revokeModes(
7423                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7424                        if (perm.modeFlags == 0) {
7425                            it.remove();
7426                        }
7427                    }
7428                }
7429                if (perms.isEmpty()) {
7430                    mGrantedUriPermissions.remove(callingUid);
7431                }
7432                if (persistChanged) {
7433                    schedulePersistUriGrants();
7434                }
7435            }
7436            return;
7437        }
7438
7439        boolean persistChanged = false;
7440
7441        // Go through all of the permissions and remove any that match.
7442        int N = mGrantedUriPermissions.size();
7443        for (int i = 0; i < N; i++) {
7444            final int targetUid = mGrantedUriPermissions.keyAt(i);
7445            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7446
7447            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7448                final UriPermission perm = it.next();
7449                if (perm.uri.sourceUserId == grantUri.sourceUserId
7450                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7451                    if (DEBUG_URI_PERMISSION)
7452                        Slog.v(TAG,
7453                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7454                    persistChanged |= perm.revokeModes(
7455                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7456                    if (perm.modeFlags == 0) {
7457                        it.remove();
7458                    }
7459                }
7460            }
7461
7462            if (perms.isEmpty()) {
7463                mGrantedUriPermissions.remove(targetUid);
7464                N--;
7465                i--;
7466            }
7467        }
7468
7469        if (persistChanged) {
7470            schedulePersistUriGrants();
7471        }
7472    }
7473
7474    /**
7475     * @param uri This uri must NOT contain an embedded userId.
7476     * @param userId The userId in which the uri is to be resolved.
7477     */
7478    @Override
7479    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7480            int userId) {
7481        enforceNotIsolatedCaller("revokeUriPermission");
7482        synchronized(this) {
7483            final ProcessRecord r = getRecordForAppLocked(caller);
7484            if (r == null) {
7485                throw new SecurityException("Unable to find app for caller "
7486                        + caller
7487                        + " when revoking permission to uri " + uri);
7488            }
7489            if (uri == null) {
7490                Slog.w(TAG, "revokeUriPermission: null uri");
7491                return;
7492            }
7493
7494            if (!Intent.isAccessUriMode(modeFlags)) {
7495                return;
7496            }
7497
7498            final IPackageManager pm = AppGlobals.getPackageManager();
7499            final String authority = uri.getAuthority();
7500            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7501            if (pi == null) {
7502                Slog.w(TAG, "No content provider found for permission revoke: "
7503                        + uri.toSafeString());
7504                return;
7505            }
7506
7507            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7508        }
7509    }
7510
7511    /**
7512     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7513     * given package.
7514     *
7515     * @param packageName Package name to match, or {@code null} to apply to all
7516     *            packages.
7517     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7518     *            to all users.
7519     * @param persistable If persistable grants should be removed.
7520     */
7521    private void removeUriPermissionsForPackageLocked(
7522            String packageName, int userHandle, boolean persistable) {
7523        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7524            throw new IllegalArgumentException("Must narrow by either package or user");
7525        }
7526
7527        boolean persistChanged = false;
7528
7529        int N = mGrantedUriPermissions.size();
7530        for (int i = 0; i < N; i++) {
7531            final int targetUid = mGrantedUriPermissions.keyAt(i);
7532            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7533
7534            // Only inspect grants matching user
7535            if (userHandle == UserHandle.USER_ALL
7536                    || userHandle == UserHandle.getUserId(targetUid)) {
7537                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7538                    final UriPermission perm = it.next();
7539
7540                    // Only inspect grants matching package
7541                    if (packageName == null || perm.sourcePkg.equals(packageName)
7542                            || perm.targetPkg.equals(packageName)) {
7543                        persistChanged |= perm.revokeModes(persistable
7544                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7545
7546                        // Only remove when no modes remain; any persisted grants
7547                        // will keep this alive.
7548                        if (perm.modeFlags == 0) {
7549                            it.remove();
7550                        }
7551                    }
7552                }
7553
7554                if (perms.isEmpty()) {
7555                    mGrantedUriPermissions.remove(targetUid);
7556                    N--;
7557                    i--;
7558                }
7559            }
7560        }
7561
7562        if (persistChanged) {
7563            schedulePersistUriGrants();
7564        }
7565    }
7566
7567    @Override
7568    public IBinder newUriPermissionOwner(String name) {
7569        enforceNotIsolatedCaller("newUriPermissionOwner");
7570        synchronized(this) {
7571            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7572            return owner.getExternalTokenLocked();
7573        }
7574    }
7575
7576    /**
7577     * @param uri This uri must NOT contain an embedded userId.
7578     * @param sourceUserId The userId in which the uri is to be resolved.
7579     * @param targetUserId The userId of the app that receives the grant.
7580     */
7581    @Override
7582    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7583            final int modeFlags, int sourceUserId, int targetUserId) {
7584        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7585                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7586        synchronized(this) {
7587            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7588            if (owner == null) {
7589                throw new IllegalArgumentException("Unknown owner: " + token);
7590            }
7591            if (fromUid != Binder.getCallingUid()) {
7592                if (Binder.getCallingUid() != Process.myUid()) {
7593                    // Only system code can grant URI permissions on behalf
7594                    // of other users.
7595                    throw new SecurityException("nice try");
7596                }
7597            }
7598            if (targetPkg == null) {
7599                throw new IllegalArgumentException("null target");
7600            }
7601            if (uri == null) {
7602                throw new IllegalArgumentException("null uri");
7603            }
7604
7605            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7606                    modeFlags, owner, targetUserId);
7607        }
7608    }
7609
7610    /**
7611     * @param uri This uri must NOT contain an embedded userId.
7612     * @param userId The userId in which the uri is to be resolved.
7613     */
7614    @Override
7615    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7616        synchronized(this) {
7617            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7618            if (owner == null) {
7619                throw new IllegalArgumentException("Unknown owner: " + token);
7620            }
7621
7622            if (uri == null) {
7623                owner.removeUriPermissionsLocked(mode);
7624            } else {
7625                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7626            }
7627        }
7628    }
7629
7630    private void schedulePersistUriGrants() {
7631        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7632            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7633                    10 * DateUtils.SECOND_IN_MILLIS);
7634        }
7635    }
7636
7637    private void writeGrantedUriPermissions() {
7638        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7639
7640        // Snapshot permissions so we can persist without lock
7641        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7642        synchronized (this) {
7643            final int size = mGrantedUriPermissions.size();
7644            for (int i = 0; i < size; i++) {
7645                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7646                for (UriPermission perm : perms.values()) {
7647                    if (perm.persistedModeFlags != 0) {
7648                        persist.add(perm.snapshot());
7649                    }
7650                }
7651            }
7652        }
7653
7654        FileOutputStream fos = null;
7655        try {
7656            fos = mGrantFile.startWrite();
7657
7658            XmlSerializer out = new FastXmlSerializer();
7659            out.setOutput(fos, "utf-8");
7660            out.startDocument(null, true);
7661            out.startTag(null, TAG_URI_GRANTS);
7662            for (UriPermission.Snapshot perm : persist) {
7663                out.startTag(null, TAG_URI_GRANT);
7664                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7665                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7666                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7667                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7668                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7669                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7670                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7671                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7672                out.endTag(null, TAG_URI_GRANT);
7673            }
7674            out.endTag(null, TAG_URI_GRANTS);
7675            out.endDocument();
7676
7677            mGrantFile.finishWrite(fos);
7678        } catch (IOException e) {
7679            if (fos != null) {
7680                mGrantFile.failWrite(fos);
7681            }
7682        }
7683    }
7684
7685    private void readGrantedUriPermissionsLocked() {
7686        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7687
7688        final long now = System.currentTimeMillis();
7689
7690        FileInputStream fis = null;
7691        try {
7692            fis = mGrantFile.openRead();
7693            final XmlPullParser in = Xml.newPullParser();
7694            in.setInput(fis, null);
7695
7696            int type;
7697            while ((type = in.next()) != END_DOCUMENT) {
7698                final String tag = in.getName();
7699                if (type == START_TAG) {
7700                    if (TAG_URI_GRANT.equals(tag)) {
7701                        final int sourceUserId;
7702                        final int targetUserId;
7703                        final int userHandle = readIntAttribute(in,
7704                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7705                        if (userHandle != UserHandle.USER_NULL) {
7706                            // For backwards compatibility.
7707                            sourceUserId = userHandle;
7708                            targetUserId = userHandle;
7709                        } else {
7710                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7711                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7712                        }
7713                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7714                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7715                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7716                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7717                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7718                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7719
7720                        // Sanity check that provider still belongs to source package
7721                        final ProviderInfo pi = getProviderInfoLocked(
7722                                uri.getAuthority(), sourceUserId);
7723                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7724                            int targetUid = -1;
7725                            try {
7726                                targetUid = AppGlobals.getPackageManager()
7727                                        .getPackageUid(targetPkg, targetUserId);
7728                            } catch (RemoteException e) {
7729                            }
7730                            if (targetUid != -1) {
7731                                final UriPermission perm = findOrCreateUriPermissionLocked(
7732                                        sourcePkg, targetPkg, targetUid,
7733                                        new GrantUri(sourceUserId, uri, prefix));
7734                                perm.initPersistedModes(modeFlags, createdTime);
7735                            }
7736                        } else {
7737                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7738                                    + " but instead found " + pi);
7739                        }
7740                    }
7741                }
7742            }
7743        } catch (FileNotFoundException e) {
7744            // Missing grants is okay
7745        } catch (IOException e) {
7746            Slog.wtf(TAG, "Failed reading Uri grants", e);
7747        } catch (XmlPullParserException e) {
7748            Slog.wtf(TAG, "Failed reading Uri grants", e);
7749        } finally {
7750            IoUtils.closeQuietly(fis);
7751        }
7752    }
7753
7754    /**
7755     * @param uri This uri must NOT contain an embedded userId.
7756     * @param userId The userId in which the uri is to be resolved.
7757     */
7758    @Override
7759    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7760        enforceNotIsolatedCaller("takePersistableUriPermission");
7761
7762        Preconditions.checkFlagsArgument(modeFlags,
7763                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7764
7765        synchronized (this) {
7766            final int callingUid = Binder.getCallingUid();
7767            boolean persistChanged = false;
7768            GrantUri grantUri = new GrantUri(userId, uri, false);
7769
7770            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7771                    new GrantUri(userId, uri, false));
7772            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7773                    new GrantUri(userId, uri, true));
7774
7775            final boolean exactValid = (exactPerm != null)
7776                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7777            final boolean prefixValid = (prefixPerm != null)
7778                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7779
7780            if (!(exactValid || prefixValid)) {
7781                throw new SecurityException("No persistable permission grants found for UID "
7782                        + callingUid + " and Uri " + grantUri.toSafeString());
7783            }
7784
7785            if (exactValid) {
7786                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7787            }
7788            if (prefixValid) {
7789                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7790            }
7791
7792            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7793
7794            if (persistChanged) {
7795                schedulePersistUriGrants();
7796            }
7797        }
7798    }
7799
7800    /**
7801     * @param uri This uri must NOT contain an embedded userId.
7802     * @param userId The userId in which the uri is to be resolved.
7803     */
7804    @Override
7805    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7806        enforceNotIsolatedCaller("releasePersistableUriPermission");
7807
7808        Preconditions.checkFlagsArgument(modeFlags,
7809                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7810
7811        synchronized (this) {
7812            final int callingUid = Binder.getCallingUid();
7813            boolean persistChanged = false;
7814
7815            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7816                    new GrantUri(userId, uri, false));
7817            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7818                    new GrantUri(userId, uri, true));
7819            if (exactPerm == null && prefixPerm == null) {
7820                throw new SecurityException("No permission grants found for UID " + callingUid
7821                        + " and Uri " + uri.toSafeString());
7822            }
7823
7824            if (exactPerm != null) {
7825                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7826                removeUriPermissionIfNeededLocked(exactPerm);
7827            }
7828            if (prefixPerm != null) {
7829                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7830                removeUriPermissionIfNeededLocked(prefixPerm);
7831            }
7832
7833            if (persistChanged) {
7834                schedulePersistUriGrants();
7835            }
7836        }
7837    }
7838
7839    /**
7840     * Prune any older {@link UriPermission} for the given UID until outstanding
7841     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7842     *
7843     * @return if any mutations occured that require persisting.
7844     */
7845    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7846        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7847        if (perms == null) return false;
7848        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7849
7850        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7851        for (UriPermission perm : perms.values()) {
7852            if (perm.persistedModeFlags != 0) {
7853                persisted.add(perm);
7854            }
7855        }
7856
7857        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7858        if (trimCount <= 0) return false;
7859
7860        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7861        for (int i = 0; i < trimCount; i++) {
7862            final UriPermission perm = persisted.get(i);
7863
7864            if (DEBUG_URI_PERMISSION) {
7865                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7866            }
7867
7868            perm.releasePersistableModes(~0);
7869            removeUriPermissionIfNeededLocked(perm);
7870        }
7871
7872        return true;
7873    }
7874
7875    @Override
7876    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7877            String packageName, boolean incoming) {
7878        enforceNotIsolatedCaller("getPersistedUriPermissions");
7879        Preconditions.checkNotNull(packageName, "packageName");
7880
7881        final int callingUid = Binder.getCallingUid();
7882        final IPackageManager pm = AppGlobals.getPackageManager();
7883        try {
7884            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7885            if (packageUid != callingUid) {
7886                throw new SecurityException(
7887                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7888            }
7889        } catch (RemoteException e) {
7890            throw new SecurityException("Failed to verify package name ownership");
7891        }
7892
7893        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7894        synchronized (this) {
7895            if (incoming) {
7896                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7897                        callingUid);
7898                if (perms == null) {
7899                    Slog.w(TAG, "No permission grants found for " + packageName);
7900                } else {
7901                    for (UriPermission perm : perms.values()) {
7902                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7903                            result.add(perm.buildPersistedPublicApiObject());
7904                        }
7905                    }
7906                }
7907            } else {
7908                final int size = mGrantedUriPermissions.size();
7909                for (int i = 0; i < size; i++) {
7910                    final ArrayMap<GrantUri, UriPermission> perms =
7911                            mGrantedUriPermissions.valueAt(i);
7912                    for (UriPermission perm : perms.values()) {
7913                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7914                            result.add(perm.buildPersistedPublicApiObject());
7915                        }
7916                    }
7917                }
7918            }
7919        }
7920        return new ParceledListSlice<android.content.UriPermission>(result);
7921    }
7922
7923    @Override
7924    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7925        synchronized (this) {
7926            ProcessRecord app =
7927                who != null ? getRecordForAppLocked(who) : null;
7928            if (app == null) return;
7929
7930            Message msg = Message.obtain();
7931            msg.what = WAIT_FOR_DEBUGGER_MSG;
7932            msg.obj = app;
7933            msg.arg1 = waiting ? 1 : 0;
7934            mHandler.sendMessage(msg);
7935        }
7936    }
7937
7938    @Override
7939    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7940        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7941        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7942        outInfo.availMem = Process.getFreeMemory();
7943        outInfo.totalMem = Process.getTotalMemory();
7944        outInfo.threshold = homeAppMem;
7945        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7946        outInfo.hiddenAppThreshold = cachedAppMem;
7947        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7948                ProcessList.SERVICE_ADJ);
7949        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7950                ProcessList.VISIBLE_APP_ADJ);
7951        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7952                ProcessList.FOREGROUND_APP_ADJ);
7953    }
7954
7955    // =========================================================
7956    // TASK MANAGEMENT
7957    // =========================================================
7958
7959    @Override
7960    public List<IAppTask> getAppTasks(String callingPackage) {
7961        int callingUid = Binder.getCallingUid();
7962        long ident = Binder.clearCallingIdentity();
7963
7964        synchronized(this) {
7965            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7966            try {
7967                if (localLOGV) Slog.v(TAG, "getAppTasks");
7968
7969                final int N = mRecentTasks.size();
7970                for (int i = 0; i < N; i++) {
7971                    TaskRecord tr = mRecentTasks.get(i);
7972                    // Skip tasks that do not match the caller.  We don't need to verify
7973                    // callingPackage, because we are also limiting to callingUid and know
7974                    // that will limit to the correct security sandbox.
7975                    if (tr.effectiveUid != callingUid) {
7976                        continue;
7977                    }
7978                    Intent intent = tr.getBaseIntent();
7979                    if (intent == null ||
7980                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7981                        continue;
7982                    }
7983                    ActivityManager.RecentTaskInfo taskInfo =
7984                            createRecentTaskInfoFromTaskRecord(tr);
7985                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7986                    list.add(taskImpl);
7987                }
7988            } finally {
7989                Binder.restoreCallingIdentity(ident);
7990            }
7991            return list;
7992        }
7993    }
7994
7995    @Override
7996    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7997        final int callingUid = Binder.getCallingUid();
7998        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7999
8000        synchronized(this) {
8001            if (localLOGV) Slog.v(
8002                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8003
8004            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8005                    callingUid);
8006
8007            // TODO: Improve with MRU list from all ActivityStacks.
8008            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8009        }
8010
8011        return list;
8012    }
8013
8014    TaskRecord getMostRecentTask() {
8015        return mRecentTasks.get(0);
8016    }
8017
8018    /**
8019     * Creates a new RecentTaskInfo from a TaskRecord.
8020     */
8021    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8022        // Update the task description to reflect any changes in the task stack
8023        tr.updateTaskDescription();
8024
8025        // Compose the recent task info
8026        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8027        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8028        rti.persistentId = tr.taskId;
8029        rti.baseIntent = new Intent(tr.getBaseIntent());
8030        rti.origActivity = tr.origActivity;
8031        rti.description = tr.lastDescription;
8032        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8033        rti.userId = tr.userId;
8034        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8035        rti.firstActiveTime = tr.firstActiveTime;
8036        rti.lastActiveTime = tr.lastActiveTime;
8037        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8038        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8039        return rti;
8040    }
8041
8042    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8043        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8044                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8045        if (!allowed) {
8046            if (checkPermission(android.Manifest.permission.GET_TASKS,
8047                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8048                // Temporary compatibility: some existing apps on the system image may
8049                // still be requesting the old permission and not switched to the new
8050                // one; if so, we'll still allow them full access.  This means we need
8051                // to see if they are holding the old permission and are a system app.
8052                try {
8053                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8054                        allowed = true;
8055                        Slog.w(TAG, caller + ": caller " + callingUid
8056                                + " is using old GET_TASKS but privileged; allowing");
8057                    }
8058                } catch (RemoteException e) {
8059                }
8060            }
8061        }
8062        if (!allowed) {
8063            Slog.w(TAG, caller + ": caller " + callingUid
8064                    + " does not hold GET_TASKS; limiting output");
8065        }
8066        return allowed;
8067    }
8068
8069    @Override
8070    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8071        final int callingUid = Binder.getCallingUid();
8072        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8073                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8074
8075        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8076        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8077        synchronized (this) {
8078            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8079                    callingUid);
8080            final boolean detailed = checkCallingPermission(
8081                    android.Manifest.permission.GET_DETAILED_TASKS)
8082                    == PackageManager.PERMISSION_GRANTED;
8083
8084            final int N = mRecentTasks.size();
8085            ArrayList<ActivityManager.RecentTaskInfo> res
8086                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8087                            maxNum < N ? maxNum : N);
8088
8089            final Set<Integer> includedUsers;
8090            if (includeProfiles) {
8091                includedUsers = getProfileIdsLocked(userId);
8092            } else {
8093                includedUsers = new HashSet<Integer>();
8094            }
8095            includedUsers.add(Integer.valueOf(userId));
8096
8097            for (int i=0; i<N && maxNum > 0; i++) {
8098                TaskRecord tr = mRecentTasks.get(i);
8099                // Only add calling user or related users recent tasks
8100                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8101                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8102                    continue;
8103                }
8104
8105                // Return the entry if desired by the caller.  We always return
8106                // the first entry, because callers always expect this to be the
8107                // foreground app.  We may filter others if the caller has
8108                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8109                // we should exclude the entry.
8110
8111                if (i == 0
8112                        || withExcluded
8113                        || (tr.intent == null)
8114                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8115                                == 0)) {
8116                    if (!allowed) {
8117                        // If the caller doesn't have the GET_TASKS permission, then only
8118                        // allow them to see a small subset of tasks -- their own and home.
8119                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8120                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8121                            continue;
8122                        }
8123                    }
8124                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8125                        if (tr.stack != null && tr.stack.isHomeStack()) {
8126                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8127                            continue;
8128                        }
8129                    }
8130                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8131                        // Don't include auto remove tasks that are finished or finishing.
8132                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8133                                + tr);
8134                        continue;
8135                    }
8136                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8137                            && !tr.isAvailable) {
8138                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8139                        continue;
8140                    }
8141
8142                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8143                    if (!detailed) {
8144                        rti.baseIntent.replaceExtras((Bundle)null);
8145                    }
8146
8147                    res.add(rti);
8148                    maxNum--;
8149                }
8150            }
8151            return res;
8152        }
8153    }
8154
8155    private TaskRecord recentTaskForIdLocked(int id) {
8156        final int N = mRecentTasks.size();
8157            for (int i=0; i<N; i++) {
8158                TaskRecord tr = mRecentTasks.get(i);
8159                if (tr.taskId == id) {
8160                    return tr;
8161                }
8162            }
8163            return null;
8164    }
8165
8166    @Override
8167    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8168        synchronized (this) {
8169            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8170                    "getTaskThumbnail()");
8171            TaskRecord tr = recentTaskForIdLocked(id);
8172            if (tr != null) {
8173                return tr.getTaskThumbnailLocked();
8174            }
8175        }
8176        return null;
8177    }
8178
8179    @Override
8180    public int addAppTask(IBinder activityToken, Intent intent,
8181            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8182        final int callingUid = Binder.getCallingUid();
8183        final long callingIdent = Binder.clearCallingIdentity();
8184
8185        try {
8186            synchronized (this) {
8187                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8188                if (r == null) {
8189                    throw new IllegalArgumentException("Activity does not exist; token="
8190                            + activityToken);
8191                }
8192                ComponentName comp = intent.getComponent();
8193                if (comp == null) {
8194                    throw new IllegalArgumentException("Intent " + intent
8195                            + " must specify explicit component");
8196                }
8197                if (thumbnail.getWidth() != mThumbnailWidth
8198                        || thumbnail.getHeight() != mThumbnailHeight) {
8199                    throw new IllegalArgumentException("Bad thumbnail size: got "
8200                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8201                            + mThumbnailWidth + "x" + mThumbnailHeight);
8202                }
8203                if (intent.getSelector() != null) {
8204                    intent.setSelector(null);
8205                }
8206                if (intent.getSourceBounds() != null) {
8207                    intent.setSourceBounds(null);
8208                }
8209                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8210                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8211                        // The caller has added this as an auto-remove task...  that makes no
8212                        // sense, so turn off auto-remove.
8213                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8214                    }
8215                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8216                    // Must be a new task.
8217                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8218                }
8219                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8220                    mLastAddedTaskActivity = null;
8221                }
8222                ActivityInfo ainfo = mLastAddedTaskActivity;
8223                if (ainfo == null) {
8224                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8225                            comp, 0, UserHandle.getUserId(callingUid));
8226                    if (ainfo.applicationInfo.uid != callingUid) {
8227                        throw new SecurityException(
8228                                "Can't add task for another application: target uid="
8229                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8230                    }
8231                }
8232
8233                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8234                        intent, description);
8235
8236                int trimIdx = trimRecentsForTask(task, false);
8237                if (trimIdx >= 0) {
8238                    // If this would have caused a trim, then we'll abort because that
8239                    // means it would be added at the end of the list but then just removed.
8240                    return -1;
8241                }
8242
8243                final int N = mRecentTasks.size();
8244                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8245                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8246                    tr.removedFromRecents(mTaskPersister);
8247                }
8248
8249                task.inRecents = true;
8250                mRecentTasks.add(task);
8251                r.task.stack.addTask(task, false, false);
8252
8253                task.setLastThumbnail(thumbnail);
8254                task.freeLastThumbnail();
8255
8256                return task.taskId;
8257            }
8258        } finally {
8259            Binder.restoreCallingIdentity(callingIdent);
8260        }
8261    }
8262
8263    @Override
8264    public Point getAppTaskThumbnailSize() {
8265        synchronized (this) {
8266            return new Point(mThumbnailWidth,  mThumbnailHeight);
8267        }
8268    }
8269
8270    @Override
8271    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8272        synchronized (this) {
8273            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8274            if (r != null) {
8275                r.setTaskDescription(td);
8276                r.task.updateTaskDescription();
8277            }
8278        }
8279    }
8280
8281    @Override
8282    public Bitmap getTaskDescriptionIcon(String filename) {
8283        if (!FileUtils.isValidExtFilename(filename)
8284                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8285            throw new IllegalArgumentException("Bad filename: " + filename);
8286        }
8287        return mTaskPersister.getTaskDescriptionIcon(filename);
8288    }
8289
8290    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8291        mRecentTasks.remove(tr);
8292        tr.removedFromRecents(mTaskPersister);
8293        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8294        Intent baseIntent = new Intent(
8295                tr.intent != null ? tr.intent : tr.affinityIntent);
8296        ComponentName component = baseIntent.getComponent();
8297        if (component == null) {
8298            Slog.w(TAG, "Now component for base intent of task: " + tr);
8299            return;
8300        }
8301
8302        // Find any running services associated with this app.
8303        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8304
8305        if (killProcesses) {
8306            // Find any running processes associated with this app.
8307            final String pkg = component.getPackageName();
8308            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8309            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8310            for (int i=0; i<pmap.size(); i++) {
8311                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8312                for (int j=0; j<uids.size(); j++) {
8313                    ProcessRecord proc = uids.valueAt(j);
8314                    if (proc.userId != tr.userId) {
8315                        continue;
8316                    }
8317                    if (!proc.pkgList.containsKey(pkg)) {
8318                        continue;
8319                    }
8320                    procs.add(proc);
8321                }
8322            }
8323
8324            // Kill the running processes.
8325            for (int i=0; i<procs.size(); i++) {
8326                ProcessRecord pr = procs.get(i);
8327                if (pr == mHomeProcess) {
8328                    // Don't kill the home process along with tasks from the same package.
8329                    continue;
8330                }
8331                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8332                    pr.kill("remove task", true);
8333                } else {
8334                    pr.waitingToKill = "remove task";
8335                }
8336            }
8337        }
8338    }
8339
8340    /**
8341     * Removes the task with the specified task id.
8342     *
8343     * @param taskId Identifier of the task to be removed.
8344     * @param flags Additional operational flags.  May be 0 or
8345     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8346     * @return Returns true if the given task was found and removed.
8347     */
8348    private boolean removeTaskByIdLocked(int taskId, int flags) {
8349        TaskRecord tr = recentTaskForIdLocked(taskId);
8350        if (tr != null) {
8351            tr.removeTaskActivitiesLocked();
8352            cleanUpRemovedTaskLocked(tr, flags);
8353            if (tr.isPersistable) {
8354                notifyTaskPersisterLocked(null, true);
8355            }
8356            return true;
8357        }
8358        return false;
8359    }
8360
8361    @Override
8362    public boolean removeTask(int taskId, int flags) {
8363        synchronized (this) {
8364            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8365                    "removeTask()");
8366            long ident = Binder.clearCallingIdentity();
8367            try {
8368                return removeTaskByIdLocked(taskId, flags);
8369            } finally {
8370                Binder.restoreCallingIdentity(ident);
8371            }
8372        }
8373    }
8374
8375    /**
8376     * TODO: Add mController hook
8377     */
8378    @Override
8379    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8380        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8381                "moveTaskToFront()");
8382
8383        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8384        synchronized(this) {
8385            moveTaskToFrontLocked(taskId, flags, options);
8386        }
8387    }
8388
8389    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8390        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8391                Binder.getCallingUid(), -1, -1, "Task to front")) {
8392            ActivityOptions.abort(options);
8393            return;
8394        }
8395        final long origId = Binder.clearCallingIdentity();
8396        try {
8397            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8398            if (task == null) {
8399                return;
8400            }
8401            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8402                mStackSupervisor.showLockTaskToast();
8403                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8404                return;
8405            }
8406            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8407            if (prev != null && prev.isRecentsActivity()) {
8408                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8409            }
8410            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8411        } finally {
8412            Binder.restoreCallingIdentity(origId);
8413        }
8414        ActivityOptions.abort(options);
8415    }
8416
8417    @Override
8418    public void moveTaskToBack(int taskId) {
8419        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8420                "moveTaskToBack()");
8421
8422        synchronized(this) {
8423            TaskRecord tr = recentTaskForIdLocked(taskId);
8424            if (tr != null) {
8425                if (tr == mStackSupervisor.mLockTaskModeTask) {
8426                    mStackSupervisor.showLockTaskToast();
8427                    return;
8428                }
8429                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8430                ActivityStack stack = tr.stack;
8431                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8432                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8433                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8434                        return;
8435                    }
8436                }
8437                final long origId = Binder.clearCallingIdentity();
8438                try {
8439                    stack.moveTaskToBackLocked(taskId, null);
8440                } finally {
8441                    Binder.restoreCallingIdentity(origId);
8442                }
8443            }
8444        }
8445    }
8446
8447    /**
8448     * Moves an activity, and all of the other activities within the same task, to the bottom
8449     * of the history stack.  The activity's order within the task is unchanged.
8450     *
8451     * @param token A reference to the activity we wish to move
8452     * @param nonRoot If false then this only works if the activity is the root
8453     *                of a task; if true it will work for any activity in a task.
8454     * @return Returns true if the move completed, false if not.
8455     */
8456    @Override
8457    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8458        enforceNotIsolatedCaller("moveActivityTaskToBack");
8459        synchronized(this) {
8460            final long origId = Binder.clearCallingIdentity();
8461            try {
8462                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8463                if (taskId >= 0) {
8464                    if ((mStackSupervisor.mLockTaskModeTask != null)
8465                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8466                        mStackSupervisor.showLockTaskToast();
8467                        return false;
8468                    }
8469                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8470                }
8471            } finally {
8472                Binder.restoreCallingIdentity(origId);
8473            }
8474        }
8475        return false;
8476    }
8477
8478    @Override
8479    public void moveTaskBackwards(int task) {
8480        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8481                "moveTaskBackwards()");
8482
8483        synchronized(this) {
8484            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8485                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8486                return;
8487            }
8488            final long origId = Binder.clearCallingIdentity();
8489            moveTaskBackwardsLocked(task);
8490            Binder.restoreCallingIdentity(origId);
8491        }
8492    }
8493
8494    private final void moveTaskBackwardsLocked(int task) {
8495        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8496    }
8497
8498    @Override
8499    public IBinder getHomeActivityToken() throws RemoteException {
8500        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8501                "getHomeActivityToken()");
8502        synchronized (this) {
8503            return mStackSupervisor.getHomeActivityToken();
8504        }
8505    }
8506
8507    @Override
8508    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8509            IActivityContainerCallback callback) throws RemoteException {
8510        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8511                "createActivityContainer()");
8512        synchronized (this) {
8513            if (parentActivityToken == null) {
8514                throw new IllegalArgumentException("parent token must not be null");
8515            }
8516            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8517            if (r == null) {
8518                return null;
8519            }
8520            if (callback == null) {
8521                throw new IllegalArgumentException("callback must not be null");
8522            }
8523            return mStackSupervisor.createActivityContainer(r, callback);
8524        }
8525    }
8526
8527    @Override
8528    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8529        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8530                "deleteActivityContainer()");
8531        synchronized (this) {
8532            mStackSupervisor.deleteActivityContainer(container);
8533        }
8534    }
8535
8536    @Override
8537    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8538            throws RemoteException {
8539        synchronized (this) {
8540            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8541            if (stack != null) {
8542                return stack.mActivityContainer;
8543            }
8544            return null;
8545        }
8546    }
8547
8548    @Override
8549    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8550        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8551                "moveTaskToStack()");
8552        if (stackId == HOME_STACK_ID) {
8553            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8554                    new RuntimeException("here").fillInStackTrace());
8555        }
8556        synchronized (this) {
8557            long ident = Binder.clearCallingIdentity();
8558            try {
8559                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8560                        + stackId + " toTop=" + toTop);
8561                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8562            } finally {
8563                Binder.restoreCallingIdentity(ident);
8564            }
8565        }
8566    }
8567
8568    @Override
8569    public void resizeStack(int stackBoxId, Rect bounds) {
8570        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8571                "resizeStackBox()");
8572        long ident = Binder.clearCallingIdentity();
8573        try {
8574            mWindowManager.resizeStack(stackBoxId, bounds);
8575        } finally {
8576            Binder.restoreCallingIdentity(ident);
8577        }
8578    }
8579
8580    @Override
8581    public List<StackInfo> getAllStackInfos() {
8582        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8583                "getAllStackInfos()");
8584        long ident = Binder.clearCallingIdentity();
8585        try {
8586            synchronized (this) {
8587                return mStackSupervisor.getAllStackInfosLocked();
8588            }
8589        } finally {
8590            Binder.restoreCallingIdentity(ident);
8591        }
8592    }
8593
8594    @Override
8595    public StackInfo getStackInfo(int stackId) {
8596        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8597                "getStackInfo()");
8598        long ident = Binder.clearCallingIdentity();
8599        try {
8600            synchronized (this) {
8601                return mStackSupervisor.getStackInfoLocked(stackId);
8602            }
8603        } finally {
8604            Binder.restoreCallingIdentity(ident);
8605        }
8606    }
8607
8608    @Override
8609    public boolean isInHomeStack(int taskId) {
8610        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8611                "getStackInfo()");
8612        long ident = Binder.clearCallingIdentity();
8613        try {
8614            synchronized (this) {
8615                TaskRecord tr = recentTaskForIdLocked(taskId);
8616                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8617            }
8618        } finally {
8619            Binder.restoreCallingIdentity(ident);
8620        }
8621    }
8622
8623    @Override
8624    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8625        synchronized(this) {
8626            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8627        }
8628    }
8629
8630    private boolean isLockTaskAuthorized(String pkg) {
8631        final DevicePolicyManager dpm = (DevicePolicyManager)
8632                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8633        try {
8634            int uid = mContext.getPackageManager().getPackageUid(pkg,
8635                    Binder.getCallingUserHandle().getIdentifier());
8636            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8637        } catch (NameNotFoundException e) {
8638            return false;
8639        }
8640    }
8641
8642    void startLockTaskMode(TaskRecord task) {
8643        final String pkg;
8644        synchronized (this) {
8645            pkg = task.intent.getComponent().getPackageName();
8646        }
8647        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8648        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8649            final TaskRecord taskRecord = task;
8650            mHandler.post(new Runnable() {
8651                @Override
8652                public void run() {
8653                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8654                }
8655            });
8656            return;
8657        }
8658        long ident = Binder.clearCallingIdentity();
8659        try {
8660            synchronized (this) {
8661                // Since we lost lock on task, make sure it is still there.
8662                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8663                if (task != null) {
8664                    if (!isSystemInitiated
8665                            && ((mStackSupervisor.getFocusedStack() == null)
8666                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8667                        throw new IllegalArgumentException("Invalid task, not in foreground");
8668                    }
8669                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8670                }
8671            }
8672        } finally {
8673            Binder.restoreCallingIdentity(ident);
8674        }
8675    }
8676
8677    @Override
8678    public void startLockTaskMode(int taskId) {
8679        final TaskRecord task;
8680        long ident = Binder.clearCallingIdentity();
8681        try {
8682            synchronized (this) {
8683                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8684            }
8685        } finally {
8686            Binder.restoreCallingIdentity(ident);
8687        }
8688        if (task != null) {
8689            startLockTaskMode(task);
8690        }
8691    }
8692
8693    @Override
8694    public void startLockTaskMode(IBinder token) {
8695        final TaskRecord task;
8696        long ident = Binder.clearCallingIdentity();
8697        try {
8698            synchronized (this) {
8699                final ActivityRecord r = ActivityRecord.forToken(token);
8700                if (r == null) {
8701                    return;
8702                }
8703                task = r.task;
8704            }
8705        } finally {
8706            Binder.restoreCallingIdentity(ident);
8707        }
8708        if (task != null) {
8709            startLockTaskMode(task);
8710        }
8711    }
8712
8713    @Override
8714    public void startLockTaskModeOnCurrent() throws RemoteException {
8715        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8716                "startLockTaskModeOnCurrent");
8717        ActivityRecord r = null;
8718        synchronized (this) {
8719            r = mStackSupervisor.topRunningActivityLocked();
8720        }
8721        startLockTaskMode(r.task);
8722    }
8723
8724    @Override
8725    public void stopLockTaskMode() {
8726        // Verify that the user matches the package of the intent for the TaskRecord
8727        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8728        // and stopLockTaskMode.
8729        final int callingUid = Binder.getCallingUid();
8730        if (callingUid != Process.SYSTEM_UID) {
8731            try {
8732                String pkg =
8733                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8734                int uid = mContext.getPackageManager().getPackageUid(pkg,
8735                        Binder.getCallingUserHandle().getIdentifier());
8736                if (uid != callingUid) {
8737                    throw new SecurityException("Invalid uid, expected " + uid);
8738                }
8739            } catch (NameNotFoundException e) {
8740                Log.d(TAG, "stopLockTaskMode " + e);
8741                return;
8742            }
8743        }
8744        long ident = Binder.clearCallingIdentity();
8745        try {
8746            Log.d(TAG, "stopLockTaskMode");
8747            // Stop lock task
8748            synchronized (this) {
8749                mStackSupervisor.setLockTaskModeLocked(null, false);
8750            }
8751        } finally {
8752            Binder.restoreCallingIdentity(ident);
8753        }
8754    }
8755
8756    @Override
8757    public void stopLockTaskModeOnCurrent() throws RemoteException {
8758        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8759                "stopLockTaskModeOnCurrent");
8760        long ident = Binder.clearCallingIdentity();
8761        try {
8762            stopLockTaskMode();
8763        } finally {
8764            Binder.restoreCallingIdentity(ident);
8765        }
8766    }
8767
8768    @Override
8769    public boolean isInLockTaskMode() {
8770        synchronized (this) {
8771            return mStackSupervisor.isInLockTaskMode();
8772        }
8773    }
8774
8775    // =========================================================
8776    // CONTENT PROVIDERS
8777    // =========================================================
8778
8779    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8780        List<ProviderInfo> providers = null;
8781        try {
8782            providers = AppGlobals.getPackageManager().
8783                queryContentProviders(app.processName, app.uid,
8784                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8785        } catch (RemoteException ex) {
8786        }
8787        if (DEBUG_MU)
8788            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8789        int userId = app.userId;
8790        if (providers != null) {
8791            int N = providers.size();
8792            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8793            for (int i=0; i<N; i++) {
8794                ProviderInfo cpi =
8795                    (ProviderInfo)providers.get(i);
8796                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8797                        cpi.name, cpi.flags);
8798                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8799                    // This is a singleton provider, but a user besides the
8800                    // default user is asking to initialize a process it runs
8801                    // in...  well, no, it doesn't actually run in this process,
8802                    // it runs in the process of the default user.  Get rid of it.
8803                    providers.remove(i);
8804                    N--;
8805                    i--;
8806                    continue;
8807                }
8808
8809                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8810                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8811                if (cpr == null) {
8812                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8813                    mProviderMap.putProviderByClass(comp, cpr);
8814                }
8815                if (DEBUG_MU)
8816                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8817                app.pubProviders.put(cpi.name, cpr);
8818                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8819                    // Don't add this if it is a platform component that is marked
8820                    // to run in multiple processes, because this is actually
8821                    // part of the framework so doesn't make sense to track as a
8822                    // separate apk in the process.
8823                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8824                            mProcessStats);
8825                }
8826                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8827            }
8828        }
8829        return providers;
8830    }
8831
8832    /**
8833     * Check if {@link ProcessRecord} has a possible chance at accessing the
8834     * given {@link ProviderInfo}. Final permission checking is always done
8835     * in {@link ContentProvider}.
8836     */
8837    private final String checkContentProviderPermissionLocked(
8838            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8839        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8840        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8841        boolean checkedGrants = false;
8842        if (checkUser) {
8843            // Looking for cross-user grants before enforcing the typical cross-users permissions
8844            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8845            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8846                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8847                    return null;
8848                }
8849                checkedGrants = true;
8850            }
8851            userId = handleIncomingUser(callingPid, callingUid, userId,
8852                    false, ALLOW_NON_FULL,
8853                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8854            if (userId != tmpTargetUserId) {
8855                // When we actually went to determine the final targer user ID, this ended
8856                // up different than our initial check for the authority.  This is because
8857                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8858                // SELF.  So we need to re-check the grants again.
8859                checkedGrants = false;
8860            }
8861        }
8862        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8863                cpi.applicationInfo.uid, cpi.exported)
8864                == PackageManager.PERMISSION_GRANTED) {
8865            return null;
8866        }
8867        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8868                cpi.applicationInfo.uid, cpi.exported)
8869                == PackageManager.PERMISSION_GRANTED) {
8870            return null;
8871        }
8872
8873        PathPermission[] pps = cpi.pathPermissions;
8874        if (pps != null) {
8875            int i = pps.length;
8876            while (i > 0) {
8877                i--;
8878                PathPermission pp = pps[i];
8879                String pprperm = pp.getReadPermission();
8880                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8881                        cpi.applicationInfo.uid, cpi.exported)
8882                        == PackageManager.PERMISSION_GRANTED) {
8883                    return null;
8884                }
8885                String ppwperm = pp.getWritePermission();
8886                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8887                        cpi.applicationInfo.uid, cpi.exported)
8888                        == PackageManager.PERMISSION_GRANTED) {
8889                    return null;
8890                }
8891            }
8892        }
8893        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8894            return null;
8895        }
8896
8897        String msg;
8898        if (!cpi.exported) {
8899            msg = "Permission Denial: opening provider " + cpi.name
8900                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8901                    + ", uid=" + callingUid + ") that is not exported from uid "
8902                    + cpi.applicationInfo.uid;
8903        } else {
8904            msg = "Permission Denial: opening provider " + cpi.name
8905                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8906                    + ", uid=" + callingUid + ") requires "
8907                    + cpi.readPermission + " or " + cpi.writePermission;
8908        }
8909        Slog.w(TAG, msg);
8910        return msg;
8911    }
8912
8913    /**
8914     * Returns if the ContentProvider has granted a uri to callingUid
8915     */
8916    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8917        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8918        if (perms != null) {
8919            for (int i=perms.size()-1; i>=0; i--) {
8920                GrantUri grantUri = perms.keyAt(i);
8921                if (grantUri.sourceUserId == userId || !checkUser) {
8922                    if (matchesProvider(grantUri.uri, cpi)) {
8923                        return true;
8924                    }
8925                }
8926            }
8927        }
8928        return false;
8929    }
8930
8931    /**
8932     * Returns true if the uri authority is one of the authorities specified in the provider.
8933     */
8934    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8935        String uriAuth = uri.getAuthority();
8936        String cpiAuth = cpi.authority;
8937        if (cpiAuth.indexOf(';') == -1) {
8938            return cpiAuth.equals(uriAuth);
8939        }
8940        String[] cpiAuths = cpiAuth.split(";");
8941        int length = cpiAuths.length;
8942        for (int i = 0; i < length; i++) {
8943            if (cpiAuths[i].equals(uriAuth)) return true;
8944        }
8945        return false;
8946    }
8947
8948    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8949            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8950        if (r != null) {
8951            for (int i=0; i<r.conProviders.size(); i++) {
8952                ContentProviderConnection conn = r.conProviders.get(i);
8953                if (conn.provider == cpr) {
8954                    if (DEBUG_PROVIDER) Slog.v(TAG,
8955                            "Adding provider requested by "
8956                            + r.processName + " from process "
8957                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8958                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8959                    if (stable) {
8960                        conn.stableCount++;
8961                        conn.numStableIncs++;
8962                    } else {
8963                        conn.unstableCount++;
8964                        conn.numUnstableIncs++;
8965                    }
8966                    return conn;
8967                }
8968            }
8969            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8970            if (stable) {
8971                conn.stableCount = 1;
8972                conn.numStableIncs = 1;
8973            } else {
8974                conn.unstableCount = 1;
8975                conn.numUnstableIncs = 1;
8976            }
8977            cpr.connections.add(conn);
8978            r.conProviders.add(conn);
8979            return conn;
8980        }
8981        cpr.addExternalProcessHandleLocked(externalProcessToken);
8982        return null;
8983    }
8984
8985    boolean decProviderCountLocked(ContentProviderConnection conn,
8986            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8987        if (conn != null) {
8988            cpr = conn.provider;
8989            if (DEBUG_PROVIDER) Slog.v(TAG,
8990                    "Removing provider requested by "
8991                    + conn.client.processName + " from process "
8992                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8993                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8994            if (stable) {
8995                conn.stableCount--;
8996            } else {
8997                conn.unstableCount--;
8998            }
8999            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9000                cpr.connections.remove(conn);
9001                conn.client.conProviders.remove(conn);
9002                return true;
9003            }
9004            return false;
9005        }
9006        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9007        return false;
9008    }
9009
9010    private void checkTime(long startTime, String where) {
9011        long now = SystemClock.elapsedRealtime();
9012        if ((now-startTime) > 1000) {
9013            // If we are taking more than a second, log about it.
9014            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9015        }
9016    }
9017
9018    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9019            String name, IBinder token, boolean stable, int userId) {
9020        ContentProviderRecord cpr;
9021        ContentProviderConnection conn = null;
9022        ProviderInfo cpi = null;
9023
9024        synchronized(this) {
9025            long startTime = SystemClock.elapsedRealtime();
9026
9027            ProcessRecord r = null;
9028            if (caller != null) {
9029                r = getRecordForAppLocked(caller);
9030                if (r == null) {
9031                    throw new SecurityException(
9032                            "Unable to find app for caller " + caller
9033                          + " (pid=" + Binder.getCallingPid()
9034                          + ") when getting content provider " + name);
9035                }
9036            }
9037
9038            boolean checkCrossUser = true;
9039
9040            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9041
9042            // First check if this content provider has been published...
9043            cpr = mProviderMap.getProviderByName(name, userId);
9044            // If that didn't work, check if it exists for user 0 and then
9045            // verify that it's a singleton provider before using it.
9046            if (cpr == null && userId != UserHandle.USER_OWNER) {
9047                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9048                if (cpr != null) {
9049                    cpi = cpr.info;
9050                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9051                            cpi.name, cpi.flags)
9052                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9053                        userId = UserHandle.USER_OWNER;
9054                        checkCrossUser = false;
9055                    } else {
9056                        cpr = null;
9057                        cpi = null;
9058                    }
9059                }
9060            }
9061
9062            boolean providerRunning = cpr != null;
9063            if (providerRunning) {
9064                cpi = cpr.info;
9065                String msg;
9066                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9067                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9068                        != null) {
9069                    throw new SecurityException(msg);
9070                }
9071                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9072
9073                if (r != null && cpr.canRunHere(r)) {
9074                    // This provider has been published or is in the process
9075                    // of being published...  but it is also allowed to run
9076                    // in the caller's process, so don't make a connection
9077                    // and just let the caller instantiate its own instance.
9078                    ContentProviderHolder holder = cpr.newHolder(null);
9079                    // don't give caller the provider object, it needs
9080                    // to make its own.
9081                    holder.provider = null;
9082                    return holder;
9083                }
9084
9085                final long origId = Binder.clearCallingIdentity();
9086
9087                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9088
9089                // In this case the provider instance already exists, so we can
9090                // return it right away.
9091                conn = incProviderCountLocked(r, cpr, token, stable);
9092                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9093                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9094                        // If this is a perceptible app accessing the provider,
9095                        // make sure to count it as being accessed and thus
9096                        // back up on the LRU list.  This is good because
9097                        // content providers are often expensive to start.
9098                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9099                        updateLruProcessLocked(cpr.proc, false, null);
9100                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9101                    }
9102                }
9103
9104                if (cpr.proc != null) {
9105                    if (false) {
9106                        if (cpr.name.flattenToShortString().equals(
9107                                "com.android.providers.calendar/.CalendarProvider2")) {
9108                            Slog.v(TAG, "****************** KILLING "
9109                                + cpr.name.flattenToShortString());
9110                            Process.killProcess(cpr.proc.pid);
9111                        }
9112                    }
9113                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9114                    boolean success = updateOomAdjLocked(cpr.proc);
9115                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9116                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9117                    // NOTE: there is still a race here where a signal could be
9118                    // pending on the process even though we managed to update its
9119                    // adj level.  Not sure what to do about this, but at least
9120                    // the race is now smaller.
9121                    if (!success) {
9122                        // Uh oh...  it looks like the provider's process
9123                        // has been killed on us.  We need to wait for a new
9124                        // process to be started, and make sure its death
9125                        // doesn't kill our process.
9126                        Slog.i(TAG,
9127                                "Existing provider " + cpr.name.flattenToShortString()
9128                                + " is crashing; detaching " + r);
9129                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9130                        checkTime(startTime, "getContentProviderImpl: before appDied");
9131                        appDiedLocked(cpr.proc);
9132                        checkTime(startTime, "getContentProviderImpl: after appDied");
9133                        if (!lastRef) {
9134                            // This wasn't the last ref our process had on
9135                            // the provider...  we have now been killed, bail.
9136                            return null;
9137                        }
9138                        providerRunning = false;
9139                        conn = null;
9140                    }
9141                }
9142
9143                Binder.restoreCallingIdentity(origId);
9144            }
9145
9146            boolean singleton;
9147            if (!providerRunning) {
9148                try {
9149                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9150                    cpi = AppGlobals.getPackageManager().
9151                        resolveContentProvider(name,
9152                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9153                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9154                } catch (RemoteException ex) {
9155                }
9156                if (cpi == null) {
9157                    return null;
9158                }
9159                // If the provider is a singleton AND
9160                // (it's a call within the same user || the provider is a
9161                // privileged app)
9162                // Then allow connecting to the singleton provider
9163                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9164                        cpi.name, cpi.flags)
9165                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9166                if (singleton) {
9167                    userId = UserHandle.USER_OWNER;
9168                }
9169                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9170                checkTime(startTime, "getContentProviderImpl: got app info for user");
9171
9172                String msg;
9173                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9174                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9175                        != null) {
9176                    throw new SecurityException(msg);
9177                }
9178                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9179
9180                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9181                        && !cpi.processName.equals("system")) {
9182                    // If this content provider does not run in the system
9183                    // process, and the system is not yet ready to run other
9184                    // processes, then fail fast instead of hanging.
9185                    throw new IllegalArgumentException(
9186                            "Attempt to launch content provider before system ready");
9187                }
9188
9189                // Make sure that the user who owns this provider is started.  If not,
9190                // we don't want to allow it to run.
9191                if (mStartedUsers.get(userId) == null) {
9192                    Slog.w(TAG, "Unable to launch app "
9193                            + cpi.applicationInfo.packageName + "/"
9194                            + cpi.applicationInfo.uid + " for provider "
9195                            + name + ": user " + userId + " is stopped");
9196                    return null;
9197                }
9198
9199                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9200                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9201                cpr = mProviderMap.getProviderByClass(comp, userId);
9202                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9203                final boolean firstClass = cpr == null;
9204                if (firstClass) {
9205                    final long ident = Binder.clearCallingIdentity();
9206                    try {
9207                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9208                        ApplicationInfo ai =
9209                            AppGlobals.getPackageManager().
9210                                getApplicationInfo(
9211                                        cpi.applicationInfo.packageName,
9212                                        STOCK_PM_FLAGS, userId);
9213                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9214                        if (ai == null) {
9215                            Slog.w(TAG, "No package info for content provider "
9216                                    + cpi.name);
9217                            return null;
9218                        }
9219                        ai = getAppInfoForUser(ai, userId);
9220                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9221                    } catch (RemoteException ex) {
9222                        // pm is in same process, this will never happen.
9223                    } finally {
9224                        Binder.restoreCallingIdentity(ident);
9225                    }
9226                }
9227
9228                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9229
9230                if (r != null && cpr.canRunHere(r)) {
9231                    // If this is a multiprocess provider, then just return its
9232                    // info and allow the caller to instantiate it.  Only do
9233                    // this if the provider is the same user as the caller's
9234                    // process, or can run as root (so can be in any process).
9235                    return cpr.newHolder(null);
9236                }
9237
9238                if (DEBUG_PROVIDER) {
9239                    RuntimeException e = new RuntimeException("here");
9240                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9241                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9242                }
9243
9244                // This is single process, and our app is now connecting to it.
9245                // See if we are already in the process of launching this
9246                // provider.
9247                final int N = mLaunchingProviders.size();
9248                int i;
9249                for (i=0; i<N; i++) {
9250                    if (mLaunchingProviders.get(i) == cpr) {
9251                        break;
9252                    }
9253                }
9254
9255                // If the provider is not already being launched, then get it
9256                // started.
9257                if (i >= N) {
9258                    final long origId = Binder.clearCallingIdentity();
9259
9260                    try {
9261                        // Content provider is now in use, its package can't be stopped.
9262                        try {
9263                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9264                            AppGlobals.getPackageManager().setPackageStoppedState(
9265                                    cpr.appInfo.packageName, false, userId);
9266                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9267                        } catch (RemoteException e) {
9268                        } catch (IllegalArgumentException e) {
9269                            Slog.w(TAG, "Failed trying to unstop package "
9270                                    + cpr.appInfo.packageName + ": " + e);
9271                        }
9272
9273                        // Use existing process if already started
9274                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9275                        ProcessRecord proc = getProcessRecordLocked(
9276                                cpi.processName, cpr.appInfo.uid, false);
9277                        if (proc != null && proc.thread != null) {
9278                            if (DEBUG_PROVIDER) {
9279                                Slog.d(TAG, "Installing in existing process " + proc);
9280                            }
9281                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9282                            proc.pubProviders.put(cpi.name, cpr);
9283                            try {
9284                                proc.thread.scheduleInstallProvider(cpi);
9285                            } catch (RemoteException e) {
9286                            }
9287                        } else {
9288                            checkTime(startTime, "getContentProviderImpl: before start process");
9289                            proc = startProcessLocked(cpi.processName,
9290                                    cpr.appInfo, false, 0, "content provider",
9291                                    new ComponentName(cpi.applicationInfo.packageName,
9292                                            cpi.name), false, false, false);
9293                            checkTime(startTime, "getContentProviderImpl: after start process");
9294                            if (proc == null) {
9295                                Slog.w(TAG, "Unable to launch app "
9296                                        + cpi.applicationInfo.packageName + "/"
9297                                        + cpi.applicationInfo.uid + " for provider "
9298                                        + name + ": process is bad");
9299                                return null;
9300                            }
9301                        }
9302                        cpr.launchingApp = proc;
9303                        mLaunchingProviders.add(cpr);
9304                    } finally {
9305                        Binder.restoreCallingIdentity(origId);
9306                    }
9307                }
9308
9309                checkTime(startTime, "getContentProviderImpl: updating data structures");
9310
9311                // Make sure the provider is published (the same provider class
9312                // may be published under multiple names).
9313                if (firstClass) {
9314                    mProviderMap.putProviderByClass(comp, cpr);
9315                }
9316
9317                mProviderMap.putProviderByName(name, cpr);
9318                conn = incProviderCountLocked(r, cpr, token, stable);
9319                if (conn != null) {
9320                    conn.waiting = true;
9321                }
9322            }
9323            checkTime(startTime, "getContentProviderImpl: done!");
9324        }
9325
9326        // Wait for the provider to be published...
9327        synchronized (cpr) {
9328            while (cpr.provider == null) {
9329                if (cpr.launchingApp == null) {
9330                    Slog.w(TAG, "Unable to launch app "
9331                            + cpi.applicationInfo.packageName + "/"
9332                            + cpi.applicationInfo.uid + " for provider "
9333                            + name + ": launching app became null");
9334                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9335                            UserHandle.getUserId(cpi.applicationInfo.uid),
9336                            cpi.applicationInfo.packageName,
9337                            cpi.applicationInfo.uid, name);
9338                    return null;
9339                }
9340                try {
9341                    if (DEBUG_MU) {
9342                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9343                                + cpr.launchingApp);
9344                    }
9345                    if (conn != null) {
9346                        conn.waiting = true;
9347                    }
9348                    cpr.wait();
9349                } catch (InterruptedException ex) {
9350                } finally {
9351                    if (conn != null) {
9352                        conn.waiting = false;
9353                    }
9354                }
9355            }
9356        }
9357        return cpr != null ? cpr.newHolder(conn) : null;
9358    }
9359
9360    @Override
9361    public final ContentProviderHolder getContentProvider(
9362            IApplicationThread caller, String name, int userId, boolean stable) {
9363        enforceNotIsolatedCaller("getContentProvider");
9364        if (caller == null) {
9365            String msg = "null IApplicationThread when getting content provider "
9366                    + name;
9367            Slog.w(TAG, msg);
9368            throw new SecurityException(msg);
9369        }
9370        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9371        // with cross-user grant.
9372        return getContentProviderImpl(caller, name, null, stable, userId);
9373    }
9374
9375    public ContentProviderHolder getContentProviderExternal(
9376            String name, int userId, IBinder token) {
9377        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9378            "Do not have permission in call getContentProviderExternal()");
9379        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9380                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9381        return getContentProviderExternalUnchecked(name, token, userId);
9382    }
9383
9384    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9385            IBinder token, int userId) {
9386        return getContentProviderImpl(null, name, token, true, userId);
9387    }
9388
9389    /**
9390     * Drop a content provider from a ProcessRecord's bookkeeping
9391     */
9392    public void removeContentProvider(IBinder connection, boolean stable) {
9393        enforceNotIsolatedCaller("removeContentProvider");
9394        long ident = Binder.clearCallingIdentity();
9395        try {
9396            synchronized (this) {
9397                ContentProviderConnection conn;
9398                try {
9399                    conn = (ContentProviderConnection)connection;
9400                } catch (ClassCastException e) {
9401                    String msg ="removeContentProvider: " + connection
9402                            + " not a ContentProviderConnection";
9403                    Slog.w(TAG, msg);
9404                    throw new IllegalArgumentException(msg);
9405                }
9406                if (conn == null) {
9407                    throw new NullPointerException("connection is null");
9408                }
9409                if (decProviderCountLocked(conn, null, null, stable)) {
9410                    updateOomAdjLocked();
9411                }
9412            }
9413        } finally {
9414            Binder.restoreCallingIdentity(ident);
9415        }
9416    }
9417
9418    public void removeContentProviderExternal(String name, IBinder token) {
9419        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9420            "Do not have permission in call removeContentProviderExternal()");
9421        int userId = UserHandle.getCallingUserId();
9422        long ident = Binder.clearCallingIdentity();
9423        try {
9424            removeContentProviderExternalUnchecked(name, token, userId);
9425        } finally {
9426            Binder.restoreCallingIdentity(ident);
9427        }
9428    }
9429
9430    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9431        synchronized (this) {
9432            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9433            if(cpr == null) {
9434                //remove from mProvidersByClass
9435                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9436                return;
9437            }
9438
9439            //update content provider record entry info
9440            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9441            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9442            if (localCpr.hasExternalProcessHandles()) {
9443                if (localCpr.removeExternalProcessHandleLocked(token)) {
9444                    updateOomAdjLocked();
9445                } else {
9446                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9447                            + " with no external reference for token: "
9448                            + token + ".");
9449                }
9450            } else {
9451                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9452                        + " with no external references.");
9453            }
9454        }
9455    }
9456
9457    public final void publishContentProviders(IApplicationThread caller,
9458            List<ContentProviderHolder> providers) {
9459        if (providers == null) {
9460            return;
9461        }
9462
9463        enforceNotIsolatedCaller("publishContentProviders");
9464        synchronized (this) {
9465            final ProcessRecord r = getRecordForAppLocked(caller);
9466            if (DEBUG_MU)
9467                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9468            if (r == null) {
9469                throw new SecurityException(
9470                        "Unable to find app for caller " + caller
9471                      + " (pid=" + Binder.getCallingPid()
9472                      + ") when publishing content providers");
9473            }
9474
9475            final long origId = Binder.clearCallingIdentity();
9476
9477            final int N = providers.size();
9478            for (int i=0; i<N; i++) {
9479                ContentProviderHolder src = providers.get(i);
9480                if (src == null || src.info == null || src.provider == null) {
9481                    continue;
9482                }
9483                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9484                if (DEBUG_MU)
9485                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9486                if (dst != null) {
9487                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9488                    mProviderMap.putProviderByClass(comp, dst);
9489                    String names[] = dst.info.authority.split(";");
9490                    for (int j = 0; j < names.length; j++) {
9491                        mProviderMap.putProviderByName(names[j], dst);
9492                    }
9493
9494                    int NL = mLaunchingProviders.size();
9495                    int j;
9496                    for (j=0; j<NL; j++) {
9497                        if (mLaunchingProviders.get(j) == dst) {
9498                            mLaunchingProviders.remove(j);
9499                            j--;
9500                            NL--;
9501                        }
9502                    }
9503                    synchronized (dst) {
9504                        dst.provider = src.provider;
9505                        dst.proc = r;
9506                        dst.notifyAll();
9507                    }
9508                    updateOomAdjLocked(r);
9509                }
9510            }
9511
9512            Binder.restoreCallingIdentity(origId);
9513        }
9514    }
9515
9516    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9517        ContentProviderConnection conn;
9518        try {
9519            conn = (ContentProviderConnection)connection;
9520        } catch (ClassCastException e) {
9521            String msg ="refContentProvider: " + connection
9522                    + " not a ContentProviderConnection";
9523            Slog.w(TAG, msg);
9524            throw new IllegalArgumentException(msg);
9525        }
9526        if (conn == null) {
9527            throw new NullPointerException("connection is null");
9528        }
9529
9530        synchronized (this) {
9531            if (stable > 0) {
9532                conn.numStableIncs += stable;
9533            }
9534            stable = conn.stableCount + stable;
9535            if (stable < 0) {
9536                throw new IllegalStateException("stableCount < 0: " + stable);
9537            }
9538
9539            if (unstable > 0) {
9540                conn.numUnstableIncs += unstable;
9541            }
9542            unstable = conn.unstableCount + unstable;
9543            if (unstable < 0) {
9544                throw new IllegalStateException("unstableCount < 0: " + unstable);
9545            }
9546
9547            if ((stable+unstable) <= 0) {
9548                throw new IllegalStateException("ref counts can't go to zero here: stable="
9549                        + stable + " unstable=" + unstable);
9550            }
9551            conn.stableCount = stable;
9552            conn.unstableCount = unstable;
9553            return !conn.dead;
9554        }
9555    }
9556
9557    public void unstableProviderDied(IBinder connection) {
9558        ContentProviderConnection conn;
9559        try {
9560            conn = (ContentProviderConnection)connection;
9561        } catch (ClassCastException e) {
9562            String msg ="refContentProvider: " + connection
9563                    + " not a ContentProviderConnection";
9564            Slog.w(TAG, msg);
9565            throw new IllegalArgumentException(msg);
9566        }
9567        if (conn == null) {
9568            throw new NullPointerException("connection is null");
9569        }
9570
9571        // Safely retrieve the content provider associated with the connection.
9572        IContentProvider provider;
9573        synchronized (this) {
9574            provider = conn.provider.provider;
9575        }
9576
9577        if (provider == null) {
9578            // Um, yeah, we're way ahead of you.
9579            return;
9580        }
9581
9582        // Make sure the caller is being honest with us.
9583        if (provider.asBinder().pingBinder()) {
9584            // Er, no, still looks good to us.
9585            synchronized (this) {
9586                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9587                        + " says " + conn + " died, but we don't agree");
9588                return;
9589            }
9590        }
9591
9592        // Well look at that!  It's dead!
9593        synchronized (this) {
9594            if (conn.provider.provider != provider) {
9595                // But something changed...  good enough.
9596                return;
9597            }
9598
9599            ProcessRecord proc = conn.provider.proc;
9600            if (proc == null || proc.thread == null) {
9601                // Seems like the process is already cleaned up.
9602                return;
9603            }
9604
9605            // As far as we're concerned, this is just like receiving a
9606            // death notification...  just a bit prematurely.
9607            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9608                    + ") early provider death");
9609            final long ident = Binder.clearCallingIdentity();
9610            try {
9611                appDiedLocked(proc);
9612            } finally {
9613                Binder.restoreCallingIdentity(ident);
9614            }
9615        }
9616    }
9617
9618    @Override
9619    public void appNotRespondingViaProvider(IBinder connection) {
9620        enforceCallingPermission(
9621                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9622
9623        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9624        if (conn == null) {
9625            Slog.w(TAG, "ContentProviderConnection is null");
9626            return;
9627        }
9628
9629        final ProcessRecord host = conn.provider.proc;
9630        if (host == null) {
9631            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9632            return;
9633        }
9634
9635        final long token = Binder.clearCallingIdentity();
9636        try {
9637            appNotResponding(host, null, null, false, "ContentProvider not responding");
9638        } finally {
9639            Binder.restoreCallingIdentity(token);
9640        }
9641    }
9642
9643    public final void installSystemProviders() {
9644        List<ProviderInfo> providers;
9645        synchronized (this) {
9646            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9647            providers = generateApplicationProvidersLocked(app);
9648            if (providers != null) {
9649                for (int i=providers.size()-1; i>=0; i--) {
9650                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9651                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9652                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9653                                + ": not system .apk");
9654                        providers.remove(i);
9655                    }
9656                }
9657            }
9658        }
9659        if (providers != null) {
9660            mSystemThread.installSystemProviders(providers);
9661        }
9662
9663        mCoreSettingsObserver = new CoreSettingsObserver(this);
9664
9665        //mUsageStatsService.monitorPackages();
9666    }
9667
9668    /**
9669     * Allows apps to retrieve the MIME type of a URI.
9670     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9671     * users, then it does not need permission to access the ContentProvider.
9672     * Either, it needs cross-user uri grants.
9673     *
9674     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9675     *
9676     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9677     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9678     */
9679    public String getProviderMimeType(Uri uri, int userId) {
9680        enforceNotIsolatedCaller("getProviderMimeType");
9681        final String name = uri.getAuthority();
9682        int callingUid = Binder.getCallingUid();
9683        int callingPid = Binder.getCallingPid();
9684        long ident = 0;
9685        boolean clearedIdentity = false;
9686        userId = unsafeConvertIncomingUser(userId);
9687        if (canClearIdentity(callingPid, callingUid, userId)) {
9688            clearedIdentity = true;
9689            ident = Binder.clearCallingIdentity();
9690        }
9691        ContentProviderHolder holder = null;
9692        try {
9693            holder = getContentProviderExternalUnchecked(name, null, userId);
9694            if (holder != null) {
9695                return holder.provider.getType(uri);
9696            }
9697        } catch (RemoteException e) {
9698            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9699            return null;
9700        } finally {
9701            // We need to clear the identity to call removeContentProviderExternalUnchecked
9702            if (!clearedIdentity) {
9703                ident = Binder.clearCallingIdentity();
9704            }
9705            try {
9706                if (holder != null) {
9707                    removeContentProviderExternalUnchecked(name, null, userId);
9708                }
9709            } finally {
9710                Binder.restoreCallingIdentity(ident);
9711            }
9712        }
9713
9714        return null;
9715    }
9716
9717    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9718        if (UserHandle.getUserId(callingUid) == userId) {
9719            return true;
9720        }
9721        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9722                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9723                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9724                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9725                return true;
9726        }
9727        return false;
9728    }
9729
9730    // =========================================================
9731    // GLOBAL MANAGEMENT
9732    // =========================================================
9733
9734    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9735            boolean isolated, int isolatedUid) {
9736        String proc = customProcess != null ? customProcess : info.processName;
9737        BatteryStatsImpl.Uid.Proc ps = null;
9738        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9739        int uid = info.uid;
9740        if (isolated) {
9741            if (isolatedUid == 0) {
9742                int userId = UserHandle.getUserId(uid);
9743                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9744                while (true) {
9745                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9746                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9747                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9748                    }
9749                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9750                    mNextIsolatedProcessUid++;
9751                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9752                        // No process for this uid, use it.
9753                        break;
9754                    }
9755                    stepsLeft--;
9756                    if (stepsLeft <= 0) {
9757                        return null;
9758                    }
9759                }
9760            } else {
9761                // Special case for startIsolatedProcess (internal only), where
9762                // the uid of the isolated process is specified by the caller.
9763                uid = isolatedUid;
9764            }
9765        }
9766        return new ProcessRecord(stats, info, proc, uid);
9767    }
9768
9769    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9770            String abiOverride) {
9771        ProcessRecord app;
9772        if (!isolated) {
9773            app = getProcessRecordLocked(info.processName, info.uid, true);
9774        } else {
9775            app = null;
9776        }
9777
9778        if (app == null) {
9779            app = newProcessRecordLocked(info, null, isolated, 0);
9780            mProcessNames.put(info.processName, app.uid, app);
9781            if (isolated) {
9782                mIsolatedProcesses.put(app.uid, app);
9783            }
9784            updateLruProcessLocked(app, false, null);
9785            updateOomAdjLocked();
9786        }
9787
9788        // This package really, really can not be stopped.
9789        try {
9790            AppGlobals.getPackageManager().setPackageStoppedState(
9791                    info.packageName, false, UserHandle.getUserId(app.uid));
9792        } catch (RemoteException e) {
9793        } catch (IllegalArgumentException e) {
9794            Slog.w(TAG, "Failed trying to unstop package "
9795                    + info.packageName + ": " + e);
9796        }
9797
9798        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9799                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9800            app.persistent = true;
9801            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9802        }
9803        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9804            mPersistentStartingProcesses.add(app);
9805            startProcessLocked(app, "added application", app.processName, abiOverride,
9806                    null /* entryPoint */, null /* entryPointArgs */);
9807        }
9808
9809        return app;
9810    }
9811
9812    public void unhandledBack() {
9813        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9814                "unhandledBack()");
9815
9816        synchronized(this) {
9817            final long origId = Binder.clearCallingIdentity();
9818            try {
9819                getFocusedStack().unhandledBackLocked();
9820            } finally {
9821                Binder.restoreCallingIdentity(origId);
9822            }
9823        }
9824    }
9825
9826    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9827        enforceNotIsolatedCaller("openContentUri");
9828        final int userId = UserHandle.getCallingUserId();
9829        String name = uri.getAuthority();
9830        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9831        ParcelFileDescriptor pfd = null;
9832        if (cph != null) {
9833            // We record the binder invoker's uid in thread-local storage before
9834            // going to the content provider to open the file.  Later, in the code
9835            // that handles all permissions checks, we look for this uid and use
9836            // that rather than the Activity Manager's own uid.  The effect is that
9837            // we do the check against the caller's permissions even though it looks
9838            // to the content provider like the Activity Manager itself is making
9839            // the request.
9840            sCallerIdentity.set(new Identity(
9841                    Binder.getCallingPid(), Binder.getCallingUid()));
9842            try {
9843                pfd = cph.provider.openFile(null, uri, "r", null);
9844            } catch (FileNotFoundException e) {
9845                // do nothing; pfd will be returned null
9846            } finally {
9847                // Ensure that whatever happens, we clean up the identity state
9848                sCallerIdentity.remove();
9849            }
9850
9851            // We've got the fd now, so we're done with the provider.
9852            removeContentProviderExternalUnchecked(name, null, userId);
9853        } else {
9854            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9855        }
9856        return pfd;
9857    }
9858
9859    // Actually is sleeping or shutting down or whatever else in the future
9860    // is an inactive state.
9861    public boolean isSleepingOrShuttingDown() {
9862        return isSleeping() || mShuttingDown;
9863    }
9864
9865    public boolean isSleeping() {
9866        return mSleeping;
9867    }
9868
9869    void goingToSleep() {
9870        synchronized(this) {
9871            mWentToSleep = true;
9872            goToSleepIfNeededLocked();
9873        }
9874    }
9875
9876    void finishRunningVoiceLocked() {
9877        if (mRunningVoice) {
9878            mRunningVoice = false;
9879            goToSleepIfNeededLocked();
9880        }
9881    }
9882
9883    void goToSleepIfNeededLocked() {
9884        if (mWentToSleep && !mRunningVoice) {
9885            if (!mSleeping) {
9886                mSleeping = true;
9887                mStackSupervisor.goingToSleepLocked();
9888
9889                // Initialize the wake times of all processes.
9890                checkExcessivePowerUsageLocked(false);
9891                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9892                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9893                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9894            }
9895        }
9896    }
9897
9898    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9899        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9900            // Never persist the home stack.
9901            return;
9902        }
9903        mTaskPersister.wakeup(task, flush);
9904    }
9905
9906    @Override
9907    public boolean shutdown(int timeout) {
9908        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9909                != PackageManager.PERMISSION_GRANTED) {
9910            throw new SecurityException("Requires permission "
9911                    + android.Manifest.permission.SHUTDOWN);
9912        }
9913
9914        boolean timedout = false;
9915
9916        synchronized(this) {
9917            mShuttingDown = true;
9918            updateEventDispatchingLocked();
9919            timedout = mStackSupervisor.shutdownLocked(timeout);
9920        }
9921
9922        mAppOpsService.shutdown();
9923        if (mUsageStatsService != null) {
9924            mUsageStatsService.prepareShutdown();
9925        }
9926        mBatteryStatsService.shutdown();
9927        synchronized (this) {
9928            mProcessStats.shutdownLocked();
9929        }
9930        notifyTaskPersisterLocked(null, true);
9931
9932        return timedout;
9933    }
9934
9935    public final void activitySlept(IBinder token) {
9936        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9937
9938        final long origId = Binder.clearCallingIdentity();
9939
9940        synchronized (this) {
9941            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9942            if (r != null) {
9943                mStackSupervisor.activitySleptLocked(r);
9944            }
9945        }
9946
9947        Binder.restoreCallingIdentity(origId);
9948    }
9949
9950    void logLockScreen(String msg) {
9951        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9952                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9953                mWentToSleep + " mSleeping=" + mSleeping);
9954    }
9955
9956    private void comeOutOfSleepIfNeededLocked() {
9957        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9958            if (mSleeping) {
9959                mSleeping = false;
9960                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9961            }
9962        }
9963    }
9964
9965    void wakingUp() {
9966        synchronized(this) {
9967            mWentToSleep = false;
9968            comeOutOfSleepIfNeededLocked();
9969        }
9970    }
9971
9972    void startRunningVoiceLocked() {
9973        if (!mRunningVoice) {
9974            mRunningVoice = true;
9975            comeOutOfSleepIfNeededLocked();
9976        }
9977    }
9978
9979    private void updateEventDispatchingLocked() {
9980        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
9981    }
9982
9983    public void setLockScreenShown(boolean shown) {
9984        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9985                != PackageManager.PERMISSION_GRANTED) {
9986            throw new SecurityException("Requires permission "
9987                    + android.Manifest.permission.DEVICE_POWER);
9988        }
9989
9990        synchronized(this) {
9991            long ident = Binder.clearCallingIdentity();
9992            try {
9993                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9994                mLockScreenShown = shown;
9995                comeOutOfSleepIfNeededLocked();
9996            } finally {
9997                Binder.restoreCallingIdentity(ident);
9998            }
9999        }
10000    }
10001
10002    @Override
10003    public void stopAppSwitches() {
10004        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10005                != PackageManager.PERMISSION_GRANTED) {
10006            throw new SecurityException("Requires permission "
10007                    + android.Manifest.permission.STOP_APP_SWITCHES);
10008        }
10009
10010        synchronized(this) {
10011            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10012                    + APP_SWITCH_DELAY_TIME;
10013            mDidAppSwitch = false;
10014            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10015            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10016            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10017        }
10018    }
10019
10020    public void resumeAppSwitches() {
10021        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10022                != PackageManager.PERMISSION_GRANTED) {
10023            throw new SecurityException("Requires permission "
10024                    + android.Manifest.permission.STOP_APP_SWITCHES);
10025        }
10026
10027        synchronized(this) {
10028            // Note that we don't execute any pending app switches... we will
10029            // let those wait until either the timeout, or the next start
10030            // activity request.
10031            mAppSwitchesAllowedTime = 0;
10032        }
10033    }
10034
10035    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10036            int callingPid, int callingUid, String name) {
10037        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10038            return true;
10039        }
10040
10041        int perm = checkComponentPermission(
10042                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10043                sourceUid, -1, true);
10044        if (perm == PackageManager.PERMISSION_GRANTED) {
10045            return true;
10046        }
10047
10048        // If the actual IPC caller is different from the logical source, then
10049        // also see if they are allowed to control app switches.
10050        if (callingUid != -1 && callingUid != sourceUid) {
10051            perm = checkComponentPermission(
10052                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10053                    callingUid, -1, true);
10054            if (perm == PackageManager.PERMISSION_GRANTED) {
10055                return true;
10056            }
10057        }
10058
10059        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10060        return false;
10061    }
10062
10063    public void setDebugApp(String packageName, boolean waitForDebugger,
10064            boolean persistent) {
10065        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10066                "setDebugApp()");
10067
10068        long ident = Binder.clearCallingIdentity();
10069        try {
10070            // Note that this is not really thread safe if there are multiple
10071            // callers into it at the same time, but that's not a situation we
10072            // care about.
10073            if (persistent) {
10074                final ContentResolver resolver = mContext.getContentResolver();
10075                Settings.Global.putString(
10076                    resolver, Settings.Global.DEBUG_APP,
10077                    packageName);
10078                Settings.Global.putInt(
10079                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10080                    waitForDebugger ? 1 : 0);
10081            }
10082
10083            synchronized (this) {
10084                if (!persistent) {
10085                    mOrigDebugApp = mDebugApp;
10086                    mOrigWaitForDebugger = mWaitForDebugger;
10087                }
10088                mDebugApp = packageName;
10089                mWaitForDebugger = waitForDebugger;
10090                mDebugTransient = !persistent;
10091                if (packageName != null) {
10092                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10093                            false, UserHandle.USER_ALL, "set debug app");
10094                }
10095            }
10096        } finally {
10097            Binder.restoreCallingIdentity(ident);
10098        }
10099    }
10100
10101    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10102        synchronized (this) {
10103            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10104            if (!isDebuggable) {
10105                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10106                    throw new SecurityException("Process not debuggable: " + app.packageName);
10107                }
10108            }
10109
10110            mOpenGlTraceApp = processName;
10111        }
10112    }
10113
10114    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10115        synchronized (this) {
10116            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10117            if (!isDebuggable) {
10118                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10119                    throw new SecurityException("Process not debuggable: " + app.packageName);
10120                }
10121            }
10122            mProfileApp = processName;
10123            mProfileFile = profilerInfo.profileFile;
10124            if (mProfileFd != null) {
10125                try {
10126                    mProfileFd.close();
10127                } catch (IOException e) {
10128                }
10129                mProfileFd = null;
10130            }
10131            mProfileFd = profilerInfo.profileFd;
10132            mSamplingInterval = profilerInfo.samplingInterval;
10133            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10134            mProfileType = 0;
10135        }
10136    }
10137
10138    @Override
10139    public void setAlwaysFinish(boolean enabled) {
10140        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10141                "setAlwaysFinish()");
10142
10143        Settings.Global.putInt(
10144                mContext.getContentResolver(),
10145                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10146
10147        synchronized (this) {
10148            mAlwaysFinishActivities = enabled;
10149        }
10150    }
10151
10152    @Override
10153    public void setActivityController(IActivityController controller) {
10154        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10155                "setActivityController()");
10156        synchronized (this) {
10157            mController = controller;
10158            Watchdog.getInstance().setActivityController(controller);
10159        }
10160    }
10161
10162    @Override
10163    public void setUserIsMonkey(boolean userIsMonkey) {
10164        synchronized (this) {
10165            synchronized (mPidsSelfLocked) {
10166                final int callingPid = Binder.getCallingPid();
10167                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10168                if (precessRecord == null) {
10169                    throw new SecurityException("Unknown process: " + callingPid);
10170                }
10171                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10172                    throw new SecurityException("Only an instrumentation process "
10173                            + "with a UiAutomation can call setUserIsMonkey");
10174                }
10175            }
10176            mUserIsMonkey = userIsMonkey;
10177        }
10178    }
10179
10180    @Override
10181    public boolean isUserAMonkey() {
10182        synchronized (this) {
10183            // If there is a controller also implies the user is a monkey.
10184            return (mUserIsMonkey || mController != null);
10185        }
10186    }
10187
10188    public void requestBugReport() {
10189        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10190        SystemProperties.set("ctl.start", "bugreport");
10191    }
10192
10193    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10194        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10195    }
10196
10197    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10198        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10199            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10200        }
10201        return KEY_DISPATCHING_TIMEOUT;
10202    }
10203
10204    @Override
10205    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10206        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10207                != PackageManager.PERMISSION_GRANTED) {
10208            throw new SecurityException("Requires permission "
10209                    + android.Manifest.permission.FILTER_EVENTS);
10210        }
10211        ProcessRecord proc;
10212        long timeout;
10213        synchronized (this) {
10214            synchronized (mPidsSelfLocked) {
10215                proc = mPidsSelfLocked.get(pid);
10216            }
10217            timeout = getInputDispatchingTimeoutLocked(proc);
10218        }
10219
10220        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10221            return -1;
10222        }
10223
10224        return timeout;
10225    }
10226
10227    /**
10228     * Handle input dispatching timeouts.
10229     * Returns whether input dispatching should be aborted or not.
10230     */
10231    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10232            final ActivityRecord activity, final ActivityRecord parent,
10233            final boolean aboveSystem, String reason) {
10234        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10235                != PackageManager.PERMISSION_GRANTED) {
10236            throw new SecurityException("Requires permission "
10237                    + android.Manifest.permission.FILTER_EVENTS);
10238        }
10239
10240        final String annotation;
10241        if (reason == null) {
10242            annotation = "Input dispatching timed out";
10243        } else {
10244            annotation = "Input dispatching timed out (" + reason + ")";
10245        }
10246
10247        if (proc != null) {
10248            synchronized (this) {
10249                if (proc.debugging) {
10250                    return false;
10251                }
10252
10253                if (mDidDexOpt) {
10254                    // Give more time since we were dexopting.
10255                    mDidDexOpt = false;
10256                    return false;
10257                }
10258
10259                if (proc.instrumentationClass != null) {
10260                    Bundle info = new Bundle();
10261                    info.putString("shortMsg", "keyDispatchingTimedOut");
10262                    info.putString("longMsg", annotation);
10263                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10264                    return true;
10265                }
10266            }
10267            mHandler.post(new Runnable() {
10268                @Override
10269                public void run() {
10270                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10271                }
10272            });
10273        }
10274
10275        return true;
10276    }
10277
10278    public Bundle getAssistContextExtras(int requestType) {
10279        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10280                UserHandle.getCallingUserId());
10281        if (pae == null) {
10282            return null;
10283        }
10284        synchronized (pae) {
10285            while (!pae.haveResult) {
10286                try {
10287                    pae.wait();
10288                } catch (InterruptedException e) {
10289                }
10290            }
10291            if (pae.result != null) {
10292                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10293            }
10294        }
10295        synchronized (this) {
10296            mPendingAssistExtras.remove(pae);
10297            mHandler.removeCallbacks(pae);
10298        }
10299        return pae.extras;
10300    }
10301
10302    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10303            int userHandle) {
10304        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10305                "getAssistContextExtras()");
10306        PendingAssistExtras pae;
10307        Bundle extras = new Bundle();
10308        synchronized (this) {
10309            ActivityRecord activity = getFocusedStack().mResumedActivity;
10310            if (activity == null) {
10311                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10312                return null;
10313            }
10314            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10315            if (activity.app == null || activity.app.thread == null) {
10316                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10317                return null;
10318            }
10319            if (activity.app.pid == Binder.getCallingPid()) {
10320                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10321                return null;
10322            }
10323            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10324            try {
10325                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10326                        requestType);
10327                mPendingAssistExtras.add(pae);
10328                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10329            } catch (RemoteException e) {
10330                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10331                return null;
10332            }
10333            return pae;
10334        }
10335    }
10336
10337    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10338        PendingAssistExtras pae = (PendingAssistExtras)token;
10339        synchronized (pae) {
10340            pae.result = extras;
10341            pae.haveResult = true;
10342            pae.notifyAll();
10343            if (pae.intent == null) {
10344                // Caller is just waiting for the result.
10345                return;
10346            }
10347        }
10348
10349        // We are now ready to launch the assist activity.
10350        synchronized (this) {
10351            boolean exists = mPendingAssistExtras.remove(pae);
10352            mHandler.removeCallbacks(pae);
10353            if (!exists) {
10354                // Timed out.
10355                return;
10356            }
10357        }
10358        pae.intent.replaceExtras(extras);
10359        if (pae.hint != null) {
10360            pae.intent.putExtra(pae.hint, true);
10361        }
10362        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10363                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10364                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10365        closeSystemDialogs("assist");
10366        try {
10367            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10368        } catch (ActivityNotFoundException e) {
10369            Slog.w(TAG, "No activity to handle assist action.", e);
10370        }
10371    }
10372
10373    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10374        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10375    }
10376
10377    public void registerProcessObserver(IProcessObserver observer) {
10378        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10379                "registerProcessObserver()");
10380        synchronized (this) {
10381            mProcessObservers.register(observer);
10382        }
10383    }
10384
10385    @Override
10386    public void unregisterProcessObserver(IProcessObserver observer) {
10387        synchronized (this) {
10388            mProcessObservers.unregister(observer);
10389        }
10390    }
10391
10392    @Override
10393    public boolean convertFromTranslucent(IBinder token) {
10394        final long origId = Binder.clearCallingIdentity();
10395        try {
10396            synchronized (this) {
10397                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10398                if (r == null) {
10399                    return false;
10400                }
10401                final boolean translucentChanged = r.changeWindowTranslucency(true);
10402                if (translucentChanged) {
10403                    r.task.stack.releaseBackgroundResources();
10404                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10405                }
10406                mWindowManager.setAppFullscreen(token, true);
10407                return translucentChanged;
10408            }
10409        } finally {
10410            Binder.restoreCallingIdentity(origId);
10411        }
10412    }
10413
10414    @Override
10415    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10416        final long origId = Binder.clearCallingIdentity();
10417        try {
10418            synchronized (this) {
10419                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10420                if (r == null) {
10421                    return false;
10422                }
10423                int index = r.task.mActivities.lastIndexOf(r);
10424                if (index > 0) {
10425                    ActivityRecord under = r.task.mActivities.get(index - 1);
10426                    under.returningOptions = options;
10427                }
10428                final boolean translucentChanged = r.changeWindowTranslucency(false);
10429                if (translucentChanged) {
10430                    r.task.stack.convertToTranslucent(r);
10431                }
10432                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10433                mWindowManager.setAppFullscreen(token, false);
10434                return translucentChanged;
10435            }
10436        } finally {
10437            Binder.restoreCallingIdentity(origId);
10438        }
10439    }
10440
10441    @Override
10442    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10443        final long origId = Binder.clearCallingIdentity();
10444        try {
10445            synchronized (this) {
10446                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10447                if (r != null) {
10448                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10449                }
10450            }
10451            return false;
10452        } finally {
10453            Binder.restoreCallingIdentity(origId);
10454        }
10455    }
10456
10457    @Override
10458    public boolean isBackgroundVisibleBehind(IBinder token) {
10459        final long origId = Binder.clearCallingIdentity();
10460        try {
10461            synchronized (this) {
10462                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10463                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10464                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10465                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10466                return visible;
10467            }
10468        } finally {
10469            Binder.restoreCallingIdentity(origId);
10470        }
10471    }
10472
10473    @Override
10474    public ActivityOptions getActivityOptions(IBinder token) {
10475        final long origId = Binder.clearCallingIdentity();
10476        try {
10477            synchronized (this) {
10478                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10479                if (r != null) {
10480                    final ActivityOptions activityOptions = r.pendingOptions;
10481                    r.pendingOptions = null;
10482                    return activityOptions;
10483                }
10484                return null;
10485            }
10486        } finally {
10487            Binder.restoreCallingIdentity(origId);
10488        }
10489    }
10490
10491    @Override
10492    public void setImmersive(IBinder token, boolean immersive) {
10493        synchronized(this) {
10494            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10495            if (r == null) {
10496                throw new IllegalArgumentException();
10497            }
10498            r.immersive = immersive;
10499
10500            // update associated state if we're frontmost
10501            if (r == mFocusedActivity) {
10502                if (DEBUG_IMMERSIVE) {
10503                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10504                }
10505                applyUpdateLockStateLocked(r);
10506            }
10507        }
10508    }
10509
10510    @Override
10511    public boolean isImmersive(IBinder token) {
10512        synchronized (this) {
10513            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10514            if (r == null) {
10515                throw new IllegalArgumentException();
10516            }
10517            return r.immersive;
10518        }
10519    }
10520
10521    public boolean isTopActivityImmersive() {
10522        enforceNotIsolatedCaller("startActivity");
10523        synchronized (this) {
10524            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10525            return (r != null) ? r.immersive : false;
10526        }
10527    }
10528
10529    @Override
10530    public boolean isTopOfTask(IBinder token) {
10531        synchronized (this) {
10532            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10533            if (r == null) {
10534                throw new IllegalArgumentException();
10535            }
10536            return r.task.getTopActivity() == r;
10537        }
10538    }
10539
10540    public final void enterSafeMode() {
10541        synchronized(this) {
10542            // It only makes sense to do this before the system is ready
10543            // and started launching other packages.
10544            if (!mSystemReady) {
10545                try {
10546                    AppGlobals.getPackageManager().enterSafeMode();
10547                } catch (RemoteException e) {
10548                }
10549            }
10550
10551            mSafeMode = true;
10552        }
10553    }
10554
10555    public final void showSafeModeOverlay() {
10556        View v = LayoutInflater.from(mContext).inflate(
10557                com.android.internal.R.layout.safe_mode, null);
10558        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10559        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10560        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10561        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10562        lp.gravity = Gravity.BOTTOM | Gravity.START;
10563        lp.format = v.getBackground().getOpacity();
10564        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10565                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10566        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10567        ((WindowManager)mContext.getSystemService(
10568                Context.WINDOW_SERVICE)).addView(v, lp);
10569    }
10570
10571    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10572        if (!(sender instanceof PendingIntentRecord)) {
10573            return;
10574        }
10575        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10576        synchronized (stats) {
10577            if (mBatteryStatsService.isOnBattery()) {
10578                mBatteryStatsService.enforceCallingPermission();
10579                PendingIntentRecord rec = (PendingIntentRecord)sender;
10580                int MY_UID = Binder.getCallingUid();
10581                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10582                BatteryStatsImpl.Uid.Pkg pkg =
10583                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10584                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10585                pkg.incWakeupsLocked();
10586            }
10587        }
10588    }
10589
10590    public boolean killPids(int[] pids, String pReason, boolean secure) {
10591        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10592            throw new SecurityException("killPids only available to the system");
10593        }
10594        String reason = (pReason == null) ? "Unknown" : pReason;
10595        // XXX Note: don't acquire main activity lock here, because the window
10596        // manager calls in with its locks held.
10597
10598        boolean killed = false;
10599        synchronized (mPidsSelfLocked) {
10600            int[] types = new int[pids.length];
10601            int worstType = 0;
10602            for (int i=0; i<pids.length; i++) {
10603                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10604                if (proc != null) {
10605                    int type = proc.setAdj;
10606                    types[i] = type;
10607                    if (type > worstType) {
10608                        worstType = type;
10609                    }
10610                }
10611            }
10612
10613            // If the worst oom_adj is somewhere in the cached proc LRU range,
10614            // then constrain it so we will kill all cached procs.
10615            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10616                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10617                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10618            }
10619
10620            // If this is not a secure call, don't let it kill processes that
10621            // are important.
10622            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10623                worstType = ProcessList.SERVICE_ADJ;
10624            }
10625
10626            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10627            for (int i=0; i<pids.length; i++) {
10628                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10629                if (proc == null) {
10630                    continue;
10631                }
10632                int adj = proc.setAdj;
10633                if (adj >= worstType && !proc.killedByAm) {
10634                    proc.kill(reason, true);
10635                    killed = true;
10636                }
10637            }
10638        }
10639        return killed;
10640    }
10641
10642    @Override
10643    public void killUid(int uid, String reason) {
10644        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10645            throw new SecurityException("killUid only available to the system");
10646        }
10647        synchronized (this) {
10648            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10649                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10650                    reason != null ? reason : "kill uid");
10651        }
10652    }
10653
10654    @Override
10655    public boolean killProcessesBelowForeground(String reason) {
10656        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10657            throw new SecurityException("killProcessesBelowForeground() only available to system");
10658        }
10659
10660        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10661    }
10662
10663    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10664        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10665            throw new SecurityException("killProcessesBelowAdj() only available to system");
10666        }
10667
10668        boolean killed = false;
10669        synchronized (mPidsSelfLocked) {
10670            final int size = mPidsSelfLocked.size();
10671            for (int i = 0; i < size; i++) {
10672                final int pid = mPidsSelfLocked.keyAt(i);
10673                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10674                if (proc == null) continue;
10675
10676                final int adj = proc.setAdj;
10677                if (adj > belowAdj && !proc.killedByAm) {
10678                    proc.kill(reason, true);
10679                    killed = true;
10680                }
10681            }
10682        }
10683        return killed;
10684    }
10685
10686    @Override
10687    public void hang(final IBinder who, boolean allowRestart) {
10688        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10689                != PackageManager.PERMISSION_GRANTED) {
10690            throw new SecurityException("Requires permission "
10691                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10692        }
10693
10694        final IBinder.DeathRecipient death = new DeathRecipient() {
10695            @Override
10696            public void binderDied() {
10697                synchronized (this) {
10698                    notifyAll();
10699                }
10700            }
10701        };
10702
10703        try {
10704            who.linkToDeath(death, 0);
10705        } catch (RemoteException e) {
10706            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10707            return;
10708        }
10709
10710        synchronized (this) {
10711            Watchdog.getInstance().setAllowRestart(allowRestart);
10712            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10713            synchronized (death) {
10714                while (who.isBinderAlive()) {
10715                    try {
10716                        death.wait();
10717                    } catch (InterruptedException e) {
10718                    }
10719                }
10720            }
10721            Watchdog.getInstance().setAllowRestart(true);
10722        }
10723    }
10724
10725    @Override
10726    public void restart() {
10727        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10728                != PackageManager.PERMISSION_GRANTED) {
10729            throw new SecurityException("Requires permission "
10730                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10731        }
10732
10733        Log.i(TAG, "Sending shutdown broadcast...");
10734
10735        BroadcastReceiver br = new BroadcastReceiver() {
10736            @Override public void onReceive(Context context, Intent intent) {
10737                // Now the broadcast is done, finish up the low-level shutdown.
10738                Log.i(TAG, "Shutting down activity manager...");
10739                shutdown(10000);
10740                Log.i(TAG, "Shutdown complete, restarting!");
10741                Process.killProcess(Process.myPid());
10742                System.exit(10);
10743            }
10744        };
10745
10746        // First send the high-level shut down broadcast.
10747        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10748        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10749        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10750        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10751        mContext.sendOrderedBroadcastAsUser(intent,
10752                UserHandle.ALL, null, br, mHandler, 0, null, null);
10753        */
10754        br.onReceive(mContext, intent);
10755    }
10756
10757    private long getLowRamTimeSinceIdle(long now) {
10758        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10759    }
10760
10761    @Override
10762    public void performIdleMaintenance() {
10763        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10764                != PackageManager.PERMISSION_GRANTED) {
10765            throw new SecurityException("Requires permission "
10766                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10767        }
10768
10769        synchronized (this) {
10770            final long now = SystemClock.uptimeMillis();
10771            final long timeSinceLastIdle = now - mLastIdleTime;
10772            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10773            mLastIdleTime = now;
10774            mLowRamTimeSinceLastIdle = 0;
10775            if (mLowRamStartTime != 0) {
10776                mLowRamStartTime = now;
10777            }
10778
10779            StringBuilder sb = new StringBuilder(128);
10780            sb.append("Idle maintenance over ");
10781            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10782            sb.append(" low RAM for ");
10783            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10784            Slog.i(TAG, sb.toString());
10785
10786            // If at least 1/3 of our time since the last idle period has been spent
10787            // with RAM low, then we want to kill processes.
10788            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10789
10790            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10791                ProcessRecord proc = mLruProcesses.get(i);
10792                if (proc.notCachedSinceIdle) {
10793                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10794                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10795                        if (doKilling && proc.initialIdlePss != 0
10796                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10797                            proc.kill("idle maint (pss " + proc.lastPss
10798                                    + " from " + proc.initialIdlePss + ")", true);
10799                        }
10800                    }
10801                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10802                    proc.notCachedSinceIdle = true;
10803                    proc.initialIdlePss = 0;
10804                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10805                            isSleeping(), now);
10806                }
10807            }
10808
10809            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10810            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10811        }
10812    }
10813
10814    private void retrieveSettings() {
10815        final ContentResolver resolver = mContext.getContentResolver();
10816        String debugApp = Settings.Global.getString(
10817            resolver, Settings.Global.DEBUG_APP);
10818        boolean waitForDebugger = Settings.Global.getInt(
10819            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10820        boolean alwaysFinishActivities = Settings.Global.getInt(
10821            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10822        boolean forceRtl = Settings.Global.getInt(
10823                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10824        // Transfer any global setting for forcing RTL layout, into a System Property
10825        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10826
10827        Configuration configuration = new Configuration();
10828        Settings.System.getConfiguration(resolver, configuration);
10829        if (forceRtl) {
10830            // This will take care of setting the correct layout direction flags
10831            configuration.setLayoutDirection(configuration.locale);
10832        }
10833
10834        synchronized (this) {
10835            mDebugApp = mOrigDebugApp = debugApp;
10836            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10837            mAlwaysFinishActivities = alwaysFinishActivities;
10838            // This happens before any activities are started, so we can
10839            // change mConfiguration in-place.
10840            updateConfigurationLocked(configuration, null, false, true);
10841            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10842        }
10843    }
10844
10845    /** Loads resources after the current configuration has been set. */
10846    private void loadResourcesOnSystemReady() {
10847        final Resources res = mContext.getResources();
10848        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10849        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10850        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10851    }
10852
10853    public boolean testIsSystemReady() {
10854        // no need to synchronize(this) just to read & return the value
10855        return mSystemReady;
10856    }
10857
10858    private static File getCalledPreBootReceiversFile() {
10859        File dataDir = Environment.getDataDirectory();
10860        File systemDir = new File(dataDir, "system");
10861        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10862        return fname;
10863    }
10864
10865    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10866        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10867        File file = getCalledPreBootReceiversFile();
10868        FileInputStream fis = null;
10869        try {
10870            fis = new FileInputStream(file);
10871            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10872            int fvers = dis.readInt();
10873            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10874                String vers = dis.readUTF();
10875                String codename = dis.readUTF();
10876                String build = dis.readUTF();
10877                if (android.os.Build.VERSION.RELEASE.equals(vers)
10878                        && android.os.Build.VERSION.CODENAME.equals(codename)
10879                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10880                    int num = dis.readInt();
10881                    while (num > 0) {
10882                        num--;
10883                        String pkg = dis.readUTF();
10884                        String cls = dis.readUTF();
10885                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10886                    }
10887                }
10888            }
10889        } catch (FileNotFoundException e) {
10890        } catch (IOException e) {
10891            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10892        } finally {
10893            if (fis != null) {
10894                try {
10895                    fis.close();
10896                } catch (IOException e) {
10897                }
10898            }
10899        }
10900        return lastDoneReceivers;
10901    }
10902
10903    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10904        File file = getCalledPreBootReceiversFile();
10905        FileOutputStream fos = null;
10906        DataOutputStream dos = null;
10907        try {
10908            fos = new FileOutputStream(file);
10909            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10910            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10911            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10912            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10913            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10914            dos.writeInt(list.size());
10915            for (int i=0; i<list.size(); i++) {
10916                dos.writeUTF(list.get(i).getPackageName());
10917                dos.writeUTF(list.get(i).getClassName());
10918            }
10919        } catch (IOException e) {
10920            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10921            file.delete();
10922        } finally {
10923            FileUtils.sync(fos);
10924            if (dos != null) {
10925                try {
10926                    dos.close();
10927                } catch (IOException e) {
10928                    // TODO Auto-generated catch block
10929                    e.printStackTrace();
10930                }
10931            }
10932        }
10933    }
10934
10935    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10936            ArrayList<ComponentName> doneReceivers, int userId) {
10937        boolean waitingUpdate = false;
10938        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10939        List<ResolveInfo> ris = null;
10940        try {
10941            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10942                    intent, null, 0, userId);
10943        } catch (RemoteException e) {
10944        }
10945        if (ris != null) {
10946            for (int i=ris.size()-1; i>=0; i--) {
10947                if ((ris.get(i).activityInfo.applicationInfo.flags
10948                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10949                    ris.remove(i);
10950                }
10951            }
10952            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10953
10954            // For User 0, load the version number. When delivering to a new user, deliver
10955            // to all receivers.
10956            if (userId == UserHandle.USER_OWNER) {
10957                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10958                for (int i=0; i<ris.size(); i++) {
10959                    ActivityInfo ai = ris.get(i).activityInfo;
10960                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10961                    if (lastDoneReceivers.contains(comp)) {
10962                        // We already did the pre boot receiver for this app with the current
10963                        // platform version, so don't do it again...
10964                        ris.remove(i);
10965                        i--;
10966                        // ...however, do keep it as one that has been done, so we don't
10967                        // forget about it when rewriting the file of last done receivers.
10968                        doneReceivers.add(comp);
10969                    }
10970                }
10971            }
10972
10973            // If primary user, send broadcast to all available users, else just to userId
10974            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10975                    : new int[] { userId };
10976            for (int i = 0; i < ris.size(); i++) {
10977                ActivityInfo ai = ris.get(i).activityInfo;
10978                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10979                doneReceivers.add(comp);
10980                intent.setComponent(comp);
10981                for (int j=0; j<users.length; j++) {
10982                    IIntentReceiver finisher = null;
10983                    // On last receiver and user, set up a completion callback
10984                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10985                        finisher = new IIntentReceiver.Stub() {
10986                            public void performReceive(Intent intent, int resultCode,
10987                                    String data, Bundle extras, boolean ordered,
10988                                    boolean sticky, int sendingUser) {
10989                                // The raw IIntentReceiver interface is called
10990                                // with the AM lock held, so redispatch to
10991                                // execute our code without the lock.
10992                                mHandler.post(onFinishCallback);
10993                            }
10994                        };
10995                    }
10996                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10997                            + " for user " + users[j]);
10998                    broadcastIntentLocked(null, null, intent, null, finisher,
10999                            0, null, null, null, AppOpsManager.OP_NONE,
11000                            true, false, MY_PID, Process.SYSTEM_UID,
11001                            users[j]);
11002                    if (finisher != null) {
11003                        waitingUpdate = true;
11004                    }
11005                }
11006            }
11007        }
11008
11009        return waitingUpdate;
11010    }
11011
11012    public void systemReady(final Runnable goingCallback) {
11013        synchronized(this) {
11014            if (mSystemReady) {
11015                // If we're done calling all the receivers, run the next "boot phase" passed in
11016                // by the SystemServer
11017                if (goingCallback != null) {
11018                    goingCallback.run();
11019                }
11020                return;
11021            }
11022
11023            // Make sure we have the current profile info, since it is needed for
11024            // security checks.
11025            updateCurrentProfileIdsLocked();
11026
11027            if (mRecentTasks == null) {
11028                mRecentTasks = mTaskPersister.restoreTasksLocked();
11029                if (!mRecentTasks.isEmpty()) {
11030                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11031                }
11032                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11033                mTaskPersister.startPersisting();
11034            }
11035
11036            // Check to see if there are any update receivers to run.
11037            if (!mDidUpdate) {
11038                if (mWaitingUpdate) {
11039                    return;
11040                }
11041                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11042                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11043                    public void run() {
11044                        synchronized (ActivityManagerService.this) {
11045                            mDidUpdate = true;
11046                        }
11047                        writeLastDonePreBootReceivers(doneReceivers);
11048                        showBootMessage(mContext.getText(
11049                                R.string.android_upgrading_complete),
11050                                false);
11051                        systemReady(goingCallback);
11052                    }
11053                }, doneReceivers, UserHandle.USER_OWNER);
11054
11055                if (mWaitingUpdate) {
11056                    return;
11057                }
11058                mDidUpdate = true;
11059            }
11060
11061            mAppOpsService.systemReady();
11062            mSystemReady = true;
11063        }
11064
11065        ArrayList<ProcessRecord> procsToKill = null;
11066        synchronized(mPidsSelfLocked) {
11067            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11068                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11069                if (!isAllowedWhileBooting(proc.info)){
11070                    if (procsToKill == null) {
11071                        procsToKill = new ArrayList<ProcessRecord>();
11072                    }
11073                    procsToKill.add(proc);
11074                }
11075            }
11076        }
11077
11078        synchronized(this) {
11079            if (procsToKill != null) {
11080                for (int i=procsToKill.size()-1; i>=0; i--) {
11081                    ProcessRecord proc = procsToKill.get(i);
11082                    Slog.i(TAG, "Removing system update proc: " + proc);
11083                    removeProcessLocked(proc, true, false, "system update done");
11084                }
11085            }
11086
11087            // Now that we have cleaned up any update processes, we
11088            // are ready to start launching real processes and know that
11089            // we won't trample on them any more.
11090            mProcessesReady = true;
11091        }
11092
11093        Slog.i(TAG, "System now ready");
11094        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11095            SystemClock.uptimeMillis());
11096
11097        synchronized(this) {
11098            // Make sure we have no pre-ready processes sitting around.
11099
11100            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11101                ResolveInfo ri = mContext.getPackageManager()
11102                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11103                                STOCK_PM_FLAGS);
11104                CharSequence errorMsg = null;
11105                if (ri != null) {
11106                    ActivityInfo ai = ri.activityInfo;
11107                    ApplicationInfo app = ai.applicationInfo;
11108                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11109                        mTopAction = Intent.ACTION_FACTORY_TEST;
11110                        mTopData = null;
11111                        mTopComponent = new ComponentName(app.packageName,
11112                                ai.name);
11113                    } else {
11114                        errorMsg = mContext.getResources().getText(
11115                                com.android.internal.R.string.factorytest_not_system);
11116                    }
11117                } else {
11118                    errorMsg = mContext.getResources().getText(
11119                            com.android.internal.R.string.factorytest_no_action);
11120                }
11121                if (errorMsg != null) {
11122                    mTopAction = null;
11123                    mTopData = null;
11124                    mTopComponent = null;
11125                    Message msg = Message.obtain();
11126                    msg.what = SHOW_FACTORY_ERROR_MSG;
11127                    msg.getData().putCharSequence("msg", errorMsg);
11128                    mHandler.sendMessage(msg);
11129                }
11130            }
11131        }
11132
11133        retrieveSettings();
11134        loadResourcesOnSystemReady();
11135
11136        synchronized (this) {
11137            readGrantedUriPermissionsLocked();
11138        }
11139
11140        if (goingCallback != null) goingCallback.run();
11141
11142        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11143                Integer.toString(mCurrentUserId), mCurrentUserId);
11144        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11145                Integer.toString(mCurrentUserId), mCurrentUserId);
11146        mSystemServiceManager.startUser(mCurrentUserId);
11147
11148        synchronized (this) {
11149            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11150                try {
11151                    List apps = AppGlobals.getPackageManager().
11152                        getPersistentApplications(STOCK_PM_FLAGS);
11153                    if (apps != null) {
11154                        int N = apps.size();
11155                        int i;
11156                        for (i=0; i<N; i++) {
11157                            ApplicationInfo info
11158                                = (ApplicationInfo)apps.get(i);
11159                            if (info != null &&
11160                                    !info.packageName.equals("android")) {
11161                                addAppLocked(info, false, null /* ABI override */);
11162                            }
11163                        }
11164                    }
11165                } catch (RemoteException ex) {
11166                    // pm is in same process, this will never happen.
11167                }
11168            }
11169
11170            // Start up initial activity.
11171            mBooting = true;
11172            startHomeActivityLocked(mCurrentUserId);
11173
11174            try {
11175                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11176                    Message msg = Message.obtain();
11177                    msg.what = SHOW_UID_ERROR_MSG;
11178                    mHandler.sendMessage(msg);
11179                }
11180            } catch (RemoteException e) {
11181            }
11182
11183            long ident = Binder.clearCallingIdentity();
11184            try {
11185                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11186                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11187                        | Intent.FLAG_RECEIVER_FOREGROUND);
11188                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11189                broadcastIntentLocked(null, null, intent,
11190                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11191                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11192                intent = new Intent(Intent.ACTION_USER_STARTING);
11193                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11194                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11195                broadcastIntentLocked(null, null, intent,
11196                        null, new IIntentReceiver.Stub() {
11197                            @Override
11198                            public void performReceive(Intent intent, int resultCode, String data,
11199                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11200                                    throws RemoteException {
11201                            }
11202                        }, 0, null, null,
11203                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11204                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11205            } catch (Throwable t) {
11206                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11207            } finally {
11208                Binder.restoreCallingIdentity(ident);
11209            }
11210            mStackSupervisor.resumeTopActivitiesLocked();
11211            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11212        }
11213    }
11214
11215    private boolean makeAppCrashingLocked(ProcessRecord app,
11216            String shortMsg, String longMsg, String stackTrace) {
11217        app.crashing = true;
11218        app.crashingReport = generateProcessError(app,
11219                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11220        startAppProblemLocked(app);
11221        app.stopFreezingAllLocked();
11222        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11223    }
11224
11225    private void makeAppNotRespondingLocked(ProcessRecord app,
11226            String activity, String shortMsg, String longMsg) {
11227        app.notResponding = true;
11228        app.notRespondingReport = generateProcessError(app,
11229                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11230                activity, shortMsg, longMsg, null);
11231        startAppProblemLocked(app);
11232        app.stopFreezingAllLocked();
11233    }
11234
11235    /**
11236     * Generate a process error record, suitable for attachment to a ProcessRecord.
11237     *
11238     * @param app The ProcessRecord in which the error occurred.
11239     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11240     *                      ActivityManager.AppErrorStateInfo
11241     * @param activity The activity associated with the crash, if known.
11242     * @param shortMsg Short message describing the crash.
11243     * @param longMsg Long message describing the crash.
11244     * @param stackTrace Full crash stack trace, may be null.
11245     *
11246     * @return Returns a fully-formed AppErrorStateInfo record.
11247     */
11248    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11249            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11250        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11251
11252        report.condition = condition;
11253        report.processName = app.processName;
11254        report.pid = app.pid;
11255        report.uid = app.info.uid;
11256        report.tag = activity;
11257        report.shortMsg = shortMsg;
11258        report.longMsg = longMsg;
11259        report.stackTrace = stackTrace;
11260
11261        return report;
11262    }
11263
11264    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11265        synchronized (this) {
11266            app.crashing = false;
11267            app.crashingReport = null;
11268            app.notResponding = false;
11269            app.notRespondingReport = null;
11270            if (app.anrDialog == fromDialog) {
11271                app.anrDialog = null;
11272            }
11273            if (app.waitDialog == fromDialog) {
11274                app.waitDialog = null;
11275            }
11276            if (app.pid > 0 && app.pid != MY_PID) {
11277                handleAppCrashLocked(app, null, null, null);
11278                app.kill("user request after error", true);
11279            }
11280        }
11281    }
11282
11283    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11284            String stackTrace) {
11285        long now = SystemClock.uptimeMillis();
11286
11287        Long crashTime;
11288        if (!app.isolated) {
11289            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11290        } else {
11291            crashTime = null;
11292        }
11293        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11294            // This process loses!
11295            Slog.w(TAG, "Process " + app.info.processName
11296                    + " has crashed too many times: killing!");
11297            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11298                    app.userId, app.info.processName, app.uid);
11299            mStackSupervisor.handleAppCrashLocked(app);
11300            if (!app.persistent) {
11301                // We don't want to start this process again until the user
11302                // explicitly does so...  but for persistent process, we really
11303                // need to keep it running.  If a persistent process is actually
11304                // repeatedly crashing, then badness for everyone.
11305                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11306                        app.info.processName);
11307                if (!app.isolated) {
11308                    // XXX We don't have a way to mark isolated processes
11309                    // as bad, since they don't have a peristent identity.
11310                    mBadProcesses.put(app.info.processName, app.uid,
11311                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11312                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11313                }
11314                app.bad = true;
11315                app.removed = true;
11316                // Don't let services in this process be restarted and potentially
11317                // annoy the user repeatedly.  Unless it is persistent, since those
11318                // processes run critical code.
11319                removeProcessLocked(app, false, false, "crash");
11320                mStackSupervisor.resumeTopActivitiesLocked();
11321                return false;
11322            }
11323            mStackSupervisor.resumeTopActivitiesLocked();
11324        } else {
11325            mStackSupervisor.finishTopRunningActivityLocked(app);
11326        }
11327
11328        // Bump up the crash count of any services currently running in the proc.
11329        for (int i=app.services.size()-1; i>=0; i--) {
11330            // Any services running in the application need to be placed
11331            // back in the pending list.
11332            ServiceRecord sr = app.services.valueAt(i);
11333            sr.crashCount++;
11334        }
11335
11336        // If the crashing process is what we consider to be the "home process" and it has been
11337        // replaced by a third-party app, clear the package preferred activities from packages
11338        // with a home activity running in the process to prevent a repeatedly crashing app
11339        // from blocking the user to manually clear the list.
11340        final ArrayList<ActivityRecord> activities = app.activities;
11341        if (app == mHomeProcess && activities.size() > 0
11342                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11343            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11344                final ActivityRecord r = activities.get(activityNdx);
11345                if (r.isHomeActivity()) {
11346                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11347                    try {
11348                        ActivityThread.getPackageManager()
11349                                .clearPackagePreferredActivities(r.packageName);
11350                    } catch (RemoteException c) {
11351                        // pm is in same process, this will never happen.
11352                    }
11353                }
11354            }
11355        }
11356
11357        if (!app.isolated) {
11358            // XXX Can't keep track of crash times for isolated processes,
11359            // because they don't have a perisistent identity.
11360            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11361        }
11362
11363        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11364        return true;
11365    }
11366
11367    void startAppProblemLocked(ProcessRecord app) {
11368        // If this app is not running under the current user, then we
11369        // can't give it a report button because that would require
11370        // launching the report UI under a different user.
11371        app.errorReportReceiver = null;
11372
11373        for (int userId : mCurrentProfileIds) {
11374            if (app.userId == userId) {
11375                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11376                        mContext, app.info.packageName, app.info.flags);
11377            }
11378        }
11379        skipCurrentReceiverLocked(app);
11380    }
11381
11382    void skipCurrentReceiverLocked(ProcessRecord app) {
11383        for (BroadcastQueue queue : mBroadcastQueues) {
11384            queue.skipCurrentReceiverLocked(app);
11385        }
11386    }
11387
11388    /**
11389     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11390     * The application process will exit immediately after this call returns.
11391     * @param app object of the crashing app, null for the system server
11392     * @param crashInfo describing the exception
11393     */
11394    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11395        ProcessRecord r = findAppProcess(app, "Crash");
11396        final String processName = app == null ? "system_server"
11397                : (r == null ? "unknown" : r.processName);
11398
11399        handleApplicationCrashInner("crash", r, processName, crashInfo);
11400    }
11401
11402    /* Native crash reporting uses this inner version because it needs to be somewhat
11403     * decoupled from the AM-managed cleanup lifecycle
11404     */
11405    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11406            ApplicationErrorReport.CrashInfo crashInfo) {
11407        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11408                UserHandle.getUserId(Binder.getCallingUid()), processName,
11409                r == null ? -1 : r.info.flags,
11410                crashInfo.exceptionClassName,
11411                crashInfo.exceptionMessage,
11412                crashInfo.throwFileName,
11413                crashInfo.throwLineNumber);
11414
11415        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11416
11417        crashApplication(r, crashInfo);
11418    }
11419
11420    public void handleApplicationStrictModeViolation(
11421            IBinder app,
11422            int violationMask,
11423            StrictMode.ViolationInfo info) {
11424        ProcessRecord r = findAppProcess(app, "StrictMode");
11425        if (r == null) {
11426            return;
11427        }
11428
11429        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11430            Integer stackFingerprint = info.hashCode();
11431            boolean logIt = true;
11432            synchronized (mAlreadyLoggedViolatedStacks) {
11433                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11434                    logIt = false;
11435                    // TODO: sub-sample into EventLog for these, with
11436                    // the info.durationMillis?  Then we'd get
11437                    // the relative pain numbers, without logging all
11438                    // the stack traces repeatedly.  We'd want to do
11439                    // likewise in the client code, which also does
11440                    // dup suppression, before the Binder call.
11441                } else {
11442                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11443                        mAlreadyLoggedViolatedStacks.clear();
11444                    }
11445                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11446                }
11447            }
11448            if (logIt) {
11449                logStrictModeViolationToDropBox(r, info);
11450            }
11451        }
11452
11453        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11454            AppErrorResult result = new AppErrorResult();
11455            synchronized (this) {
11456                final long origId = Binder.clearCallingIdentity();
11457
11458                Message msg = Message.obtain();
11459                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11460                HashMap<String, Object> data = new HashMap<String, Object>();
11461                data.put("result", result);
11462                data.put("app", r);
11463                data.put("violationMask", violationMask);
11464                data.put("info", info);
11465                msg.obj = data;
11466                mHandler.sendMessage(msg);
11467
11468                Binder.restoreCallingIdentity(origId);
11469            }
11470            int res = result.get();
11471            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11472        }
11473    }
11474
11475    // Depending on the policy in effect, there could be a bunch of
11476    // these in quick succession so we try to batch these together to
11477    // minimize disk writes, number of dropbox entries, and maximize
11478    // compression, by having more fewer, larger records.
11479    private void logStrictModeViolationToDropBox(
11480            ProcessRecord process,
11481            StrictMode.ViolationInfo info) {
11482        if (info == null) {
11483            return;
11484        }
11485        final boolean isSystemApp = process == null ||
11486                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11487                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11488        final String processName = process == null ? "unknown" : process.processName;
11489        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11490        final DropBoxManager dbox = (DropBoxManager)
11491                mContext.getSystemService(Context.DROPBOX_SERVICE);
11492
11493        // Exit early if the dropbox isn't configured to accept this report type.
11494        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11495
11496        boolean bufferWasEmpty;
11497        boolean needsFlush;
11498        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11499        synchronized (sb) {
11500            bufferWasEmpty = sb.length() == 0;
11501            appendDropBoxProcessHeaders(process, processName, sb);
11502            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11503            sb.append("System-App: ").append(isSystemApp).append("\n");
11504            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11505            if (info.violationNumThisLoop != 0) {
11506                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11507            }
11508            if (info.numAnimationsRunning != 0) {
11509                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11510            }
11511            if (info.broadcastIntentAction != null) {
11512                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11513            }
11514            if (info.durationMillis != -1) {
11515                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11516            }
11517            if (info.numInstances != -1) {
11518                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11519            }
11520            if (info.tags != null) {
11521                for (String tag : info.tags) {
11522                    sb.append("Span-Tag: ").append(tag).append("\n");
11523                }
11524            }
11525            sb.append("\n");
11526            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11527                sb.append(info.crashInfo.stackTrace);
11528            }
11529            sb.append("\n");
11530
11531            // Only buffer up to ~64k.  Various logging bits truncate
11532            // things at 128k.
11533            needsFlush = (sb.length() > 64 * 1024);
11534        }
11535
11536        // Flush immediately if the buffer's grown too large, or this
11537        // is a non-system app.  Non-system apps are isolated with a
11538        // different tag & policy and not batched.
11539        //
11540        // Batching is useful during internal testing with
11541        // StrictMode settings turned up high.  Without batching,
11542        // thousands of separate files could be created on boot.
11543        if (!isSystemApp || needsFlush) {
11544            new Thread("Error dump: " + dropboxTag) {
11545                @Override
11546                public void run() {
11547                    String report;
11548                    synchronized (sb) {
11549                        report = sb.toString();
11550                        sb.delete(0, sb.length());
11551                        sb.trimToSize();
11552                    }
11553                    if (report.length() != 0) {
11554                        dbox.addText(dropboxTag, report);
11555                    }
11556                }
11557            }.start();
11558            return;
11559        }
11560
11561        // System app batching:
11562        if (!bufferWasEmpty) {
11563            // An existing dropbox-writing thread is outstanding, so
11564            // we don't need to start it up.  The existing thread will
11565            // catch the buffer appends we just did.
11566            return;
11567        }
11568
11569        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11570        // (After this point, we shouldn't access AMS internal data structures.)
11571        new Thread("Error dump: " + dropboxTag) {
11572            @Override
11573            public void run() {
11574                // 5 second sleep to let stacks arrive and be batched together
11575                try {
11576                    Thread.sleep(5000);  // 5 seconds
11577                } catch (InterruptedException e) {}
11578
11579                String errorReport;
11580                synchronized (mStrictModeBuffer) {
11581                    errorReport = mStrictModeBuffer.toString();
11582                    if (errorReport.length() == 0) {
11583                        return;
11584                    }
11585                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11586                    mStrictModeBuffer.trimToSize();
11587                }
11588                dbox.addText(dropboxTag, errorReport);
11589            }
11590        }.start();
11591    }
11592
11593    /**
11594     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11595     * @param app object of the crashing app, null for the system server
11596     * @param tag reported by the caller
11597     * @param system whether this wtf is coming from the system
11598     * @param crashInfo describing the context of the error
11599     * @return true if the process should exit immediately (WTF is fatal)
11600     */
11601    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11602            final ApplicationErrorReport.CrashInfo crashInfo) {
11603        final int callingUid = Binder.getCallingUid();
11604        final int callingPid = Binder.getCallingPid();
11605
11606        if (system) {
11607            // If this is coming from the system, we could very well have low-level
11608            // system locks held, so we want to do this all asynchronously.  And we
11609            // never want this to become fatal, so there is that too.
11610            mHandler.post(new Runnable() {
11611                @Override public void run() {
11612                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11613                }
11614            });
11615            return false;
11616        }
11617
11618        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11619                crashInfo);
11620
11621        if (r != null && r.pid != Process.myPid() &&
11622                Settings.Global.getInt(mContext.getContentResolver(),
11623                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11624            crashApplication(r, crashInfo);
11625            return true;
11626        } else {
11627            return false;
11628        }
11629    }
11630
11631    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11632            final ApplicationErrorReport.CrashInfo crashInfo) {
11633        final ProcessRecord r = findAppProcess(app, "WTF");
11634        final String processName = app == null ? "system_server"
11635                : (r == null ? "unknown" : r.processName);
11636
11637        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11638                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11639
11640        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11641
11642        return r;
11643    }
11644
11645    /**
11646     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11647     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11648     */
11649    private ProcessRecord findAppProcess(IBinder app, String reason) {
11650        if (app == null) {
11651            return null;
11652        }
11653
11654        synchronized (this) {
11655            final int NP = mProcessNames.getMap().size();
11656            for (int ip=0; ip<NP; ip++) {
11657                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11658                final int NA = apps.size();
11659                for (int ia=0; ia<NA; ia++) {
11660                    ProcessRecord p = apps.valueAt(ia);
11661                    if (p.thread != null && p.thread.asBinder() == app) {
11662                        return p;
11663                    }
11664                }
11665            }
11666
11667            Slog.w(TAG, "Can't find mystery application for " + reason
11668                    + " from pid=" + Binder.getCallingPid()
11669                    + " uid=" + Binder.getCallingUid() + ": " + app);
11670            return null;
11671        }
11672    }
11673
11674    /**
11675     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11676     * to append various headers to the dropbox log text.
11677     */
11678    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11679            StringBuilder sb) {
11680        // Watchdog thread ends up invoking this function (with
11681        // a null ProcessRecord) to add the stack file to dropbox.
11682        // Do not acquire a lock on this (am) in such cases, as it
11683        // could cause a potential deadlock, if and when watchdog
11684        // is invoked due to unavailability of lock on am and it
11685        // would prevent watchdog from killing system_server.
11686        if (process == null) {
11687            sb.append("Process: ").append(processName).append("\n");
11688            return;
11689        }
11690        // Note: ProcessRecord 'process' is guarded by the service
11691        // instance.  (notably process.pkgList, which could otherwise change
11692        // concurrently during execution of this method)
11693        synchronized (this) {
11694            sb.append("Process: ").append(processName).append("\n");
11695            int flags = process.info.flags;
11696            IPackageManager pm = AppGlobals.getPackageManager();
11697            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11698            for (int ip=0; ip<process.pkgList.size(); ip++) {
11699                String pkg = process.pkgList.keyAt(ip);
11700                sb.append("Package: ").append(pkg);
11701                try {
11702                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11703                    if (pi != null) {
11704                        sb.append(" v").append(pi.versionCode);
11705                        if (pi.versionName != null) {
11706                            sb.append(" (").append(pi.versionName).append(")");
11707                        }
11708                    }
11709                } catch (RemoteException e) {
11710                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11711                }
11712                sb.append("\n");
11713            }
11714        }
11715    }
11716
11717    private static String processClass(ProcessRecord process) {
11718        if (process == null || process.pid == MY_PID) {
11719            return "system_server";
11720        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11721            return "system_app";
11722        } else {
11723            return "data_app";
11724        }
11725    }
11726
11727    /**
11728     * Write a description of an error (crash, WTF, ANR) to the drop box.
11729     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11730     * @param process which caused the error, null means the system server
11731     * @param activity which triggered the error, null if unknown
11732     * @param parent activity related to the error, null if unknown
11733     * @param subject line related to the error, null if absent
11734     * @param report in long form describing the error, null if absent
11735     * @param logFile to include in the report, null if none
11736     * @param crashInfo giving an application stack trace, null if absent
11737     */
11738    public void addErrorToDropBox(String eventType,
11739            ProcessRecord process, String processName, ActivityRecord activity,
11740            ActivityRecord parent, String subject,
11741            final String report, final File logFile,
11742            final ApplicationErrorReport.CrashInfo crashInfo) {
11743        // NOTE -- this must never acquire the ActivityManagerService lock,
11744        // otherwise the watchdog may be prevented from resetting the system.
11745
11746        final String dropboxTag = processClass(process) + "_" + eventType;
11747        final DropBoxManager dbox = (DropBoxManager)
11748                mContext.getSystemService(Context.DROPBOX_SERVICE);
11749
11750        // Exit early if the dropbox isn't configured to accept this report type.
11751        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11752
11753        final StringBuilder sb = new StringBuilder(1024);
11754        appendDropBoxProcessHeaders(process, processName, sb);
11755        if (activity != null) {
11756            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11757        }
11758        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11759            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11760        }
11761        if (parent != null && parent != activity) {
11762            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11763        }
11764        if (subject != null) {
11765            sb.append("Subject: ").append(subject).append("\n");
11766        }
11767        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11768        if (Debug.isDebuggerConnected()) {
11769            sb.append("Debugger: Connected\n");
11770        }
11771        sb.append("\n");
11772
11773        // Do the rest in a worker thread to avoid blocking the caller on I/O
11774        // (After this point, we shouldn't access AMS internal data structures.)
11775        Thread worker = new Thread("Error dump: " + dropboxTag) {
11776            @Override
11777            public void run() {
11778                if (report != null) {
11779                    sb.append(report);
11780                }
11781                if (logFile != null) {
11782                    try {
11783                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11784                                    "\n\n[[TRUNCATED]]"));
11785                    } catch (IOException e) {
11786                        Slog.e(TAG, "Error reading " + logFile, e);
11787                    }
11788                }
11789                if (crashInfo != null && crashInfo.stackTrace != null) {
11790                    sb.append(crashInfo.stackTrace);
11791                }
11792
11793                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11794                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11795                if (lines > 0) {
11796                    sb.append("\n");
11797
11798                    // Merge several logcat streams, and take the last N lines
11799                    InputStreamReader input = null;
11800                    try {
11801                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11802                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11803                                "-b", "crash",
11804                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11805
11806                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11807                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11808                        input = new InputStreamReader(logcat.getInputStream());
11809
11810                        int num;
11811                        char[] buf = new char[8192];
11812                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11813                    } catch (IOException e) {
11814                        Slog.e(TAG, "Error running logcat", e);
11815                    } finally {
11816                        if (input != null) try { input.close(); } catch (IOException e) {}
11817                    }
11818                }
11819
11820                dbox.addText(dropboxTag, sb.toString());
11821            }
11822        };
11823
11824        if (process == null) {
11825            // If process is null, we are being called from some internal code
11826            // and may be about to die -- run this synchronously.
11827            worker.run();
11828        } else {
11829            worker.start();
11830        }
11831    }
11832
11833    /**
11834     * Bring up the "unexpected error" dialog box for a crashing app.
11835     * Deal with edge cases (intercepts from instrumented applications,
11836     * ActivityController, error intent receivers, that sort of thing).
11837     * @param r the application crashing
11838     * @param crashInfo describing the failure
11839     */
11840    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11841        long timeMillis = System.currentTimeMillis();
11842        String shortMsg = crashInfo.exceptionClassName;
11843        String longMsg = crashInfo.exceptionMessage;
11844        String stackTrace = crashInfo.stackTrace;
11845        if (shortMsg != null && longMsg != null) {
11846            longMsg = shortMsg + ": " + longMsg;
11847        } else if (shortMsg != null) {
11848            longMsg = shortMsg;
11849        }
11850
11851        AppErrorResult result = new AppErrorResult();
11852        synchronized (this) {
11853            if (mController != null) {
11854                try {
11855                    String name = r != null ? r.processName : null;
11856                    int pid = r != null ? r.pid : Binder.getCallingPid();
11857                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11858                    if (!mController.appCrashed(name, pid,
11859                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11860                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11861                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11862                            Slog.w(TAG, "Skip killing native crashed app " + name
11863                                    + "(" + pid + ") during testing");
11864                        } else {
11865                            Slog.w(TAG, "Force-killing crashed app " + name
11866                                    + " at watcher's request");
11867                            if (r != null) {
11868                                r.kill("crash", true);
11869                            } else {
11870                                // Huh.
11871                                Process.killProcess(pid);
11872                                Process.killProcessGroup(uid, pid);
11873                            }
11874                        }
11875                        return;
11876                    }
11877                } catch (RemoteException e) {
11878                    mController = null;
11879                    Watchdog.getInstance().setActivityController(null);
11880                }
11881            }
11882
11883            final long origId = Binder.clearCallingIdentity();
11884
11885            // If this process is running instrumentation, finish it.
11886            if (r != null && r.instrumentationClass != null) {
11887                Slog.w(TAG, "Error in app " + r.processName
11888                      + " running instrumentation " + r.instrumentationClass + ":");
11889                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11890                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11891                Bundle info = new Bundle();
11892                info.putString("shortMsg", shortMsg);
11893                info.putString("longMsg", longMsg);
11894                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11895                Binder.restoreCallingIdentity(origId);
11896                return;
11897            }
11898
11899            // If we can't identify the process or it's already exceeded its crash quota,
11900            // quit right away without showing a crash dialog.
11901            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11902                Binder.restoreCallingIdentity(origId);
11903                return;
11904            }
11905
11906            Message msg = Message.obtain();
11907            msg.what = SHOW_ERROR_MSG;
11908            HashMap data = new HashMap();
11909            data.put("result", result);
11910            data.put("app", r);
11911            msg.obj = data;
11912            mHandler.sendMessage(msg);
11913
11914            Binder.restoreCallingIdentity(origId);
11915        }
11916
11917        int res = result.get();
11918
11919        Intent appErrorIntent = null;
11920        synchronized (this) {
11921            if (r != null && !r.isolated) {
11922                // XXX Can't keep track of crash time for isolated processes,
11923                // since they don't have a persistent identity.
11924                mProcessCrashTimes.put(r.info.processName, r.uid,
11925                        SystemClock.uptimeMillis());
11926            }
11927            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11928                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11929            }
11930        }
11931
11932        if (appErrorIntent != null) {
11933            try {
11934                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11935            } catch (ActivityNotFoundException e) {
11936                Slog.w(TAG, "bug report receiver dissappeared", e);
11937            }
11938        }
11939    }
11940
11941    Intent createAppErrorIntentLocked(ProcessRecord r,
11942            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11943        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11944        if (report == null) {
11945            return null;
11946        }
11947        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11948        result.setComponent(r.errorReportReceiver);
11949        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11950        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11951        return result;
11952    }
11953
11954    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11955            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11956        if (r.errorReportReceiver == null) {
11957            return null;
11958        }
11959
11960        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11961            return null;
11962        }
11963
11964        ApplicationErrorReport report = new ApplicationErrorReport();
11965        report.packageName = r.info.packageName;
11966        report.installerPackageName = r.errorReportReceiver.getPackageName();
11967        report.processName = r.processName;
11968        report.time = timeMillis;
11969        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11970
11971        if (r.crashing || r.forceCrashReport) {
11972            report.type = ApplicationErrorReport.TYPE_CRASH;
11973            report.crashInfo = crashInfo;
11974        } else if (r.notResponding) {
11975            report.type = ApplicationErrorReport.TYPE_ANR;
11976            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11977
11978            report.anrInfo.activity = r.notRespondingReport.tag;
11979            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11980            report.anrInfo.info = r.notRespondingReport.longMsg;
11981        }
11982
11983        return report;
11984    }
11985
11986    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11987        enforceNotIsolatedCaller("getProcessesInErrorState");
11988        // assume our apps are happy - lazy create the list
11989        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11990
11991        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11992                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11993        int userId = UserHandle.getUserId(Binder.getCallingUid());
11994
11995        synchronized (this) {
11996
11997            // iterate across all processes
11998            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11999                ProcessRecord app = mLruProcesses.get(i);
12000                if (!allUsers && app.userId != userId) {
12001                    continue;
12002                }
12003                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12004                    // This one's in trouble, so we'll generate a report for it
12005                    // crashes are higher priority (in case there's a crash *and* an anr)
12006                    ActivityManager.ProcessErrorStateInfo report = null;
12007                    if (app.crashing) {
12008                        report = app.crashingReport;
12009                    } else if (app.notResponding) {
12010                        report = app.notRespondingReport;
12011                    }
12012
12013                    if (report != null) {
12014                        if (errList == null) {
12015                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12016                        }
12017                        errList.add(report);
12018                    } else {
12019                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12020                                " crashing = " + app.crashing +
12021                                " notResponding = " + app.notResponding);
12022                    }
12023                }
12024            }
12025        }
12026
12027        return errList;
12028    }
12029
12030    static int procStateToImportance(int procState, int memAdj,
12031            ActivityManager.RunningAppProcessInfo currApp) {
12032        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12033        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12034            currApp.lru = memAdj;
12035        } else {
12036            currApp.lru = 0;
12037        }
12038        return imp;
12039    }
12040
12041    private void fillInProcMemInfo(ProcessRecord app,
12042            ActivityManager.RunningAppProcessInfo outInfo) {
12043        outInfo.pid = app.pid;
12044        outInfo.uid = app.info.uid;
12045        if (mHeavyWeightProcess == app) {
12046            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12047        }
12048        if (app.persistent) {
12049            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12050        }
12051        if (app.activities.size() > 0) {
12052            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12053        }
12054        outInfo.lastTrimLevel = app.trimMemoryLevel;
12055        int adj = app.curAdj;
12056        int procState = app.curProcState;
12057        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12058        outInfo.importanceReasonCode = app.adjTypeCode;
12059        outInfo.processState = app.curProcState;
12060    }
12061
12062    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12063        enforceNotIsolatedCaller("getRunningAppProcesses");
12064        // Lazy instantiation of list
12065        List<ActivityManager.RunningAppProcessInfo> runList = null;
12066        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12067                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12068        int userId = UserHandle.getUserId(Binder.getCallingUid());
12069        synchronized (this) {
12070            // Iterate across all processes
12071            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12072                ProcessRecord app = mLruProcesses.get(i);
12073                if (!allUsers && app.userId != userId) {
12074                    continue;
12075                }
12076                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12077                    // Generate process state info for running application
12078                    ActivityManager.RunningAppProcessInfo currApp =
12079                        new ActivityManager.RunningAppProcessInfo(app.processName,
12080                                app.pid, app.getPackageList());
12081                    fillInProcMemInfo(app, currApp);
12082                    if (app.adjSource instanceof ProcessRecord) {
12083                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12084                        currApp.importanceReasonImportance =
12085                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12086                                        app.adjSourceProcState);
12087                    } else if (app.adjSource instanceof ActivityRecord) {
12088                        ActivityRecord r = (ActivityRecord)app.adjSource;
12089                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12090                    }
12091                    if (app.adjTarget instanceof ComponentName) {
12092                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12093                    }
12094                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12095                    //        + " lru=" + currApp.lru);
12096                    if (runList == null) {
12097                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12098                    }
12099                    runList.add(currApp);
12100                }
12101            }
12102        }
12103        return runList;
12104    }
12105
12106    public List<ApplicationInfo> getRunningExternalApplications() {
12107        enforceNotIsolatedCaller("getRunningExternalApplications");
12108        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12109        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12110        if (runningApps != null && runningApps.size() > 0) {
12111            Set<String> extList = new HashSet<String>();
12112            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12113                if (app.pkgList != null) {
12114                    for (String pkg : app.pkgList) {
12115                        extList.add(pkg);
12116                    }
12117                }
12118            }
12119            IPackageManager pm = AppGlobals.getPackageManager();
12120            for (String pkg : extList) {
12121                try {
12122                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12123                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12124                        retList.add(info);
12125                    }
12126                } catch (RemoteException e) {
12127                }
12128            }
12129        }
12130        return retList;
12131    }
12132
12133    @Override
12134    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12135        enforceNotIsolatedCaller("getMyMemoryState");
12136        synchronized (this) {
12137            ProcessRecord proc;
12138            synchronized (mPidsSelfLocked) {
12139                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12140            }
12141            fillInProcMemInfo(proc, outInfo);
12142        }
12143    }
12144
12145    @Override
12146    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12147        if (checkCallingPermission(android.Manifest.permission.DUMP)
12148                != PackageManager.PERMISSION_GRANTED) {
12149            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12150                    + Binder.getCallingPid()
12151                    + ", uid=" + Binder.getCallingUid()
12152                    + " without permission "
12153                    + android.Manifest.permission.DUMP);
12154            return;
12155        }
12156
12157        boolean dumpAll = false;
12158        boolean dumpClient = false;
12159        String dumpPackage = null;
12160
12161        int opti = 0;
12162        while (opti < args.length) {
12163            String opt = args[opti];
12164            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12165                break;
12166            }
12167            opti++;
12168            if ("-a".equals(opt)) {
12169                dumpAll = true;
12170            } else if ("-c".equals(opt)) {
12171                dumpClient = true;
12172            } else if ("-h".equals(opt)) {
12173                pw.println("Activity manager dump options:");
12174                pw.println("  [-a] [-c] [-h] [cmd] ...");
12175                pw.println("  cmd may be one of:");
12176                pw.println("    a[ctivities]: activity stack state");
12177                pw.println("    r[recents]: recent activities state");
12178                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12179                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12180                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12181                pw.println("    o[om]: out of memory management");
12182                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12183                pw.println("    provider [COMP_SPEC]: provider client-side state");
12184                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12185                pw.println("    service [COMP_SPEC]: service client-side state");
12186                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12187                pw.println("    all: dump all activities");
12188                pw.println("    top: dump the top activity");
12189                pw.println("    write: write all pending state to storage");
12190                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12191                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12192                pw.println("    a partial substring in a component name, a");
12193                pw.println("    hex object identifier.");
12194                pw.println("  -a: include all available server state.");
12195                pw.println("  -c: include client state.");
12196                return;
12197            } else {
12198                pw.println("Unknown argument: " + opt + "; use -h for help");
12199            }
12200        }
12201
12202        long origId = Binder.clearCallingIdentity();
12203        boolean more = false;
12204        // Is the caller requesting to dump a particular piece of data?
12205        if (opti < args.length) {
12206            String cmd = args[opti];
12207            opti++;
12208            if ("activities".equals(cmd) || "a".equals(cmd)) {
12209                synchronized (this) {
12210                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12211                }
12212            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12213                synchronized (this) {
12214                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12215                }
12216            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12217                String[] newArgs;
12218                String name;
12219                if (opti >= args.length) {
12220                    name = null;
12221                    newArgs = EMPTY_STRING_ARRAY;
12222                } else {
12223                    name = args[opti];
12224                    opti++;
12225                    newArgs = new String[args.length - opti];
12226                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12227                            args.length - opti);
12228                }
12229                synchronized (this) {
12230                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12231                }
12232            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12233                String[] newArgs;
12234                String name;
12235                if (opti >= args.length) {
12236                    name = null;
12237                    newArgs = EMPTY_STRING_ARRAY;
12238                } else {
12239                    name = args[opti];
12240                    opti++;
12241                    newArgs = new String[args.length - opti];
12242                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12243                            args.length - opti);
12244                }
12245                synchronized (this) {
12246                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12247                }
12248            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12249                String[] newArgs;
12250                String name;
12251                if (opti >= args.length) {
12252                    name = null;
12253                    newArgs = EMPTY_STRING_ARRAY;
12254                } else {
12255                    name = args[opti];
12256                    opti++;
12257                    newArgs = new String[args.length - opti];
12258                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12259                            args.length - opti);
12260                }
12261                synchronized (this) {
12262                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12263                }
12264            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12265                synchronized (this) {
12266                    dumpOomLocked(fd, pw, args, opti, true);
12267                }
12268            } else if ("provider".equals(cmd)) {
12269                String[] newArgs;
12270                String name;
12271                if (opti >= args.length) {
12272                    name = null;
12273                    newArgs = EMPTY_STRING_ARRAY;
12274                } else {
12275                    name = args[opti];
12276                    opti++;
12277                    newArgs = new String[args.length - opti];
12278                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12279                }
12280                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12281                    pw.println("No providers match: " + name);
12282                    pw.println("Use -h for help.");
12283                }
12284            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12285                synchronized (this) {
12286                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12287                }
12288            } else if ("service".equals(cmd)) {
12289                String[] newArgs;
12290                String name;
12291                if (opti >= args.length) {
12292                    name = null;
12293                    newArgs = EMPTY_STRING_ARRAY;
12294                } else {
12295                    name = args[opti];
12296                    opti++;
12297                    newArgs = new String[args.length - opti];
12298                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12299                            args.length - opti);
12300                }
12301                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12302                    pw.println("No services match: " + name);
12303                    pw.println("Use -h for help.");
12304                }
12305            } else if ("package".equals(cmd)) {
12306                String[] newArgs;
12307                if (opti >= args.length) {
12308                    pw.println("package: no package name specified");
12309                    pw.println("Use -h for help.");
12310                } else {
12311                    dumpPackage = args[opti];
12312                    opti++;
12313                    newArgs = new String[args.length - opti];
12314                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12315                            args.length - opti);
12316                    args = newArgs;
12317                    opti = 0;
12318                    more = true;
12319                }
12320            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12321                synchronized (this) {
12322                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12323                }
12324            } else if ("write".equals(cmd)) {
12325                mTaskPersister.flush();
12326                pw.println("All tasks persisted.");
12327                return;
12328            } else {
12329                // Dumping a single activity?
12330                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12331                    pw.println("Bad activity command, or no activities match: " + cmd);
12332                    pw.println("Use -h for help.");
12333                }
12334            }
12335            if (!more) {
12336                Binder.restoreCallingIdentity(origId);
12337                return;
12338            }
12339        }
12340
12341        // No piece of data specified, dump everything.
12342        synchronized (this) {
12343            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12344            pw.println();
12345            if (dumpAll) {
12346                pw.println("-------------------------------------------------------------------------------");
12347            }
12348            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12349            pw.println();
12350            if (dumpAll) {
12351                pw.println("-------------------------------------------------------------------------------");
12352            }
12353            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12354            pw.println();
12355            if (dumpAll) {
12356                pw.println("-------------------------------------------------------------------------------");
12357            }
12358            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12359            pw.println();
12360            if (dumpAll) {
12361                pw.println("-------------------------------------------------------------------------------");
12362            }
12363            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12364            pw.println();
12365            if (dumpAll) {
12366                pw.println("-------------------------------------------------------------------------------");
12367            }
12368            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12369            pw.println();
12370            if (dumpAll) {
12371                pw.println("-------------------------------------------------------------------------------");
12372            }
12373            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12374        }
12375        Binder.restoreCallingIdentity(origId);
12376    }
12377
12378    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12379            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12380        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12381
12382        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12383                dumpPackage);
12384        boolean needSep = printedAnything;
12385
12386        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12387                dumpPackage, needSep, "  mFocusedActivity: ");
12388        if (printed) {
12389            printedAnything = true;
12390            needSep = false;
12391        }
12392
12393        if (dumpPackage == null) {
12394            if (needSep) {
12395                pw.println();
12396            }
12397            needSep = true;
12398            printedAnything = true;
12399            mStackSupervisor.dump(pw, "  ");
12400        }
12401
12402        if (!printedAnything) {
12403            pw.println("  (nothing)");
12404        }
12405    }
12406
12407    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12408            int opti, boolean dumpAll, String dumpPackage) {
12409        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12410
12411        boolean printedAnything = false;
12412
12413        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12414            boolean printedHeader = false;
12415
12416            final int N = mRecentTasks.size();
12417            for (int i=0; i<N; i++) {
12418                TaskRecord tr = mRecentTasks.get(i);
12419                if (dumpPackage != null) {
12420                    if (tr.realActivity == null ||
12421                            !dumpPackage.equals(tr.realActivity)) {
12422                        continue;
12423                    }
12424                }
12425                if (!printedHeader) {
12426                    pw.println("  Recent tasks:");
12427                    printedHeader = true;
12428                    printedAnything = true;
12429                }
12430                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12431                        pw.println(tr);
12432                if (dumpAll) {
12433                    mRecentTasks.get(i).dump(pw, "    ");
12434                }
12435            }
12436        }
12437
12438        if (!printedAnything) {
12439            pw.println("  (nothing)");
12440        }
12441    }
12442
12443    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12444            int opti, boolean dumpAll, String dumpPackage) {
12445        boolean needSep = false;
12446        boolean printedAnything = false;
12447        int numPers = 0;
12448
12449        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12450
12451        if (dumpAll) {
12452            final int NP = mProcessNames.getMap().size();
12453            for (int ip=0; ip<NP; ip++) {
12454                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12455                final int NA = procs.size();
12456                for (int ia=0; ia<NA; ia++) {
12457                    ProcessRecord r = procs.valueAt(ia);
12458                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12459                        continue;
12460                    }
12461                    if (!needSep) {
12462                        pw.println("  All known processes:");
12463                        needSep = true;
12464                        printedAnything = true;
12465                    }
12466                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12467                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12468                        pw.print(" "); pw.println(r);
12469                    r.dump(pw, "    ");
12470                    if (r.persistent) {
12471                        numPers++;
12472                    }
12473                }
12474            }
12475        }
12476
12477        if (mIsolatedProcesses.size() > 0) {
12478            boolean printed = false;
12479            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12480                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12481                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12482                    continue;
12483                }
12484                if (!printed) {
12485                    if (needSep) {
12486                        pw.println();
12487                    }
12488                    pw.println("  Isolated process list (sorted by uid):");
12489                    printedAnything = true;
12490                    printed = true;
12491                    needSep = true;
12492                }
12493                pw.println(String.format("%sIsolated #%2d: %s",
12494                        "    ", i, r.toString()));
12495            }
12496        }
12497
12498        if (mLruProcesses.size() > 0) {
12499            if (needSep) {
12500                pw.println();
12501            }
12502            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12503                    pw.print(" total, non-act at ");
12504                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12505                    pw.print(", non-svc at ");
12506                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12507                    pw.println("):");
12508            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12509            needSep = true;
12510            printedAnything = true;
12511        }
12512
12513        if (dumpAll || dumpPackage != null) {
12514            synchronized (mPidsSelfLocked) {
12515                boolean printed = false;
12516                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12517                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12518                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12519                        continue;
12520                    }
12521                    if (!printed) {
12522                        if (needSep) pw.println();
12523                        needSep = true;
12524                        pw.println("  PID mappings:");
12525                        printed = true;
12526                        printedAnything = true;
12527                    }
12528                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12529                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12530                }
12531            }
12532        }
12533
12534        if (mForegroundProcesses.size() > 0) {
12535            synchronized (mPidsSelfLocked) {
12536                boolean printed = false;
12537                for (int i=0; i<mForegroundProcesses.size(); i++) {
12538                    ProcessRecord r = mPidsSelfLocked.get(
12539                            mForegroundProcesses.valueAt(i).pid);
12540                    if (dumpPackage != null && (r == null
12541                            || !r.pkgList.containsKey(dumpPackage))) {
12542                        continue;
12543                    }
12544                    if (!printed) {
12545                        if (needSep) pw.println();
12546                        needSep = true;
12547                        pw.println("  Foreground Processes:");
12548                        printed = true;
12549                        printedAnything = true;
12550                    }
12551                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12552                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12553                }
12554            }
12555        }
12556
12557        if (mPersistentStartingProcesses.size() > 0) {
12558            if (needSep) pw.println();
12559            needSep = true;
12560            printedAnything = true;
12561            pw.println("  Persisent processes that are starting:");
12562            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12563                    "Starting Norm", "Restarting PERS", dumpPackage);
12564        }
12565
12566        if (mRemovedProcesses.size() > 0) {
12567            if (needSep) pw.println();
12568            needSep = true;
12569            printedAnything = true;
12570            pw.println("  Processes that are being removed:");
12571            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12572                    "Removed Norm", "Removed PERS", dumpPackage);
12573        }
12574
12575        if (mProcessesOnHold.size() > 0) {
12576            if (needSep) pw.println();
12577            needSep = true;
12578            printedAnything = true;
12579            pw.println("  Processes that are on old until the system is ready:");
12580            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12581                    "OnHold Norm", "OnHold PERS", dumpPackage);
12582        }
12583
12584        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12585
12586        if (mProcessCrashTimes.getMap().size() > 0) {
12587            boolean printed = false;
12588            long now = SystemClock.uptimeMillis();
12589            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12590            final int NP = pmap.size();
12591            for (int ip=0; ip<NP; ip++) {
12592                String pname = pmap.keyAt(ip);
12593                SparseArray<Long> uids = pmap.valueAt(ip);
12594                final int N = uids.size();
12595                for (int i=0; i<N; i++) {
12596                    int puid = uids.keyAt(i);
12597                    ProcessRecord r = mProcessNames.get(pname, puid);
12598                    if (dumpPackage != null && (r == null
12599                            || !r.pkgList.containsKey(dumpPackage))) {
12600                        continue;
12601                    }
12602                    if (!printed) {
12603                        if (needSep) pw.println();
12604                        needSep = true;
12605                        pw.println("  Time since processes crashed:");
12606                        printed = true;
12607                        printedAnything = true;
12608                    }
12609                    pw.print("    Process "); pw.print(pname);
12610                            pw.print(" uid "); pw.print(puid);
12611                            pw.print(": last crashed ");
12612                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12613                            pw.println(" ago");
12614                }
12615            }
12616        }
12617
12618        if (mBadProcesses.getMap().size() > 0) {
12619            boolean printed = false;
12620            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12621            final int NP = pmap.size();
12622            for (int ip=0; ip<NP; ip++) {
12623                String pname = pmap.keyAt(ip);
12624                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12625                final int N = uids.size();
12626                for (int i=0; i<N; i++) {
12627                    int puid = uids.keyAt(i);
12628                    ProcessRecord r = mProcessNames.get(pname, puid);
12629                    if (dumpPackage != null && (r == null
12630                            || !r.pkgList.containsKey(dumpPackage))) {
12631                        continue;
12632                    }
12633                    if (!printed) {
12634                        if (needSep) pw.println();
12635                        needSep = true;
12636                        pw.println("  Bad processes:");
12637                        printedAnything = true;
12638                    }
12639                    BadProcessInfo info = uids.valueAt(i);
12640                    pw.print("    Bad process "); pw.print(pname);
12641                            pw.print(" uid "); pw.print(puid);
12642                            pw.print(": crashed at time "); pw.println(info.time);
12643                    if (info.shortMsg != null) {
12644                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12645                    }
12646                    if (info.longMsg != null) {
12647                        pw.print("      Long msg: "); pw.println(info.longMsg);
12648                    }
12649                    if (info.stack != null) {
12650                        pw.println("      Stack:");
12651                        int lastPos = 0;
12652                        for (int pos=0; pos<info.stack.length(); pos++) {
12653                            if (info.stack.charAt(pos) == '\n') {
12654                                pw.print("        ");
12655                                pw.write(info.stack, lastPos, pos-lastPos);
12656                                pw.println();
12657                                lastPos = pos+1;
12658                            }
12659                        }
12660                        if (lastPos < info.stack.length()) {
12661                            pw.print("        ");
12662                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12663                            pw.println();
12664                        }
12665                    }
12666                }
12667            }
12668        }
12669
12670        if (dumpPackage == null) {
12671            pw.println();
12672            needSep = false;
12673            pw.println("  mStartedUsers:");
12674            for (int i=0; i<mStartedUsers.size(); i++) {
12675                UserStartedState uss = mStartedUsers.valueAt(i);
12676                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12677                        pw.print(": "); uss.dump("", pw);
12678            }
12679            pw.print("  mStartedUserArray: [");
12680            for (int i=0; i<mStartedUserArray.length; i++) {
12681                if (i > 0) pw.print(", ");
12682                pw.print(mStartedUserArray[i]);
12683            }
12684            pw.println("]");
12685            pw.print("  mUserLru: [");
12686            for (int i=0; i<mUserLru.size(); i++) {
12687                if (i > 0) pw.print(", ");
12688                pw.print(mUserLru.get(i));
12689            }
12690            pw.println("]");
12691            if (dumpAll) {
12692                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12693            }
12694            synchronized (mUserProfileGroupIdsSelfLocked) {
12695                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12696                    pw.println("  mUserProfileGroupIds:");
12697                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12698                        pw.print("    User #");
12699                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12700                        pw.print(" -> profile #");
12701                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12702                    }
12703                }
12704            }
12705        }
12706        if (mHomeProcess != null && (dumpPackage == null
12707                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12708            if (needSep) {
12709                pw.println();
12710                needSep = false;
12711            }
12712            pw.println("  mHomeProcess: " + mHomeProcess);
12713        }
12714        if (mPreviousProcess != null && (dumpPackage == null
12715                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12716            if (needSep) {
12717                pw.println();
12718                needSep = false;
12719            }
12720            pw.println("  mPreviousProcess: " + mPreviousProcess);
12721        }
12722        if (dumpAll) {
12723            StringBuilder sb = new StringBuilder(128);
12724            sb.append("  mPreviousProcessVisibleTime: ");
12725            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12726            pw.println(sb);
12727        }
12728        if (mHeavyWeightProcess != null && (dumpPackage == null
12729                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12730            if (needSep) {
12731                pw.println();
12732                needSep = false;
12733            }
12734            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12735        }
12736        if (dumpPackage == null) {
12737            pw.println("  mConfiguration: " + mConfiguration);
12738        }
12739        if (dumpAll) {
12740            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12741            if (mCompatModePackages.getPackages().size() > 0) {
12742                boolean printed = false;
12743                for (Map.Entry<String, Integer> entry
12744                        : mCompatModePackages.getPackages().entrySet()) {
12745                    String pkg = entry.getKey();
12746                    int mode = entry.getValue();
12747                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12748                        continue;
12749                    }
12750                    if (!printed) {
12751                        pw.println("  mScreenCompatPackages:");
12752                        printed = true;
12753                    }
12754                    pw.print("    "); pw.print(pkg); pw.print(": ");
12755                            pw.print(mode); pw.println();
12756                }
12757            }
12758        }
12759        if (dumpPackage == null) {
12760            if (mSleeping || mWentToSleep || mLockScreenShown) {
12761                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12762                        + " mLockScreenShown " + mLockScreenShown);
12763            }
12764            if (mShuttingDown || mRunningVoice) {
12765                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12766            }
12767        }
12768        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12769                || mOrigWaitForDebugger) {
12770            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12771                    || dumpPackage.equals(mOrigDebugApp)) {
12772                if (needSep) {
12773                    pw.println();
12774                    needSep = false;
12775                }
12776                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12777                        + " mDebugTransient=" + mDebugTransient
12778                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12779            }
12780        }
12781        if (mOpenGlTraceApp != null) {
12782            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12783                if (needSep) {
12784                    pw.println();
12785                    needSep = false;
12786                }
12787                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12788            }
12789        }
12790        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12791                || mProfileFd != null) {
12792            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12793                if (needSep) {
12794                    pw.println();
12795                    needSep = false;
12796                }
12797                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12798                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12799                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12800                        + mAutoStopProfiler);
12801                pw.println("  mProfileType=" + mProfileType);
12802            }
12803        }
12804        if (dumpPackage == null) {
12805            if (mAlwaysFinishActivities || mController != null) {
12806                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12807                        + " mController=" + mController);
12808            }
12809            if (dumpAll) {
12810                pw.println("  Total persistent processes: " + numPers);
12811                pw.println("  mProcessesReady=" + mProcessesReady
12812                        + " mSystemReady=" + mSystemReady
12813                        + " mBooted=" + mBooted
12814                        + " mFactoryTest=" + mFactoryTest);
12815                pw.println("  mBooting=" + mBooting
12816                        + " mCallFinishBooting=" + mCallFinishBooting
12817                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12818                pw.print("  mLastPowerCheckRealtime=");
12819                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12820                        pw.println("");
12821                pw.print("  mLastPowerCheckUptime=");
12822                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12823                        pw.println("");
12824                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12825                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12826                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12827                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12828                        + " (" + mLruProcesses.size() + " total)"
12829                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12830                        + " mNumServiceProcs=" + mNumServiceProcs
12831                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12832                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12833                        + " mLastMemoryLevel" + mLastMemoryLevel
12834                        + " mLastNumProcesses" + mLastNumProcesses);
12835                long now = SystemClock.uptimeMillis();
12836                pw.print("  mLastIdleTime=");
12837                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12838                        pw.print(" mLowRamSinceLastIdle=");
12839                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12840                        pw.println();
12841            }
12842        }
12843
12844        if (!printedAnything) {
12845            pw.println("  (nothing)");
12846        }
12847    }
12848
12849    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12850            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12851        if (mProcessesToGc.size() > 0) {
12852            boolean printed = false;
12853            long now = SystemClock.uptimeMillis();
12854            for (int i=0; i<mProcessesToGc.size(); i++) {
12855                ProcessRecord proc = mProcessesToGc.get(i);
12856                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12857                    continue;
12858                }
12859                if (!printed) {
12860                    if (needSep) pw.println();
12861                    needSep = true;
12862                    pw.println("  Processes that are waiting to GC:");
12863                    printed = true;
12864                }
12865                pw.print("    Process "); pw.println(proc);
12866                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12867                        pw.print(", last gced=");
12868                        pw.print(now-proc.lastRequestedGc);
12869                        pw.print(" ms ago, last lowMem=");
12870                        pw.print(now-proc.lastLowMemory);
12871                        pw.println(" ms ago");
12872
12873            }
12874        }
12875        return needSep;
12876    }
12877
12878    void printOomLevel(PrintWriter pw, String name, int adj) {
12879        pw.print("    ");
12880        if (adj >= 0) {
12881            pw.print(' ');
12882            if (adj < 10) pw.print(' ');
12883        } else {
12884            if (adj > -10) pw.print(' ');
12885        }
12886        pw.print(adj);
12887        pw.print(": ");
12888        pw.print(name);
12889        pw.print(" (");
12890        pw.print(mProcessList.getMemLevel(adj)/1024);
12891        pw.println(" kB)");
12892    }
12893
12894    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12895            int opti, boolean dumpAll) {
12896        boolean needSep = false;
12897
12898        if (mLruProcesses.size() > 0) {
12899            if (needSep) pw.println();
12900            needSep = true;
12901            pw.println("  OOM levels:");
12902            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12903            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12904            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12905            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12906            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12907            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12908            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12909            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12910            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12911            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12912            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12913            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12914            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12915            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12916
12917            if (needSep) pw.println();
12918            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12919                    pw.print(" total, non-act at ");
12920                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12921                    pw.print(", non-svc at ");
12922                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12923                    pw.println("):");
12924            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12925            needSep = true;
12926        }
12927
12928        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12929
12930        pw.println();
12931        pw.println("  mHomeProcess: " + mHomeProcess);
12932        pw.println("  mPreviousProcess: " + mPreviousProcess);
12933        if (mHeavyWeightProcess != null) {
12934            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12935        }
12936
12937        return true;
12938    }
12939
12940    /**
12941     * There are three ways to call this:
12942     *  - no provider specified: dump all the providers
12943     *  - a flattened component name that matched an existing provider was specified as the
12944     *    first arg: dump that one provider
12945     *  - the first arg isn't the flattened component name of an existing provider:
12946     *    dump all providers whose component contains the first arg as a substring
12947     */
12948    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12949            int opti, boolean dumpAll) {
12950        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12951    }
12952
12953    static class ItemMatcher {
12954        ArrayList<ComponentName> components;
12955        ArrayList<String> strings;
12956        ArrayList<Integer> objects;
12957        boolean all;
12958
12959        ItemMatcher() {
12960            all = true;
12961        }
12962
12963        void build(String name) {
12964            ComponentName componentName = ComponentName.unflattenFromString(name);
12965            if (componentName != null) {
12966                if (components == null) {
12967                    components = new ArrayList<ComponentName>();
12968                }
12969                components.add(componentName);
12970                all = false;
12971            } else {
12972                int objectId = 0;
12973                // Not a '/' separated full component name; maybe an object ID?
12974                try {
12975                    objectId = Integer.parseInt(name, 16);
12976                    if (objects == null) {
12977                        objects = new ArrayList<Integer>();
12978                    }
12979                    objects.add(objectId);
12980                    all = false;
12981                } catch (RuntimeException e) {
12982                    // Not an integer; just do string match.
12983                    if (strings == null) {
12984                        strings = new ArrayList<String>();
12985                    }
12986                    strings.add(name);
12987                    all = false;
12988                }
12989            }
12990        }
12991
12992        int build(String[] args, int opti) {
12993            for (; opti<args.length; opti++) {
12994                String name = args[opti];
12995                if ("--".equals(name)) {
12996                    return opti+1;
12997                }
12998                build(name);
12999            }
13000            return opti;
13001        }
13002
13003        boolean match(Object object, ComponentName comp) {
13004            if (all) {
13005                return true;
13006            }
13007            if (components != null) {
13008                for (int i=0; i<components.size(); i++) {
13009                    if (components.get(i).equals(comp)) {
13010                        return true;
13011                    }
13012                }
13013            }
13014            if (objects != null) {
13015                for (int i=0; i<objects.size(); i++) {
13016                    if (System.identityHashCode(object) == objects.get(i)) {
13017                        return true;
13018                    }
13019                }
13020            }
13021            if (strings != null) {
13022                String flat = comp.flattenToString();
13023                for (int i=0; i<strings.size(); i++) {
13024                    if (flat.contains(strings.get(i))) {
13025                        return true;
13026                    }
13027                }
13028            }
13029            return false;
13030        }
13031    }
13032
13033    /**
13034     * There are three things that cmd can be:
13035     *  - a flattened component name that matches an existing activity
13036     *  - the cmd arg isn't the flattened component name of an existing activity:
13037     *    dump all activity whose component contains the cmd as a substring
13038     *  - A hex number of the ActivityRecord object instance.
13039     */
13040    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13041            int opti, boolean dumpAll) {
13042        ArrayList<ActivityRecord> activities;
13043
13044        synchronized (this) {
13045            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13046        }
13047
13048        if (activities.size() <= 0) {
13049            return false;
13050        }
13051
13052        String[] newArgs = new String[args.length - opti];
13053        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13054
13055        TaskRecord lastTask = null;
13056        boolean needSep = false;
13057        for (int i=activities.size()-1; i>=0; i--) {
13058            ActivityRecord r = activities.get(i);
13059            if (needSep) {
13060                pw.println();
13061            }
13062            needSep = true;
13063            synchronized (this) {
13064                if (lastTask != r.task) {
13065                    lastTask = r.task;
13066                    pw.print("TASK "); pw.print(lastTask.affinity);
13067                            pw.print(" id="); pw.println(lastTask.taskId);
13068                    if (dumpAll) {
13069                        lastTask.dump(pw, "  ");
13070                    }
13071                }
13072            }
13073            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13074        }
13075        return true;
13076    }
13077
13078    /**
13079     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13080     * there is a thread associated with the activity.
13081     */
13082    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13083            final ActivityRecord r, String[] args, boolean dumpAll) {
13084        String innerPrefix = prefix + "  ";
13085        synchronized (this) {
13086            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13087                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13088                    pw.print(" pid=");
13089                    if (r.app != null) pw.println(r.app.pid);
13090                    else pw.println("(not running)");
13091            if (dumpAll) {
13092                r.dump(pw, innerPrefix);
13093            }
13094        }
13095        if (r.app != null && r.app.thread != null) {
13096            // flush anything that is already in the PrintWriter since the thread is going
13097            // to write to the file descriptor directly
13098            pw.flush();
13099            try {
13100                TransferPipe tp = new TransferPipe();
13101                try {
13102                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13103                            r.appToken, innerPrefix, args);
13104                    tp.go(fd);
13105                } finally {
13106                    tp.kill();
13107                }
13108            } catch (IOException e) {
13109                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13110            } catch (RemoteException e) {
13111                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13112            }
13113        }
13114    }
13115
13116    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13117            int opti, boolean dumpAll, String dumpPackage) {
13118        boolean needSep = false;
13119        boolean onlyHistory = false;
13120        boolean printedAnything = false;
13121
13122        if ("history".equals(dumpPackage)) {
13123            if (opti < args.length && "-s".equals(args[opti])) {
13124                dumpAll = false;
13125            }
13126            onlyHistory = true;
13127            dumpPackage = null;
13128        }
13129
13130        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13131        if (!onlyHistory && dumpAll) {
13132            if (mRegisteredReceivers.size() > 0) {
13133                boolean printed = false;
13134                Iterator it = mRegisteredReceivers.values().iterator();
13135                while (it.hasNext()) {
13136                    ReceiverList r = (ReceiverList)it.next();
13137                    if (dumpPackage != null && (r.app == null ||
13138                            !dumpPackage.equals(r.app.info.packageName))) {
13139                        continue;
13140                    }
13141                    if (!printed) {
13142                        pw.println("  Registered Receivers:");
13143                        needSep = true;
13144                        printed = true;
13145                        printedAnything = true;
13146                    }
13147                    pw.print("  * "); pw.println(r);
13148                    r.dump(pw, "    ");
13149                }
13150            }
13151
13152            if (mReceiverResolver.dump(pw, needSep ?
13153                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13154                    "    ", dumpPackage, false)) {
13155                needSep = true;
13156                printedAnything = true;
13157            }
13158        }
13159
13160        for (BroadcastQueue q : mBroadcastQueues) {
13161            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13162            printedAnything |= needSep;
13163        }
13164
13165        needSep = true;
13166
13167        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13168            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13169                if (needSep) {
13170                    pw.println();
13171                }
13172                needSep = true;
13173                printedAnything = true;
13174                pw.print("  Sticky broadcasts for user ");
13175                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13176                StringBuilder sb = new StringBuilder(128);
13177                for (Map.Entry<String, ArrayList<Intent>> ent
13178                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13179                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13180                    if (dumpAll) {
13181                        pw.println(":");
13182                        ArrayList<Intent> intents = ent.getValue();
13183                        final int N = intents.size();
13184                        for (int i=0; i<N; i++) {
13185                            sb.setLength(0);
13186                            sb.append("    Intent: ");
13187                            intents.get(i).toShortString(sb, false, true, false, false);
13188                            pw.println(sb.toString());
13189                            Bundle bundle = intents.get(i).getExtras();
13190                            if (bundle != null) {
13191                                pw.print("      ");
13192                                pw.println(bundle.toString());
13193                            }
13194                        }
13195                    } else {
13196                        pw.println("");
13197                    }
13198                }
13199            }
13200        }
13201
13202        if (!onlyHistory && dumpAll) {
13203            pw.println();
13204            for (BroadcastQueue queue : mBroadcastQueues) {
13205                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13206                        + queue.mBroadcastsScheduled);
13207            }
13208            pw.println("  mHandler:");
13209            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13210            needSep = true;
13211            printedAnything = true;
13212        }
13213
13214        if (!printedAnything) {
13215            pw.println("  (nothing)");
13216        }
13217    }
13218
13219    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13220            int opti, boolean dumpAll, String dumpPackage) {
13221        boolean needSep;
13222        boolean printedAnything = false;
13223
13224        ItemMatcher matcher = new ItemMatcher();
13225        matcher.build(args, opti);
13226
13227        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13228
13229        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13230        printedAnything |= needSep;
13231
13232        if (mLaunchingProviders.size() > 0) {
13233            boolean printed = false;
13234            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13235                ContentProviderRecord r = mLaunchingProviders.get(i);
13236                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13237                    continue;
13238                }
13239                if (!printed) {
13240                    if (needSep) pw.println();
13241                    needSep = true;
13242                    pw.println("  Launching content providers:");
13243                    printed = true;
13244                    printedAnything = true;
13245                }
13246                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13247                        pw.println(r);
13248            }
13249        }
13250
13251        if (mGrantedUriPermissions.size() > 0) {
13252            boolean printed = false;
13253            int dumpUid = -2;
13254            if (dumpPackage != null) {
13255                try {
13256                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13257                } catch (NameNotFoundException e) {
13258                    dumpUid = -1;
13259                }
13260            }
13261            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13262                int uid = mGrantedUriPermissions.keyAt(i);
13263                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13264                    continue;
13265                }
13266                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13267                if (!printed) {
13268                    if (needSep) pw.println();
13269                    needSep = true;
13270                    pw.println("  Granted Uri Permissions:");
13271                    printed = true;
13272                    printedAnything = true;
13273                }
13274                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13275                for (UriPermission perm : perms.values()) {
13276                    pw.print("    "); pw.println(perm);
13277                    if (dumpAll) {
13278                        perm.dump(pw, "      ");
13279                    }
13280                }
13281            }
13282        }
13283
13284        if (!printedAnything) {
13285            pw.println("  (nothing)");
13286        }
13287    }
13288
13289    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13290            int opti, boolean dumpAll, String dumpPackage) {
13291        boolean printed = false;
13292
13293        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13294
13295        if (mIntentSenderRecords.size() > 0) {
13296            Iterator<WeakReference<PendingIntentRecord>> it
13297                    = mIntentSenderRecords.values().iterator();
13298            while (it.hasNext()) {
13299                WeakReference<PendingIntentRecord> ref = it.next();
13300                PendingIntentRecord rec = ref != null ? ref.get(): null;
13301                if (dumpPackage != null && (rec == null
13302                        || !dumpPackage.equals(rec.key.packageName))) {
13303                    continue;
13304                }
13305                printed = true;
13306                if (rec != null) {
13307                    pw.print("  * "); pw.println(rec);
13308                    if (dumpAll) {
13309                        rec.dump(pw, "    ");
13310                    }
13311                } else {
13312                    pw.print("  * "); pw.println(ref);
13313                }
13314            }
13315        }
13316
13317        if (!printed) {
13318            pw.println("  (nothing)");
13319        }
13320    }
13321
13322    private static final int dumpProcessList(PrintWriter pw,
13323            ActivityManagerService service, List list,
13324            String prefix, String normalLabel, String persistentLabel,
13325            String dumpPackage) {
13326        int numPers = 0;
13327        final int N = list.size()-1;
13328        for (int i=N; i>=0; i--) {
13329            ProcessRecord r = (ProcessRecord)list.get(i);
13330            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13331                continue;
13332            }
13333            pw.println(String.format("%s%s #%2d: %s",
13334                    prefix, (r.persistent ? persistentLabel : normalLabel),
13335                    i, r.toString()));
13336            if (r.persistent) {
13337                numPers++;
13338            }
13339        }
13340        return numPers;
13341    }
13342
13343    private static final boolean dumpProcessOomList(PrintWriter pw,
13344            ActivityManagerService service, List<ProcessRecord> origList,
13345            String prefix, String normalLabel, String persistentLabel,
13346            boolean inclDetails, String dumpPackage) {
13347
13348        ArrayList<Pair<ProcessRecord, Integer>> list
13349                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13350        for (int i=0; i<origList.size(); i++) {
13351            ProcessRecord r = origList.get(i);
13352            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13353                continue;
13354            }
13355            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13356        }
13357
13358        if (list.size() <= 0) {
13359            return false;
13360        }
13361
13362        Comparator<Pair<ProcessRecord, Integer>> comparator
13363                = new Comparator<Pair<ProcessRecord, Integer>>() {
13364            @Override
13365            public int compare(Pair<ProcessRecord, Integer> object1,
13366                    Pair<ProcessRecord, Integer> object2) {
13367                if (object1.first.setAdj != object2.first.setAdj) {
13368                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13369                }
13370                if (object1.second.intValue() != object2.second.intValue()) {
13371                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13372                }
13373                return 0;
13374            }
13375        };
13376
13377        Collections.sort(list, comparator);
13378
13379        final long curRealtime = SystemClock.elapsedRealtime();
13380        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13381        final long curUptime = SystemClock.uptimeMillis();
13382        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13383
13384        for (int i=list.size()-1; i>=0; i--) {
13385            ProcessRecord r = list.get(i).first;
13386            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13387            char schedGroup;
13388            switch (r.setSchedGroup) {
13389                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13390                    schedGroup = 'B';
13391                    break;
13392                case Process.THREAD_GROUP_DEFAULT:
13393                    schedGroup = 'F';
13394                    break;
13395                default:
13396                    schedGroup = '?';
13397                    break;
13398            }
13399            char foreground;
13400            if (r.foregroundActivities) {
13401                foreground = 'A';
13402            } else if (r.foregroundServices) {
13403                foreground = 'S';
13404            } else {
13405                foreground = ' ';
13406            }
13407            String procState = ProcessList.makeProcStateString(r.curProcState);
13408            pw.print(prefix);
13409            pw.print(r.persistent ? persistentLabel : normalLabel);
13410            pw.print(" #");
13411            int num = (origList.size()-1)-list.get(i).second;
13412            if (num < 10) pw.print(' ');
13413            pw.print(num);
13414            pw.print(": ");
13415            pw.print(oomAdj);
13416            pw.print(' ');
13417            pw.print(schedGroup);
13418            pw.print('/');
13419            pw.print(foreground);
13420            pw.print('/');
13421            pw.print(procState);
13422            pw.print(" trm:");
13423            if (r.trimMemoryLevel < 10) pw.print(' ');
13424            pw.print(r.trimMemoryLevel);
13425            pw.print(' ');
13426            pw.print(r.toShortString());
13427            pw.print(" (");
13428            pw.print(r.adjType);
13429            pw.println(')');
13430            if (r.adjSource != null || r.adjTarget != null) {
13431                pw.print(prefix);
13432                pw.print("    ");
13433                if (r.adjTarget instanceof ComponentName) {
13434                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13435                } else if (r.adjTarget != null) {
13436                    pw.print(r.adjTarget.toString());
13437                } else {
13438                    pw.print("{null}");
13439                }
13440                pw.print("<=");
13441                if (r.adjSource instanceof ProcessRecord) {
13442                    pw.print("Proc{");
13443                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13444                    pw.println("}");
13445                } else if (r.adjSource != null) {
13446                    pw.println(r.adjSource.toString());
13447                } else {
13448                    pw.println("{null}");
13449                }
13450            }
13451            if (inclDetails) {
13452                pw.print(prefix);
13453                pw.print("    ");
13454                pw.print("oom: max="); pw.print(r.maxAdj);
13455                pw.print(" curRaw="); pw.print(r.curRawAdj);
13456                pw.print(" setRaw="); pw.print(r.setRawAdj);
13457                pw.print(" cur="); pw.print(r.curAdj);
13458                pw.print(" set="); pw.println(r.setAdj);
13459                pw.print(prefix);
13460                pw.print("    ");
13461                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13462                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13463                pw.print(" lastPss="); pw.print(r.lastPss);
13464                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13465                pw.print(prefix);
13466                pw.print("    ");
13467                pw.print("cached="); pw.print(r.cached);
13468                pw.print(" empty="); pw.print(r.empty);
13469                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13470
13471                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13472                    if (r.lastWakeTime != 0) {
13473                        long wtime;
13474                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13475                        synchronized (stats) {
13476                            wtime = stats.getProcessWakeTime(r.info.uid,
13477                                    r.pid, curRealtime);
13478                        }
13479                        long timeUsed = wtime - r.lastWakeTime;
13480                        pw.print(prefix);
13481                        pw.print("    ");
13482                        pw.print("keep awake over ");
13483                        TimeUtils.formatDuration(realtimeSince, pw);
13484                        pw.print(" used ");
13485                        TimeUtils.formatDuration(timeUsed, pw);
13486                        pw.print(" (");
13487                        pw.print((timeUsed*100)/realtimeSince);
13488                        pw.println("%)");
13489                    }
13490                    if (r.lastCpuTime != 0) {
13491                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13492                        pw.print(prefix);
13493                        pw.print("    ");
13494                        pw.print("run cpu over ");
13495                        TimeUtils.formatDuration(uptimeSince, pw);
13496                        pw.print(" used ");
13497                        TimeUtils.formatDuration(timeUsed, pw);
13498                        pw.print(" (");
13499                        pw.print((timeUsed*100)/uptimeSince);
13500                        pw.println("%)");
13501                    }
13502                }
13503            }
13504        }
13505        return true;
13506    }
13507
13508    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13509            String[] args) {
13510        ArrayList<ProcessRecord> procs;
13511        synchronized (this) {
13512            if (args != null && args.length > start
13513                    && args[start].charAt(0) != '-') {
13514                procs = new ArrayList<ProcessRecord>();
13515                int pid = -1;
13516                try {
13517                    pid = Integer.parseInt(args[start]);
13518                } catch (NumberFormatException e) {
13519                }
13520                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13521                    ProcessRecord proc = mLruProcesses.get(i);
13522                    if (proc.pid == pid) {
13523                        procs.add(proc);
13524                    } else if (allPkgs && proc.pkgList != null
13525                            && proc.pkgList.containsKey(args[start])) {
13526                        procs.add(proc);
13527                    } else if (proc.processName.equals(args[start])) {
13528                        procs.add(proc);
13529                    }
13530                }
13531                if (procs.size() <= 0) {
13532                    return null;
13533                }
13534            } else {
13535                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13536            }
13537        }
13538        return procs;
13539    }
13540
13541    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13542            PrintWriter pw, String[] args) {
13543        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13544        if (procs == null) {
13545            pw.println("No process found for: " + args[0]);
13546            return;
13547        }
13548
13549        long uptime = SystemClock.uptimeMillis();
13550        long realtime = SystemClock.elapsedRealtime();
13551        pw.println("Applications Graphics Acceleration Info:");
13552        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13553
13554        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13555            ProcessRecord r = procs.get(i);
13556            if (r.thread != null) {
13557                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13558                pw.flush();
13559                try {
13560                    TransferPipe tp = new TransferPipe();
13561                    try {
13562                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13563                        tp.go(fd);
13564                    } finally {
13565                        tp.kill();
13566                    }
13567                } catch (IOException e) {
13568                    pw.println("Failure while dumping the app: " + r);
13569                    pw.flush();
13570                } catch (RemoteException e) {
13571                    pw.println("Got a RemoteException while dumping the app " + r);
13572                    pw.flush();
13573                }
13574            }
13575        }
13576    }
13577
13578    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13579        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13580        if (procs == null) {
13581            pw.println("No process found for: " + args[0]);
13582            return;
13583        }
13584
13585        pw.println("Applications Database Info:");
13586
13587        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13588            ProcessRecord r = procs.get(i);
13589            if (r.thread != null) {
13590                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13591                pw.flush();
13592                try {
13593                    TransferPipe tp = new TransferPipe();
13594                    try {
13595                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13596                        tp.go(fd);
13597                    } finally {
13598                        tp.kill();
13599                    }
13600                } catch (IOException e) {
13601                    pw.println("Failure while dumping the app: " + r);
13602                    pw.flush();
13603                } catch (RemoteException e) {
13604                    pw.println("Got a RemoteException while dumping the app " + r);
13605                    pw.flush();
13606                }
13607            }
13608        }
13609    }
13610
13611    final static class MemItem {
13612        final boolean isProc;
13613        final String label;
13614        final String shortLabel;
13615        final long pss;
13616        final int id;
13617        final boolean hasActivities;
13618        ArrayList<MemItem> subitems;
13619
13620        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13621                boolean _hasActivities) {
13622            isProc = true;
13623            label = _label;
13624            shortLabel = _shortLabel;
13625            pss = _pss;
13626            id = _id;
13627            hasActivities = _hasActivities;
13628        }
13629
13630        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13631            isProc = false;
13632            label = _label;
13633            shortLabel = _shortLabel;
13634            pss = _pss;
13635            id = _id;
13636            hasActivities = false;
13637        }
13638    }
13639
13640    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13641            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13642        if (sort && !isCompact) {
13643            Collections.sort(items, new Comparator<MemItem>() {
13644                @Override
13645                public int compare(MemItem lhs, MemItem rhs) {
13646                    if (lhs.pss < rhs.pss) {
13647                        return 1;
13648                    } else if (lhs.pss > rhs.pss) {
13649                        return -1;
13650                    }
13651                    return 0;
13652                }
13653            });
13654        }
13655
13656        for (int i=0; i<items.size(); i++) {
13657            MemItem mi = items.get(i);
13658            if (!isCompact) {
13659                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13660            } else if (mi.isProc) {
13661                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13662                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13663                pw.println(mi.hasActivities ? ",a" : ",e");
13664            } else {
13665                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13666                pw.println(mi.pss);
13667            }
13668            if (mi.subitems != null) {
13669                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13670                        true, isCompact);
13671            }
13672        }
13673    }
13674
13675    // These are in KB.
13676    static final long[] DUMP_MEM_BUCKETS = new long[] {
13677        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13678        120*1024, 160*1024, 200*1024,
13679        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13680        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13681    };
13682
13683    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13684            boolean stackLike) {
13685        int start = label.lastIndexOf('.');
13686        if (start >= 0) start++;
13687        else start = 0;
13688        int end = label.length();
13689        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13690            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13691                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13692                out.append(bucket);
13693                out.append(stackLike ? "MB." : "MB ");
13694                out.append(label, start, end);
13695                return;
13696            }
13697        }
13698        out.append(memKB/1024);
13699        out.append(stackLike ? "MB." : "MB ");
13700        out.append(label, start, end);
13701    }
13702
13703    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13704            ProcessList.NATIVE_ADJ,
13705            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13706            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13707            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13708            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13709            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13710            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13711    };
13712    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13713            "Native",
13714            "System", "Persistent", "Persistent Service", "Foreground",
13715            "Visible", "Perceptible",
13716            "Heavy Weight", "Backup",
13717            "A Services", "Home",
13718            "Previous", "B Services", "Cached"
13719    };
13720    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13721            "native",
13722            "sys", "pers", "persvc", "fore",
13723            "vis", "percept",
13724            "heavy", "backup",
13725            "servicea", "home",
13726            "prev", "serviceb", "cached"
13727    };
13728
13729    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13730            long realtime, boolean isCheckinRequest, boolean isCompact) {
13731        if (isCheckinRequest || isCompact) {
13732            // short checkin version
13733            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13734        } else {
13735            pw.println("Applications Memory Usage (kB):");
13736            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13737        }
13738    }
13739
13740    private static final int KSM_SHARED = 0;
13741    private static final int KSM_SHARING = 1;
13742    private static final int KSM_UNSHARED = 2;
13743    private static final int KSM_VOLATILE = 3;
13744
13745    private final long[] getKsmInfo() {
13746        long[] longOut = new long[4];
13747        final int[] SINGLE_LONG_FORMAT = new int[] {
13748            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13749        };
13750        long[] longTmp = new long[1];
13751        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13752                SINGLE_LONG_FORMAT, null, longTmp, null);
13753        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13754        longTmp[0] = 0;
13755        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13756                SINGLE_LONG_FORMAT, null, longTmp, null);
13757        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13758        longTmp[0] = 0;
13759        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13760                SINGLE_LONG_FORMAT, null, longTmp, null);
13761        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13762        longTmp[0] = 0;
13763        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13764                SINGLE_LONG_FORMAT, null, longTmp, null);
13765        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13766        return longOut;
13767    }
13768
13769    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13770            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13771        boolean dumpDetails = false;
13772        boolean dumpFullDetails = false;
13773        boolean dumpDalvik = false;
13774        boolean oomOnly = false;
13775        boolean isCompact = false;
13776        boolean localOnly = false;
13777        boolean packages = false;
13778
13779        int opti = 0;
13780        while (opti < args.length) {
13781            String opt = args[opti];
13782            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13783                break;
13784            }
13785            opti++;
13786            if ("-a".equals(opt)) {
13787                dumpDetails = true;
13788                dumpFullDetails = true;
13789                dumpDalvik = true;
13790            } else if ("-d".equals(opt)) {
13791                dumpDalvik = true;
13792            } else if ("-c".equals(opt)) {
13793                isCompact = true;
13794            } else if ("--oom".equals(opt)) {
13795                oomOnly = true;
13796            } else if ("--local".equals(opt)) {
13797                localOnly = true;
13798            } else if ("--package".equals(opt)) {
13799                packages = true;
13800            } else if ("-h".equals(opt)) {
13801                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13802                pw.println("  -a: include all available information for each process.");
13803                pw.println("  -d: include dalvik details when dumping process details.");
13804                pw.println("  -c: dump in a compact machine-parseable representation.");
13805                pw.println("  --oom: only show processes organized by oom adj.");
13806                pw.println("  --local: only collect details locally, don't call process.");
13807                pw.println("  --package: interpret process arg as package, dumping all");
13808                pw.println("             processes that have loaded that package.");
13809                pw.println("If [process] is specified it can be the name or ");
13810                pw.println("pid of a specific process to dump.");
13811                return;
13812            } else {
13813                pw.println("Unknown argument: " + opt + "; use -h for help");
13814            }
13815        }
13816
13817        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13818        long uptime = SystemClock.uptimeMillis();
13819        long realtime = SystemClock.elapsedRealtime();
13820        final long[] tmpLong = new long[1];
13821
13822        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13823        if (procs == null) {
13824            // No Java processes.  Maybe they want to print a native process.
13825            if (args != null && args.length > opti
13826                    && args[opti].charAt(0) != '-') {
13827                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13828                        = new ArrayList<ProcessCpuTracker.Stats>();
13829                updateCpuStatsNow();
13830                int findPid = -1;
13831                try {
13832                    findPid = Integer.parseInt(args[opti]);
13833                } catch (NumberFormatException e) {
13834                }
13835                synchronized (mProcessCpuTracker) {
13836                    final int N = mProcessCpuTracker.countStats();
13837                    for (int i=0; i<N; i++) {
13838                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13839                        if (st.pid == findPid || (st.baseName != null
13840                                && st.baseName.equals(args[opti]))) {
13841                            nativeProcs.add(st);
13842                        }
13843                    }
13844                }
13845                if (nativeProcs.size() > 0) {
13846                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13847                            isCompact);
13848                    Debug.MemoryInfo mi = null;
13849                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13850                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13851                        final int pid = r.pid;
13852                        if (!isCheckinRequest && dumpDetails) {
13853                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13854                        }
13855                        if (mi == null) {
13856                            mi = new Debug.MemoryInfo();
13857                        }
13858                        if (dumpDetails || (!brief && !oomOnly)) {
13859                            Debug.getMemoryInfo(pid, mi);
13860                        } else {
13861                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13862                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13863                        }
13864                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13865                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13866                        if (isCheckinRequest) {
13867                            pw.println();
13868                        }
13869                    }
13870                    return;
13871                }
13872            }
13873            pw.println("No process found for: " + args[opti]);
13874            return;
13875        }
13876
13877        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13878            dumpDetails = true;
13879        }
13880
13881        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13882
13883        String[] innerArgs = new String[args.length-opti];
13884        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13885
13886        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13887        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13888        long nativePss=0, dalvikPss=0, otherPss=0;
13889        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13890
13891        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13892        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13893                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13894
13895        long totalPss = 0;
13896        long cachedPss = 0;
13897
13898        Debug.MemoryInfo mi = null;
13899        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13900            final ProcessRecord r = procs.get(i);
13901            final IApplicationThread thread;
13902            final int pid;
13903            final int oomAdj;
13904            final boolean hasActivities;
13905            synchronized (this) {
13906                thread = r.thread;
13907                pid = r.pid;
13908                oomAdj = r.getSetAdjWithServices();
13909                hasActivities = r.activities.size() > 0;
13910            }
13911            if (thread != null) {
13912                if (!isCheckinRequest && dumpDetails) {
13913                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13914                }
13915                if (mi == null) {
13916                    mi = new Debug.MemoryInfo();
13917                }
13918                if (dumpDetails || (!brief && !oomOnly)) {
13919                    Debug.getMemoryInfo(pid, mi);
13920                } else {
13921                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13922                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13923                }
13924                if (dumpDetails) {
13925                    if (localOnly) {
13926                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13927                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13928                        if (isCheckinRequest) {
13929                            pw.println();
13930                        }
13931                    } else {
13932                        try {
13933                            pw.flush();
13934                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13935                                    dumpDalvik, innerArgs);
13936                        } catch (RemoteException e) {
13937                            if (!isCheckinRequest) {
13938                                pw.println("Got RemoteException!");
13939                                pw.flush();
13940                            }
13941                        }
13942                    }
13943                }
13944
13945                final long myTotalPss = mi.getTotalPss();
13946                final long myTotalUss = mi.getTotalUss();
13947
13948                synchronized (this) {
13949                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13950                        // Record this for posterity if the process has been stable.
13951                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13952                    }
13953                }
13954
13955                if (!isCheckinRequest && mi != null) {
13956                    totalPss += myTotalPss;
13957                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13958                            (hasActivities ? " / activities)" : ")"),
13959                            r.processName, myTotalPss, pid, hasActivities);
13960                    procMems.add(pssItem);
13961                    procMemsMap.put(pid, pssItem);
13962
13963                    nativePss += mi.nativePss;
13964                    dalvikPss += mi.dalvikPss;
13965                    otherPss += mi.otherPss;
13966                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13967                        long mem = mi.getOtherPss(j);
13968                        miscPss[j] += mem;
13969                        otherPss -= mem;
13970                    }
13971
13972                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13973                        cachedPss += myTotalPss;
13974                    }
13975
13976                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13977                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13978                                || oomIndex == (oomPss.length-1)) {
13979                            oomPss[oomIndex] += myTotalPss;
13980                            if (oomProcs[oomIndex] == null) {
13981                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13982                            }
13983                            oomProcs[oomIndex].add(pssItem);
13984                            break;
13985                        }
13986                    }
13987                }
13988            }
13989        }
13990
13991        long nativeProcTotalPss = 0;
13992
13993        if (!isCheckinRequest && procs.size() > 1 && !packages) {
13994            // If we are showing aggregations, also look for native processes to
13995            // include so that our aggregations are more accurate.
13996            updateCpuStatsNow();
13997            synchronized (mProcessCpuTracker) {
13998                final int N = mProcessCpuTracker.countStats();
13999                for (int i=0; i<N; i++) {
14000                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14001                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14002                        if (mi == null) {
14003                            mi = new Debug.MemoryInfo();
14004                        }
14005                        if (!brief && !oomOnly) {
14006                            Debug.getMemoryInfo(st.pid, mi);
14007                        } else {
14008                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14009                            mi.nativePrivateDirty = (int)tmpLong[0];
14010                        }
14011
14012                        final long myTotalPss = mi.getTotalPss();
14013                        totalPss += myTotalPss;
14014                        nativeProcTotalPss += myTotalPss;
14015
14016                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14017                                st.name, myTotalPss, st.pid, false);
14018                        procMems.add(pssItem);
14019
14020                        nativePss += mi.nativePss;
14021                        dalvikPss += mi.dalvikPss;
14022                        otherPss += mi.otherPss;
14023                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14024                            long mem = mi.getOtherPss(j);
14025                            miscPss[j] += mem;
14026                            otherPss -= mem;
14027                        }
14028                        oomPss[0] += myTotalPss;
14029                        if (oomProcs[0] == null) {
14030                            oomProcs[0] = new ArrayList<MemItem>();
14031                        }
14032                        oomProcs[0].add(pssItem);
14033                    }
14034                }
14035            }
14036
14037            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14038
14039            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14040            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14041            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14042            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14043                String label = Debug.MemoryInfo.getOtherLabel(j);
14044                catMems.add(new MemItem(label, label, miscPss[j], j));
14045            }
14046
14047            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14048            for (int j=0; j<oomPss.length; j++) {
14049                if (oomPss[j] != 0) {
14050                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14051                            : DUMP_MEM_OOM_LABEL[j];
14052                    MemItem item = new MemItem(label, label, oomPss[j],
14053                            DUMP_MEM_OOM_ADJ[j]);
14054                    item.subitems = oomProcs[j];
14055                    oomMems.add(item);
14056                }
14057            }
14058
14059            if (!brief && !oomOnly && !isCompact) {
14060                pw.println();
14061                pw.println("Total PSS by process:");
14062                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14063                pw.println();
14064            }
14065            if (!isCompact) {
14066                pw.println("Total PSS by OOM adjustment:");
14067            }
14068            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14069            if (!brief && !oomOnly) {
14070                PrintWriter out = categoryPw != null ? categoryPw : pw;
14071                if (!isCompact) {
14072                    out.println();
14073                    out.println("Total PSS by category:");
14074                }
14075                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14076            }
14077            if (!isCompact) {
14078                pw.println();
14079            }
14080            MemInfoReader memInfo = new MemInfoReader();
14081            memInfo.readMemInfo();
14082            if (nativeProcTotalPss > 0) {
14083                synchronized (this) {
14084                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14085                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14086                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14087                }
14088            }
14089            if (!brief) {
14090                if (!isCompact) {
14091                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14092                    pw.print(" kB (status ");
14093                    switch (mLastMemoryLevel) {
14094                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14095                            pw.println("normal)");
14096                            break;
14097                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14098                            pw.println("moderate)");
14099                            break;
14100                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14101                            pw.println("low)");
14102                            break;
14103                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14104                            pw.println("critical)");
14105                            break;
14106                        default:
14107                            pw.print(mLastMemoryLevel);
14108                            pw.println(")");
14109                            break;
14110                    }
14111                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14112                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14113                            pw.print(cachedPss); pw.print(" cached pss + ");
14114                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14115                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14116                } else {
14117                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14118                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14119                            + memInfo.getFreeSizeKb()); pw.print(",");
14120                    pw.println(totalPss - cachedPss);
14121                }
14122            }
14123            if (!isCompact) {
14124                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14125                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14126                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14127                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14128                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14129                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14130                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14131            }
14132            if (!brief) {
14133                if (memInfo.getZramTotalSizeKb() != 0) {
14134                    if (!isCompact) {
14135                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14136                                pw.print(" kB physical used for ");
14137                                pw.print(memInfo.getSwapTotalSizeKb()
14138                                        - memInfo.getSwapFreeSizeKb());
14139                                pw.print(" kB in swap (");
14140                                pw.print(memInfo.getSwapTotalSizeKb());
14141                                pw.println(" kB total swap)");
14142                    } else {
14143                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14144                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14145                                pw.println(memInfo.getSwapFreeSizeKb());
14146                    }
14147                }
14148                final long[] ksm = getKsmInfo();
14149                if (!isCompact) {
14150                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14151                            || ksm[KSM_VOLATILE] != 0) {
14152                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14153                                pw.print(" kB saved from shared ");
14154                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14155                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14156                                pw.print(" kB unshared; ");
14157                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14158                    }
14159                    pw.print("   Tuning: ");
14160                    pw.print(ActivityManager.staticGetMemoryClass());
14161                    pw.print(" (large ");
14162                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14163                    pw.print("), oom ");
14164                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14165                    pw.print(" kB");
14166                    pw.print(", restore limit ");
14167                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14168                    pw.print(" kB");
14169                    if (ActivityManager.isLowRamDeviceStatic()) {
14170                        pw.print(" (low-ram)");
14171                    }
14172                    if (ActivityManager.isHighEndGfx()) {
14173                        pw.print(" (high-end-gfx)");
14174                    }
14175                    pw.println();
14176                } else {
14177                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14178                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14179                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14180                    pw.print("tuning,");
14181                    pw.print(ActivityManager.staticGetMemoryClass());
14182                    pw.print(',');
14183                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14184                    pw.print(',');
14185                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14186                    if (ActivityManager.isLowRamDeviceStatic()) {
14187                        pw.print(",low-ram");
14188                    }
14189                    if (ActivityManager.isHighEndGfx()) {
14190                        pw.print(",high-end-gfx");
14191                    }
14192                    pw.println();
14193                }
14194            }
14195        }
14196    }
14197
14198    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14199            String name) {
14200        sb.append("  ");
14201        sb.append(ProcessList.makeOomAdjString(oomAdj));
14202        sb.append(' ');
14203        sb.append(ProcessList.makeProcStateString(procState));
14204        sb.append(' ');
14205        ProcessList.appendRamKb(sb, pss);
14206        sb.append(" kB: ");
14207        sb.append(name);
14208    }
14209
14210    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14211        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14212        sb.append(" (");
14213        sb.append(mi.pid);
14214        sb.append(") ");
14215        sb.append(mi.adjType);
14216        sb.append('\n');
14217        if (mi.adjReason != null) {
14218            sb.append("                      ");
14219            sb.append(mi.adjReason);
14220            sb.append('\n');
14221        }
14222    }
14223
14224    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14225        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14226        for (int i=0, N=memInfos.size(); i<N; i++) {
14227            ProcessMemInfo mi = memInfos.get(i);
14228            infoMap.put(mi.pid, mi);
14229        }
14230        updateCpuStatsNow();
14231        synchronized (mProcessCpuTracker) {
14232            final int N = mProcessCpuTracker.countStats();
14233            for (int i=0; i<N; i++) {
14234                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14235                if (st.vsize > 0) {
14236                    long pss = Debug.getPss(st.pid, null);
14237                    if (pss > 0) {
14238                        if (infoMap.indexOfKey(st.pid) < 0) {
14239                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14240                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14241                            mi.pss = pss;
14242                            memInfos.add(mi);
14243                        }
14244                    }
14245                }
14246            }
14247        }
14248
14249        long totalPss = 0;
14250        for (int i=0, N=memInfos.size(); i<N; i++) {
14251            ProcessMemInfo mi = memInfos.get(i);
14252            if (mi.pss == 0) {
14253                mi.pss = Debug.getPss(mi.pid, null);
14254            }
14255            totalPss += mi.pss;
14256        }
14257        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14258            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14259                if (lhs.oomAdj != rhs.oomAdj) {
14260                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14261                }
14262                if (lhs.pss != rhs.pss) {
14263                    return lhs.pss < rhs.pss ? 1 : -1;
14264                }
14265                return 0;
14266            }
14267        });
14268
14269        StringBuilder tag = new StringBuilder(128);
14270        StringBuilder stack = new StringBuilder(128);
14271        tag.append("Low on memory -- ");
14272        appendMemBucket(tag, totalPss, "total", false);
14273        appendMemBucket(stack, totalPss, "total", true);
14274
14275        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14276        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14277        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14278
14279        boolean firstLine = true;
14280        int lastOomAdj = Integer.MIN_VALUE;
14281        long extraNativeRam = 0;
14282        long cachedPss = 0;
14283        for (int i=0, N=memInfos.size(); i<N; i++) {
14284            ProcessMemInfo mi = memInfos.get(i);
14285
14286            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14287                cachedPss += mi.pss;
14288            }
14289
14290            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14291                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14292                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14293                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14294                if (lastOomAdj != mi.oomAdj) {
14295                    lastOomAdj = mi.oomAdj;
14296                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14297                        tag.append(" / ");
14298                    }
14299                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14300                        if (firstLine) {
14301                            stack.append(":");
14302                            firstLine = false;
14303                        }
14304                        stack.append("\n\t at ");
14305                    } else {
14306                        stack.append("$");
14307                    }
14308                } else {
14309                    tag.append(" ");
14310                    stack.append("$");
14311                }
14312                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14313                    appendMemBucket(tag, mi.pss, mi.name, false);
14314                }
14315                appendMemBucket(stack, mi.pss, mi.name, true);
14316                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14317                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14318                    stack.append("(");
14319                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14320                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14321                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14322                            stack.append(":");
14323                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14324                        }
14325                    }
14326                    stack.append(")");
14327                }
14328            }
14329
14330            appendMemInfo(fullNativeBuilder, mi);
14331            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14332                // The short form only has native processes that are >= 1MB.
14333                if (mi.pss >= 1000) {
14334                    appendMemInfo(shortNativeBuilder, mi);
14335                } else {
14336                    extraNativeRam += mi.pss;
14337                }
14338            } else {
14339                // Short form has all other details, but if we have collected RAM
14340                // from smaller native processes let's dump a summary of that.
14341                if (extraNativeRam > 0) {
14342                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14343                            -1, extraNativeRam, "(Other native)");
14344                    shortNativeBuilder.append('\n');
14345                    extraNativeRam = 0;
14346                }
14347                appendMemInfo(fullJavaBuilder, mi);
14348            }
14349        }
14350
14351        fullJavaBuilder.append("           ");
14352        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14353        fullJavaBuilder.append(" kB: TOTAL\n");
14354
14355        MemInfoReader memInfo = new MemInfoReader();
14356        memInfo.readMemInfo();
14357        final long[] infos = memInfo.getRawInfo();
14358
14359        StringBuilder memInfoBuilder = new StringBuilder(1024);
14360        Debug.getMemInfo(infos);
14361        memInfoBuilder.append("  MemInfo: ");
14362        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14363        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14364        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14365        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14366        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14367        memInfoBuilder.append("           ");
14368        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14369        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14370        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14371        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14372        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14373            memInfoBuilder.append("  ZRAM: ");
14374            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14375            memInfoBuilder.append(" kB RAM, ");
14376            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14377            memInfoBuilder.append(" kB swap total, ");
14378            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14379            memInfoBuilder.append(" kB swap free\n");
14380        }
14381        final long[] ksm = getKsmInfo();
14382        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14383                || ksm[KSM_VOLATILE] != 0) {
14384            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14385            memInfoBuilder.append(" kB saved from shared ");
14386            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14387            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14388            memInfoBuilder.append(" kB unshared; ");
14389            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14390        }
14391        memInfoBuilder.append("  Free RAM: ");
14392        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14393                + memInfo.getFreeSizeKb());
14394        memInfoBuilder.append(" kB\n");
14395        memInfoBuilder.append("  Used RAM: ");
14396        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14397        memInfoBuilder.append(" kB\n");
14398        memInfoBuilder.append("  Lost RAM: ");
14399        memInfoBuilder.append(memInfo.getTotalSizeKb()
14400                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14401                - memInfo.getKernelUsedSizeKb());
14402        memInfoBuilder.append(" kB\n");
14403        Slog.i(TAG, "Low on memory:");
14404        Slog.i(TAG, shortNativeBuilder.toString());
14405        Slog.i(TAG, fullJavaBuilder.toString());
14406        Slog.i(TAG, memInfoBuilder.toString());
14407
14408        StringBuilder dropBuilder = new StringBuilder(1024);
14409        /*
14410        StringWriter oomSw = new StringWriter();
14411        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14412        StringWriter catSw = new StringWriter();
14413        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14414        String[] emptyArgs = new String[] { };
14415        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14416        oomPw.flush();
14417        String oomString = oomSw.toString();
14418        */
14419        dropBuilder.append("Low on memory:");
14420        dropBuilder.append(stack);
14421        dropBuilder.append('\n');
14422        dropBuilder.append(fullNativeBuilder);
14423        dropBuilder.append(fullJavaBuilder);
14424        dropBuilder.append('\n');
14425        dropBuilder.append(memInfoBuilder);
14426        dropBuilder.append('\n');
14427        /*
14428        dropBuilder.append(oomString);
14429        dropBuilder.append('\n');
14430        */
14431        StringWriter catSw = new StringWriter();
14432        synchronized (ActivityManagerService.this) {
14433            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14434            String[] emptyArgs = new String[] { };
14435            catPw.println();
14436            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14437            catPw.println();
14438            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14439                    false, false, null);
14440            catPw.println();
14441            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14442            catPw.flush();
14443        }
14444        dropBuilder.append(catSw.toString());
14445        addErrorToDropBox("lowmem", null, "system_server", null,
14446                null, tag.toString(), dropBuilder.toString(), null, null);
14447        //Slog.i(TAG, "Sent to dropbox:");
14448        //Slog.i(TAG, dropBuilder.toString());
14449        synchronized (ActivityManagerService.this) {
14450            long now = SystemClock.uptimeMillis();
14451            if (mLastMemUsageReportTime < now) {
14452                mLastMemUsageReportTime = now;
14453            }
14454        }
14455    }
14456
14457    /**
14458     * Searches array of arguments for the specified string
14459     * @param args array of argument strings
14460     * @param value value to search for
14461     * @return true if the value is contained in the array
14462     */
14463    private static boolean scanArgs(String[] args, String value) {
14464        if (args != null) {
14465            for (String arg : args) {
14466                if (value.equals(arg)) {
14467                    return true;
14468                }
14469            }
14470        }
14471        return false;
14472    }
14473
14474    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14475            ContentProviderRecord cpr, boolean always) {
14476        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14477
14478        if (!inLaunching || always) {
14479            synchronized (cpr) {
14480                cpr.launchingApp = null;
14481                cpr.notifyAll();
14482            }
14483            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14484            String names[] = cpr.info.authority.split(";");
14485            for (int j = 0; j < names.length; j++) {
14486                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14487            }
14488        }
14489
14490        for (int i=0; i<cpr.connections.size(); i++) {
14491            ContentProviderConnection conn = cpr.connections.get(i);
14492            if (conn.waiting) {
14493                // If this connection is waiting for the provider, then we don't
14494                // need to mess with its process unless we are always removing
14495                // or for some reason the provider is not currently launching.
14496                if (inLaunching && !always) {
14497                    continue;
14498                }
14499            }
14500            ProcessRecord capp = conn.client;
14501            conn.dead = true;
14502            if (conn.stableCount > 0) {
14503                if (!capp.persistent && capp.thread != null
14504                        && capp.pid != 0
14505                        && capp.pid != MY_PID) {
14506                    capp.kill("depends on provider "
14507                            + cpr.name.flattenToShortString()
14508                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14509                }
14510            } else if (capp.thread != null && conn.provider.provider != null) {
14511                try {
14512                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14513                } catch (RemoteException e) {
14514                }
14515                // In the protocol here, we don't expect the client to correctly
14516                // clean up this connection, we'll just remove it.
14517                cpr.connections.remove(i);
14518                conn.client.conProviders.remove(conn);
14519            }
14520        }
14521
14522        if (inLaunching && always) {
14523            mLaunchingProviders.remove(cpr);
14524        }
14525        return inLaunching;
14526    }
14527
14528    /**
14529     * Main code for cleaning up a process when it has gone away.  This is
14530     * called both as a result of the process dying, or directly when stopping
14531     * a process when running in single process mode.
14532     *
14533     * @return Returns true if the given process has been restarted, so the
14534     * app that was passed in must remain on the process lists.
14535     */
14536    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14537            boolean restarting, boolean allowRestart, int index) {
14538        if (index >= 0) {
14539            removeLruProcessLocked(app);
14540            ProcessList.remove(app.pid);
14541        }
14542
14543        mProcessesToGc.remove(app);
14544        mPendingPssProcesses.remove(app);
14545
14546        // Dismiss any open dialogs.
14547        if (app.crashDialog != null && !app.forceCrashReport) {
14548            app.crashDialog.dismiss();
14549            app.crashDialog = null;
14550        }
14551        if (app.anrDialog != null) {
14552            app.anrDialog.dismiss();
14553            app.anrDialog = null;
14554        }
14555        if (app.waitDialog != null) {
14556            app.waitDialog.dismiss();
14557            app.waitDialog = null;
14558        }
14559
14560        app.crashing = false;
14561        app.notResponding = false;
14562
14563        app.resetPackageList(mProcessStats);
14564        app.unlinkDeathRecipient();
14565        app.makeInactive(mProcessStats);
14566        app.waitingToKill = null;
14567        app.forcingToForeground = null;
14568        updateProcessForegroundLocked(app, false, false);
14569        app.foregroundActivities = false;
14570        app.hasShownUi = false;
14571        app.treatLikeActivity = false;
14572        app.hasAboveClient = false;
14573        app.hasClientActivities = false;
14574
14575        mServices.killServicesLocked(app, allowRestart);
14576
14577        boolean restart = false;
14578
14579        // Remove published content providers.
14580        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14581            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14582            final boolean always = app.bad || !allowRestart;
14583            if (removeDyingProviderLocked(app, cpr, always) || always) {
14584                // We left the provider in the launching list, need to
14585                // restart it.
14586                restart = true;
14587            }
14588
14589            cpr.provider = null;
14590            cpr.proc = null;
14591        }
14592        app.pubProviders.clear();
14593
14594        // Take care of any launching providers waiting for this process.
14595        if (checkAppInLaunchingProvidersLocked(app, false)) {
14596            restart = true;
14597        }
14598
14599        // Unregister from connected content providers.
14600        if (!app.conProviders.isEmpty()) {
14601            for (int i=0; i<app.conProviders.size(); i++) {
14602                ContentProviderConnection conn = app.conProviders.get(i);
14603                conn.provider.connections.remove(conn);
14604            }
14605            app.conProviders.clear();
14606        }
14607
14608        // At this point there may be remaining entries in mLaunchingProviders
14609        // where we were the only one waiting, so they are no longer of use.
14610        // Look for these and clean up if found.
14611        // XXX Commented out for now.  Trying to figure out a way to reproduce
14612        // the actual situation to identify what is actually going on.
14613        if (false) {
14614            for (int i=0; i<mLaunchingProviders.size(); i++) {
14615                ContentProviderRecord cpr = (ContentProviderRecord)
14616                        mLaunchingProviders.get(i);
14617                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14618                    synchronized (cpr) {
14619                        cpr.launchingApp = null;
14620                        cpr.notifyAll();
14621                    }
14622                }
14623            }
14624        }
14625
14626        skipCurrentReceiverLocked(app);
14627
14628        // Unregister any receivers.
14629        for (int i=app.receivers.size()-1; i>=0; i--) {
14630            removeReceiverLocked(app.receivers.valueAt(i));
14631        }
14632        app.receivers.clear();
14633
14634        // If the app is undergoing backup, tell the backup manager about it
14635        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14636            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14637                    + mBackupTarget.appInfo + " died during backup");
14638            try {
14639                IBackupManager bm = IBackupManager.Stub.asInterface(
14640                        ServiceManager.getService(Context.BACKUP_SERVICE));
14641                bm.agentDisconnected(app.info.packageName);
14642            } catch (RemoteException e) {
14643                // can't happen; backup manager is local
14644            }
14645        }
14646
14647        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14648            ProcessChangeItem item = mPendingProcessChanges.get(i);
14649            if (item.pid == app.pid) {
14650                mPendingProcessChanges.remove(i);
14651                mAvailProcessChanges.add(item);
14652            }
14653        }
14654        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14655
14656        // If the caller is restarting this app, then leave it in its
14657        // current lists and let the caller take care of it.
14658        if (restarting) {
14659            return false;
14660        }
14661
14662        if (!app.persistent || app.isolated) {
14663            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14664                    "Removing non-persistent process during cleanup: " + app);
14665            mProcessNames.remove(app.processName, app.uid);
14666            mIsolatedProcesses.remove(app.uid);
14667            if (mHeavyWeightProcess == app) {
14668                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14669                        mHeavyWeightProcess.userId, 0));
14670                mHeavyWeightProcess = null;
14671            }
14672        } else if (!app.removed) {
14673            // This app is persistent, so we need to keep its record around.
14674            // If it is not already on the pending app list, add it there
14675            // and start a new process for it.
14676            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14677                mPersistentStartingProcesses.add(app);
14678                restart = true;
14679            }
14680        }
14681        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14682                "Clean-up removing on hold: " + app);
14683        mProcessesOnHold.remove(app);
14684
14685        if (app == mHomeProcess) {
14686            mHomeProcess = null;
14687        }
14688        if (app == mPreviousProcess) {
14689            mPreviousProcess = null;
14690        }
14691
14692        if (restart && !app.isolated) {
14693            // We have components that still need to be running in the
14694            // process, so re-launch it.
14695            if (index < 0) {
14696                ProcessList.remove(app.pid);
14697            }
14698            mProcessNames.put(app.processName, app.uid, app);
14699            startProcessLocked(app, "restart", app.processName);
14700            return true;
14701        } else if (app.pid > 0 && app.pid != MY_PID) {
14702            // Goodbye!
14703            boolean removed;
14704            synchronized (mPidsSelfLocked) {
14705                mPidsSelfLocked.remove(app.pid);
14706                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14707            }
14708            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14709            if (app.isolated) {
14710                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14711            }
14712            app.setPid(0);
14713        }
14714        return false;
14715    }
14716
14717    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14718        // Look through the content providers we are waiting to have launched,
14719        // and if any run in this process then either schedule a restart of
14720        // the process or kill the client waiting for it if this process has
14721        // gone bad.
14722        int NL = mLaunchingProviders.size();
14723        boolean restart = false;
14724        for (int i=0; i<NL; i++) {
14725            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14726            if (cpr.launchingApp == app) {
14727                if (!alwaysBad && !app.bad) {
14728                    restart = true;
14729                } else {
14730                    removeDyingProviderLocked(app, cpr, true);
14731                    // cpr should have been removed from mLaunchingProviders
14732                    NL = mLaunchingProviders.size();
14733                    i--;
14734                }
14735            }
14736        }
14737        return restart;
14738    }
14739
14740    // =========================================================
14741    // SERVICES
14742    // =========================================================
14743
14744    @Override
14745    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14746            int flags) {
14747        enforceNotIsolatedCaller("getServices");
14748        synchronized (this) {
14749            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14750        }
14751    }
14752
14753    @Override
14754    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14755        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14756        synchronized (this) {
14757            return mServices.getRunningServiceControlPanelLocked(name);
14758        }
14759    }
14760
14761    @Override
14762    public ComponentName startService(IApplicationThread caller, Intent service,
14763            String resolvedType, int userId) {
14764        enforceNotIsolatedCaller("startService");
14765        // Refuse possible leaked file descriptors
14766        if (service != null && service.hasFileDescriptors() == true) {
14767            throw new IllegalArgumentException("File descriptors passed in Intent");
14768        }
14769
14770        if (DEBUG_SERVICE)
14771            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14772        synchronized(this) {
14773            final int callingPid = Binder.getCallingPid();
14774            final int callingUid = Binder.getCallingUid();
14775            final long origId = Binder.clearCallingIdentity();
14776            ComponentName res = mServices.startServiceLocked(caller, service,
14777                    resolvedType, callingPid, callingUid, userId);
14778            Binder.restoreCallingIdentity(origId);
14779            return res;
14780        }
14781    }
14782
14783    ComponentName startServiceInPackage(int uid,
14784            Intent service, String resolvedType, int userId) {
14785        synchronized(this) {
14786            if (DEBUG_SERVICE)
14787                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14788            final long origId = Binder.clearCallingIdentity();
14789            ComponentName res = mServices.startServiceLocked(null, service,
14790                    resolvedType, -1, uid, userId);
14791            Binder.restoreCallingIdentity(origId);
14792            return res;
14793        }
14794    }
14795
14796    @Override
14797    public int stopService(IApplicationThread caller, Intent service,
14798            String resolvedType, int userId) {
14799        enforceNotIsolatedCaller("stopService");
14800        // Refuse possible leaked file descriptors
14801        if (service != null && service.hasFileDescriptors() == true) {
14802            throw new IllegalArgumentException("File descriptors passed in Intent");
14803        }
14804
14805        synchronized(this) {
14806            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14807        }
14808    }
14809
14810    @Override
14811    public IBinder peekService(Intent service, String resolvedType) {
14812        enforceNotIsolatedCaller("peekService");
14813        // Refuse possible leaked file descriptors
14814        if (service != null && service.hasFileDescriptors() == true) {
14815            throw new IllegalArgumentException("File descriptors passed in Intent");
14816        }
14817        synchronized(this) {
14818            return mServices.peekServiceLocked(service, resolvedType);
14819        }
14820    }
14821
14822    @Override
14823    public boolean stopServiceToken(ComponentName className, IBinder token,
14824            int startId) {
14825        synchronized(this) {
14826            return mServices.stopServiceTokenLocked(className, token, startId);
14827        }
14828    }
14829
14830    @Override
14831    public void setServiceForeground(ComponentName className, IBinder token,
14832            int id, Notification notification, boolean removeNotification) {
14833        synchronized(this) {
14834            mServices.setServiceForegroundLocked(className, token, id, notification,
14835                    removeNotification);
14836        }
14837    }
14838
14839    @Override
14840    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14841            boolean requireFull, String name, String callerPackage) {
14842        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14843                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14844    }
14845
14846    int unsafeConvertIncomingUser(int userId) {
14847        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14848                ? mCurrentUserId : userId;
14849    }
14850
14851    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14852            int allowMode, String name, String callerPackage) {
14853        final int callingUserId = UserHandle.getUserId(callingUid);
14854        if (callingUserId == userId) {
14855            return userId;
14856        }
14857
14858        // Note that we may be accessing mCurrentUserId outside of a lock...
14859        // shouldn't be a big deal, if this is being called outside
14860        // of a locked context there is intrinsically a race with
14861        // the value the caller will receive and someone else changing it.
14862        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14863        // we will switch to the calling user if access to the current user fails.
14864        int targetUserId = unsafeConvertIncomingUser(userId);
14865
14866        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14867            final boolean allow;
14868            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14869                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14870                // If the caller has this permission, they always pass go.  And collect $200.
14871                allow = true;
14872            } else if (allowMode == ALLOW_FULL_ONLY) {
14873                // We require full access, sucks to be you.
14874                allow = false;
14875            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14876                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14877                // If the caller does not have either permission, they are always doomed.
14878                allow = false;
14879            } else if (allowMode == ALLOW_NON_FULL) {
14880                // We are blanket allowing non-full access, you lucky caller!
14881                allow = true;
14882            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14883                // We may or may not allow this depending on whether the two users are
14884                // in the same profile.
14885                synchronized (mUserProfileGroupIdsSelfLocked) {
14886                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14887                            UserInfo.NO_PROFILE_GROUP_ID);
14888                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14889                            UserInfo.NO_PROFILE_GROUP_ID);
14890                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14891                            && callingProfile == targetProfile;
14892                }
14893            } else {
14894                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14895            }
14896            if (!allow) {
14897                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14898                    // In this case, they would like to just execute as their
14899                    // owner user instead of failing.
14900                    targetUserId = callingUserId;
14901                } else {
14902                    StringBuilder builder = new StringBuilder(128);
14903                    builder.append("Permission Denial: ");
14904                    builder.append(name);
14905                    if (callerPackage != null) {
14906                        builder.append(" from ");
14907                        builder.append(callerPackage);
14908                    }
14909                    builder.append(" asks to run as user ");
14910                    builder.append(userId);
14911                    builder.append(" but is calling from user ");
14912                    builder.append(UserHandle.getUserId(callingUid));
14913                    builder.append("; this requires ");
14914                    builder.append(INTERACT_ACROSS_USERS_FULL);
14915                    if (allowMode != ALLOW_FULL_ONLY) {
14916                        builder.append(" or ");
14917                        builder.append(INTERACT_ACROSS_USERS);
14918                    }
14919                    String msg = builder.toString();
14920                    Slog.w(TAG, msg);
14921                    throw new SecurityException(msg);
14922                }
14923            }
14924        }
14925        if (!allowAll && targetUserId < 0) {
14926            throw new IllegalArgumentException(
14927                    "Call does not support special user #" + targetUserId);
14928        }
14929        // Check shell permission
14930        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14931            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14932                    targetUserId)) {
14933                throw new SecurityException("Shell does not have permission to access user "
14934                        + targetUserId + "\n " + Debug.getCallers(3));
14935            }
14936        }
14937        return targetUserId;
14938    }
14939
14940    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14941            String className, int flags) {
14942        boolean result = false;
14943        // For apps that don't have pre-defined UIDs, check for permission
14944        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14945            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14946                if (ActivityManager.checkUidPermission(
14947                        INTERACT_ACROSS_USERS,
14948                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14949                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14950                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14951                            + " requests FLAG_SINGLE_USER, but app does not hold "
14952                            + INTERACT_ACROSS_USERS;
14953                    Slog.w(TAG, msg);
14954                    throw new SecurityException(msg);
14955                }
14956                // Permission passed
14957                result = true;
14958            }
14959        } else if ("system".equals(componentProcessName)) {
14960            result = true;
14961        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14962            // Phone app and persistent apps are allowed to export singleuser providers.
14963            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14964                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14965        }
14966        if (DEBUG_MU) {
14967            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14968                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14969        }
14970        return result;
14971    }
14972
14973    /**
14974     * Checks to see if the caller is in the same app as the singleton
14975     * component, or the component is in a special app. It allows special apps
14976     * to export singleton components but prevents exporting singleton
14977     * components for regular apps.
14978     */
14979    boolean isValidSingletonCall(int callingUid, int componentUid) {
14980        int componentAppId = UserHandle.getAppId(componentUid);
14981        return UserHandle.isSameApp(callingUid, componentUid)
14982                || componentAppId == Process.SYSTEM_UID
14983                || componentAppId == Process.PHONE_UID
14984                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14985                        == PackageManager.PERMISSION_GRANTED;
14986    }
14987
14988    public int bindService(IApplicationThread caller, IBinder token,
14989            Intent service, String resolvedType,
14990            IServiceConnection connection, int flags, int userId) {
14991        enforceNotIsolatedCaller("bindService");
14992
14993        // Refuse possible leaked file descriptors
14994        if (service != null && service.hasFileDescriptors() == true) {
14995            throw new IllegalArgumentException("File descriptors passed in Intent");
14996        }
14997
14998        synchronized(this) {
14999            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15000                    connection, flags, userId);
15001        }
15002    }
15003
15004    public boolean unbindService(IServiceConnection connection) {
15005        synchronized (this) {
15006            return mServices.unbindServiceLocked(connection);
15007        }
15008    }
15009
15010    public void publishService(IBinder token, Intent intent, IBinder service) {
15011        // Refuse possible leaked file descriptors
15012        if (intent != null && intent.hasFileDescriptors() == true) {
15013            throw new IllegalArgumentException("File descriptors passed in Intent");
15014        }
15015
15016        synchronized(this) {
15017            if (!(token instanceof ServiceRecord)) {
15018                throw new IllegalArgumentException("Invalid service token");
15019            }
15020            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15021        }
15022    }
15023
15024    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15025        // Refuse possible leaked file descriptors
15026        if (intent != null && intent.hasFileDescriptors() == true) {
15027            throw new IllegalArgumentException("File descriptors passed in Intent");
15028        }
15029
15030        synchronized(this) {
15031            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15032        }
15033    }
15034
15035    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15036        synchronized(this) {
15037            if (!(token instanceof ServiceRecord)) {
15038                throw new IllegalArgumentException("Invalid service token");
15039            }
15040            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15041        }
15042    }
15043
15044    // =========================================================
15045    // BACKUP AND RESTORE
15046    // =========================================================
15047
15048    // Cause the target app to be launched if necessary and its backup agent
15049    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15050    // activity manager to announce its creation.
15051    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15052        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15053        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15054
15055        synchronized(this) {
15056            // !!! TODO: currently no check here that we're already bound
15057            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15058            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15059            synchronized (stats) {
15060                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15061            }
15062
15063            // Backup agent is now in use, its package can't be stopped.
15064            try {
15065                AppGlobals.getPackageManager().setPackageStoppedState(
15066                        app.packageName, false, UserHandle.getUserId(app.uid));
15067            } catch (RemoteException e) {
15068            } catch (IllegalArgumentException e) {
15069                Slog.w(TAG, "Failed trying to unstop package "
15070                        + app.packageName + ": " + e);
15071            }
15072
15073            BackupRecord r = new BackupRecord(ss, app, backupMode);
15074            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15075                    ? new ComponentName(app.packageName, app.backupAgentName)
15076                    : new ComponentName("android", "FullBackupAgent");
15077            // startProcessLocked() returns existing proc's record if it's already running
15078            ProcessRecord proc = startProcessLocked(app.processName, app,
15079                    false, 0, "backup", hostingName, false, false, false);
15080            if (proc == null) {
15081                Slog.e(TAG, "Unable to start backup agent process " + r);
15082                return false;
15083            }
15084
15085            r.app = proc;
15086            mBackupTarget = r;
15087            mBackupAppName = app.packageName;
15088
15089            // Try not to kill the process during backup
15090            updateOomAdjLocked(proc);
15091
15092            // If the process is already attached, schedule the creation of the backup agent now.
15093            // If it is not yet live, this will be done when it attaches to the framework.
15094            if (proc.thread != null) {
15095                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15096                try {
15097                    proc.thread.scheduleCreateBackupAgent(app,
15098                            compatibilityInfoForPackageLocked(app), backupMode);
15099                } catch (RemoteException e) {
15100                    // Will time out on the backup manager side
15101                }
15102            } else {
15103                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15104            }
15105            // Invariants: at this point, the target app process exists and the application
15106            // is either already running or in the process of coming up.  mBackupTarget and
15107            // mBackupAppName describe the app, so that when it binds back to the AM we
15108            // know that it's scheduled for a backup-agent operation.
15109        }
15110
15111        return true;
15112    }
15113
15114    @Override
15115    public void clearPendingBackup() {
15116        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15117        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15118
15119        synchronized (this) {
15120            mBackupTarget = null;
15121            mBackupAppName = null;
15122        }
15123    }
15124
15125    // A backup agent has just come up
15126    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15127        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15128                + " = " + agent);
15129
15130        synchronized(this) {
15131            if (!agentPackageName.equals(mBackupAppName)) {
15132                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15133                return;
15134            }
15135        }
15136
15137        long oldIdent = Binder.clearCallingIdentity();
15138        try {
15139            IBackupManager bm = IBackupManager.Stub.asInterface(
15140                    ServiceManager.getService(Context.BACKUP_SERVICE));
15141            bm.agentConnected(agentPackageName, agent);
15142        } catch (RemoteException e) {
15143            // can't happen; the backup manager service is local
15144        } catch (Exception e) {
15145            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15146            e.printStackTrace();
15147        } finally {
15148            Binder.restoreCallingIdentity(oldIdent);
15149        }
15150    }
15151
15152    // done with this agent
15153    public void unbindBackupAgent(ApplicationInfo appInfo) {
15154        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15155        if (appInfo == null) {
15156            Slog.w(TAG, "unbind backup agent for null app");
15157            return;
15158        }
15159
15160        synchronized(this) {
15161            try {
15162                if (mBackupAppName == null) {
15163                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15164                    return;
15165                }
15166
15167                if (!mBackupAppName.equals(appInfo.packageName)) {
15168                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15169                    return;
15170                }
15171
15172                // Not backing this app up any more; reset its OOM adjustment
15173                final ProcessRecord proc = mBackupTarget.app;
15174                updateOomAdjLocked(proc);
15175
15176                // If the app crashed during backup, 'thread' will be null here
15177                if (proc.thread != null) {
15178                    try {
15179                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15180                                compatibilityInfoForPackageLocked(appInfo));
15181                    } catch (Exception e) {
15182                        Slog.e(TAG, "Exception when unbinding backup agent:");
15183                        e.printStackTrace();
15184                    }
15185                }
15186            } finally {
15187                mBackupTarget = null;
15188                mBackupAppName = null;
15189            }
15190        }
15191    }
15192    // =========================================================
15193    // BROADCASTS
15194    // =========================================================
15195
15196    private final List getStickiesLocked(String action, IntentFilter filter,
15197            List cur, int userId) {
15198        final ContentResolver resolver = mContext.getContentResolver();
15199        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15200        if (stickies == null) {
15201            return cur;
15202        }
15203        final ArrayList<Intent> list = stickies.get(action);
15204        if (list == null) {
15205            return cur;
15206        }
15207        int N = list.size();
15208        for (int i=0; i<N; i++) {
15209            Intent intent = list.get(i);
15210            if (filter.match(resolver, intent, true, TAG) >= 0) {
15211                if (cur == null) {
15212                    cur = new ArrayList<Intent>();
15213                }
15214                cur.add(intent);
15215            }
15216        }
15217        return cur;
15218    }
15219
15220    boolean isPendingBroadcastProcessLocked(int pid) {
15221        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15222                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15223    }
15224
15225    void skipPendingBroadcastLocked(int pid) {
15226            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15227            for (BroadcastQueue queue : mBroadcastQueues) {
15228                queue.skipPendingBroadcastLocked(pid);
15229            }
15230    }
15231
15232    // The app just attached; send any pending broadcasts that it should receive
15233    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15234        boolean didSomething = false;
15235        for (BroadcastQueue queue : mBroadcastQueues) {
15236            didSomething |= queue.sendPendingBroadcastsLocked(app);
15237        }
15238        return didSomething;
15239    }
15240
15241    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15242            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15243        enforceNotIsolatedCaller("registerReceiver");
15244        int callingUid;
15245        int callingPid;
15246        synchronized(this) {
15247            ProcessRecord callerApp = null;
15248            if (caller != null) {
15249                callerApp = getRecordForAppLocked(caller);
15250                if (callerApp == null) {
15251                    throw new SecurityException(
15252                            "Unable to find app for caller " + caller
15253                            + " (pid=" + Binder.getCallingPid()
15254                            + ") when registering receiver " + receiver);
15255                }
15256                if (callerApp.info.uid != Process.SYSTEM_UID &&
15257                        !callerApp.pkgList.containsKey(callerPackage) &&
15258                        !"android".equals(callerPackage)) {
15259                    throw new SecurityException("Given caller package " + callerPackage
15260                            + " is not running in process " + callerApp);
15261                }
15262                callingUid = callerApp.info.uid;
15263                callingPid = callerApp.pid;
15264            } else {
15265                callerPackage = null;
15266                callingUid = Binder.getCallingUid();
15267                callingPid = Binder.getCallingPid();
15268            }
15269
15270            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15271                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15272
15273            List allSticky = null;
15274
15275            // Look for any matching sticky broadcasts...
15276            Iterator actions = filter.actionsIterator();
15277            if (actions != null) {
15278                while (actions.hasNext()) {
15279                    String action = (String)actions.next();
15280                    allSticky = getStickiesLocked(action, filter, allSticky,
15281                            UserHandle.USER_ALL);
15282                    allSticky = getStickiesLocked(action, filter, allSticky,
15283                            UserHandle.getUserId(callingUid));
15284                }
15285            } else {
15286                allSticky = getStickiesLocked(null, filter, allSticky,
15287                        UserHandle.USER_ALL);
15288                allSticky = getStickiesLocked(null, filter, allSticky,
15289                        UserHandle.getUserId(callingUid));
15290            }
15291
15292            // The first sticky in the list is returned directly back to
15293            // the client.
15294            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15295
15296            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15297                    + ": " + sticky);
15298
15299            if (receiver == null) {
15300                return sticky;
15301            }
15302
15303            ReceiverList rl
15304                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15305            if (rl == null) {
15306                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15307                        userId, receiver);
15308                if (rl.app != null) {
15309                    rl.app.receivers.add(rl);
15310                } else {
15311                    try {
15312                        receiver.asBinder().linkToDeath(rl, 0);
15313                    } catch (RemoteException e) {
15314                        return sticky;
15315                    }
15316                    rl.linkedToDeath = true;
15317                }
15318                mRegisteredReceivers.put(receiver.asBinder(), rl);
15319            } else if (rl.uid != callingUid) {
15320                throw new IllegalArgumentException(
15321                        "Receiver requested to register for uid " + callingUid
15322                        + " was previously registered for uid " + rl.uid);
15323            } else if (rl.pid != callingPid) {
15324                throw new IllegalArgumentException(
15325                        "Receiver requested to register for pid " + callingPid
15326                        + " was previously registered for pid " + rl.pid);
15327            } else if (rl.userId != userId) {
15328                throw new IllegalArgumentException(
15329                        "Receiver requested to register for user " + userId
15330                        + " was previously registered for user " + rl.userId);
15331            }
15332            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15333                    permission, callingUid, userId);
15334            rl.add(bf);
15335            if (!bf.debugCheck()) {
15336                Slog.w(TAG, "==> For Dynamic broadast");
15337            }
15338            mReceiverResolver.addFilter(bf);
15339
15340            // Enqueue broadcasts for all existing stickies that match
15341            // this filter.
15342            if (allSticky != null) {
15343                ArrayList receivers = new ArrayList();
15344                receivers.add(bf);
15345
15346                int N = allSticky.size();
15347                for (int i=0; i<N; i++) {
15348                    Intent intent = (Intent)allSticky.get(i);
15349                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15350                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15351                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15352                            null, null, false, true, true, -1);
15353                    queue.enqueueParallelBroadcastLocked(r);
15354                    queue.scheduleBroadcastsLocked();
15355                }
15356            }
15357
15358            return sticky;
15359        }
15360    }
15361
15362    public void unregisterReceiver(IIntentReceiver receiver) {
15363        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15364
15365        final long origId = Binder.clearCallingIdentity();
15366        try {
15367            boolean doTrim = false;
15368
15369            synchronized(this) {
15370                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15371                if (rl != null) {
15372                    if (rl.curBroadcast != null) {
15373                        BroadcastRecord r = rl.curBroadcast;
15374                        final boolean doNext = finishReceiverLocked(
15375                                receiver.asBinder(), r.resultCode, r.resultData,
15376                                r.resultExtras, r.resultAbort);
15377                        if (doNext) {
15378                            doTrim = true;
15379                            r.queue.processNextBroadcast(false);
15380                        }
15381                    }
15382
15383                    if (rl.app != null) {
15384                        rl.app.receivers.remove(rl);
15385                    }
15386                    removeReceiverLocked(rl);
15387                    if (rl.linkedToDeath) {
15388                        rl.linkedToDeath = false;
15389                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15390                    }
15391                }
15392            }
15393
15394            // If we actually concluded any broadcasts, we might now be able
15395            // to trim the recipients' apps from our working set
15396            if (doTrim) {
15397                trimApplications();
15398                return;
15399            }
15400
15401        } finally {
15402            Binder.restoreCallingIdentity(origId);
15403        }
15404    }
15405
15406    void removeReceiverLocked(ReceiverList rl) {
15407        mRegisteredReceivers.remove(rl.receiver.asBinder());
15408        int N = rl.size();
15409        for (int i=0; i<N; i++) {
15410            mReceiverResolver.removeFilter(rl.get(i));
15411        }
15412    }
15413
15414    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15415        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15416            ProcessRecord r = mLruProcesses.get(i);
15417            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15418                try {
15419                    r.thread.dispatchPackageBroadcast(cmd, packages);
15420                } catch (RemoteException ex) {
15421                }
15422            }
15423        }
15424    }
15425
15426    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15427            int callingUid, int[] users) {
15428        List<ResolveInfo> receivers = null;
15429        try {
15430            HashSet<ComponentName> singleUserReceivers = null;
15431            boolean scannedFirstReceivers = false;
15432            for (int user : users) {
15433                // Skip users that have Shell restrictions
15434                if (callingUid == Process.SHELL_UID
15435                        && getUserManagerLocked().hasUserRestriction(
15436                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15437                    continue;
15438                }
15439                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15440                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15441                if (user != 0 && newReceivers != null) {
15442                    // If this is not the primary user, we need to check for
15443                    // any receivers that should be filtered out.
15444                    for (int i=0; i<newReceivers.size(); i++) {
15445                        ResolveInfo ri = newReceivers.get(i);
15446                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15447                            newReceivers.remove(i);
15448                            i--;
15449                        }
15450                    }
15451                }
15452                if (newReceivers != null && newReceivers.size() == 0) {
15453                    newReceivers = null;
15454                }
15455                if (receivers == null) {
15456                    receivers = newReceivers;
15457                } else if (newReceivers != null) {
15458                    // We need to concatenate the additional receivers
15459                    // found with what we have do far.  This would be easy,
15460                    // but we also need to de-dup any receivers that are
15461                    // singleUser.
15462                    if (!scannedFirstReceivers) {
15463                        // Collect any single user receivers we had already retrieved.
15464                        scannedFirstReceivers = true;
15465                        for (int i=0; i<receivers.size(); i++) {
15466                            ResolveInfo ri = receivers.get(i);
15467                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15468                                ComponentName cn = new ComponentName(
15469                                        ri.activityInfo.packageName, ri.activityInfo.name);
15470                                if (singleUserReceivers == null) {
15471                                    singleUserReceivers = new HashSet<ComponentName>();
15472                                }
15473                                singleUserReceivers.add(cn);
15474                            }
15475                        }
15476                    }
15477                    // Add the new results to the existing results, tracking
15478                    // and de-dupping single user receivers.
15479                    for (int i=0; i<newReceivers.size(); i++) {
15480                        ResolveInfo ri = newReceivers.get(i);
15481                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15482                            ComponentName cn = new ComponentName(
15483                                    ri.activityInfo.packageName, ri.activityInfo.name);
15484                            if (singleUserReceivers == null) {
15485                                singleUserReceivers = new HashSet<ComponentName>();
15486                            }
15487                            if (!singleUserReceivers.contains(cn)) {
15488                                singleUserReceivers.add(cn);
15489                                receivers.add(ri);
15490                            }
15491                        } else {
15492                            receivers.add(ri);
15493                        }
15494                    }
15495                }
15496            }
15497        } catch (RemoteException ex) {
15498            // pm is in same process, this will never happen.
15499        }
15500        return receivers;
15501    }
15502
15503    private final int broadcastIntentLocked(ProcessRecord callerApp,
15504            String callerPackage, Intent intent, String resolvedType,
15505            IIntentReceiver resultTo, int resultCode, String resultData,
15506            Bundle map, String requiredPermission, int appOp,
15507            boolean ordered, boolean sticky, int callingPid, int callingUid,
15508            int userId) {
15509        intent = new Intent(intent);
15510
15511        // By default broadcasts do not go to stopped apps.
15512        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15513
15514        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15515            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15516            + " ordered=" + ordered + " userid=" + userId);
15517        if ((resultTo != null) && !ordered) {
15518            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15519        }
15520
15521        userId = handleIncomingUser(callingPid, callingUid, userId,
15522                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15523
15524        // Make sure that the user who is receiving this broadcast is started.
15525        // If not, we will just skip it.
15526
15527        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15528            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15529                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15530                Slog.w(TAG, "Skipping broadcast of " + intent
15531                        + ": user " + userId + " is stopped");
15532                return ActivityManager.BROADCAST_SUCCESS;
15533            }
15534        }
15535
15536        /*
15537         * Prevent non-system code (defined here to be non-persistent
15538         * processes) from sending protected broadcasts.
15539         */
15540        int callingAppId = UserHandle.getAppId(callingUid);
15541        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15542            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15543            || callingAppId == Process.NFC_UID || callingUid == 0) {
15544            // Always okay.
15545        } else if (callerApp == null || !callerApp.persistent) {
15546            try {
15547                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15548                        intent.getAction())) {
15549                    String msg = "Permission Denial: not allowed to send broadcast "
15550                            + intent.getAction() + " from pid="
15551                            + callingPid + ", uid=" + callingUid;
15552                    Slog.w(TAG, msg);
15553                    throw new SecurityException(msg);
15554                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15555                    // Special case for compatibility: we don't want apps to send this,
15556                    // but historically it has not been protected and apps may be using it
15557                    // to poke their own app widget.  So, instead of making it protected,
15558                    // just limit it to the caller.
15559                    if (callerApp == null) {
15560                        String msg = "Permission Denial: not allowed to send broadcast "
15561                                + intent.getAction() + " from unknown caller.";
15562                        Slog.w(TAG, msg);
15563                        throw new SecurityException(msg);
15564                    } else if (intent.getComponent() != null) {
15565                        // They are good enough to send to an explicit component...  verify
15566                        // it is being sent to the calling app.
15567                        if (!intent.getComponent().getPackageName().equals(
15568                                callerApp.info.packageName)) {
15569                            String msg = "Permission Denial: not allowed to send broadcast "
15570                                    + intent.getAction() + " to "
15571                                    + intent.getComponent().getPackageName() + " from "
15572                                    + callerApp.info.packageName;
15573                            Slog.w(TAG, msg);
15574                            throw new SecurityException(msg);
15575                        }
15576                    } else {
15577                        // Limit broadcast to their own package.
15578                        intent.setPackage(callerApp.info.packageName);
15579                    }
15580                }
15581            } catch (RemoteException e) {
15582                Slog.w(TAG, "Remote exception", e);
15583                return ActivityManager.BROADCAST_SUCCESS;
15584            }
15585        }
15586
15587        // Handle special intents: if this broadcast is from the package
15588        // manager about a package being removed, we need to remove all of
15589        // its activities from the history stack.
15590        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15591                intent.getAction());
15592        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15593                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15594                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15595                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15596                || uidRemoved) {
15597            if (checkComponentPermission(
15598                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15599                    callingPid, callingUid, -1, true)
15600                    == PackageManager.PERMISSION_GRANTED) {
15601                if (uidRemoved) {
15602                    final Bundle intentExtras = intent.getExtras();
15603                    final int uid = intentExtras != null
15604                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15605                    if (uid >= 0) {
15606                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15607                        synchronized (bs) {
15608                            bs.removeUidStatsLocked(uid);
15609                        }
15610                        mAppOpsService.uidRemoved(uid);
15611                    }
15612                } else {
15613                    // If resources are unavailable just force stop all
15614                    // those packages and flush the attribute cache as well.
15615                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15616                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15617                        if (list != null && (list.length > 0)) {
15618                            for (String pkg : list) {
15619                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15620                                        "storage unmount");
15621                            }
15622                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15623                            sendPackageBroadcastLocked(
15624                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15625                        }
15626                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15627                            intent.getAction())) {
15628                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15629                    } else {
15630                        Uri data = intent.getData();
15631                        String ssp;
15632                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15633                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15634                                    intent.getAction());
15635                            boolean fullUninstall = removed &&
15636                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15637                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15638                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15639                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15640                                        false, fullUninstall, userId,
15641                                        removed ? "pkg removed" : "pkg changed");
15642                            }
15643                            if (removed) {
15644                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15645                                        new String[] {ssp}, userId);
15646                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15647                                    mAppOpsService.packageRemoved(
15648                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15649
15650                                    // Remove all permissions granted from/to this package
15651                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15652                                }
15653                            }
15654                        }
15655                    }
15656                }
15657            } else {
15658                String msg = "Permission Denial: " + intent.getAction()
15659                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15660                        + ", uid=" + callingUid + ")"
15661                        + " requires "
15662                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15663                Slog.w(TAG, msg);
15664                throw new SecurityException(msg);
15665            }
15666
15667        // Special case for adding a package: by default turn on compatibility
15668        // mode.
15669        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15670            Uri data = intent.getData();
15671            String ssp;
15672            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15673                mCompatModePackages.handlePackageAddedLocked(ssp,
15674                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15675            }
15676        }
15677
15678        /*
15679         * If this is the time zone changed action, queue up a message that will reset the timezone
15680         * of all currently running processes. This message will get queued up before the broadcast
15681         * happens.
15682         */
15683        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15684            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15685        }
15686
15687        /*
15688         * If the user set the time, let all running processes know.
15689         */
15690        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15691            final int is24Hour = intent.getBooleanExtra(
15692                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15693            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15694            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15695            synchronized (stats) {
15696                stats.noteCurrentTimeChangedLocked();
15697            }
15698        }
15699
15700        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15701            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15702        }
15703
15704        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15705            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15706            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15707        }
15708
15709        // Add to the sticky list if requested.
15710        if (sticky) {
15711            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15712                    callingPid, callingUid)
15713                    != PackageManager.PERMISSION_GRANTED) {
15714                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15715                        + callingPid + ", uid=" + callingUid
15716                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15717                Slog.w(TAG, msg);
15718                throw new SecurityException(msg);
15719            }
15720            if (requiredPermission != null) {
15721                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15722                        + " and enforce permission " + requiredPermission);
15723                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15724            }
15725            if (intent.getComponent() != null) {
15726                throw new SecurityException(
15727                        "Sticky broadcasts can't target a specific component");
15728            }
15729            // We use userId directly here, since the "all" target is maintained
15730            // as a separate set of sticky broadcasts.
15731            if (userId != UserHandle.USER_ALL) {
15732                // But first, if this is not a broadcast to all users, then
15733                // make sure it doesn't conflict with an existing broadcast to
15734                // all users.
15735                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15736                        UserHandle.USER_ALL);
15737                if (stickies != null) {
15738                    ArrayList<Intent> list = stickies.get(intent.getAction());
15739                    if (list != null) {
15740                        int N = list.size();
15741                        int i;
15742                        for (i=0; i<N; i++) {
15743                            if (intent.filterEquals(list.get(i))) {
15744                                throw new IllegalArgumentException(
15745                                        "Sticky broadcast " + intent + " for user "
15746                                        + userId + " conflicts with existing global broadcast");
15747                            }
15748                        }
15749                    }
15750                }
15751            }
15752            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15753            if (stickies == null) {
15754                stickies = new ArrayMap<String, ArrayList<Intent>>();
15755                mStickyBroadcasts.put(userId, stickies);
15756            }
15757            ArrayList<Intent> list = stickies.get(intent.getAction());
15758            if (list == null) {
15759                list = new ArrayList<Intent>();
15760                stickies.put(intent.getAction(), list);
15761            }
15762            int N = list.size();
15763            int i;
15764            for (i=0; i<N; i++) {
15765                if (intent.filterEquals(list.get(i))) {
15766                    // This sticky already exists, replace it.
15767                    list.set(i, new Intent(intent));
15768                    break;
15769                }
15770            }
15771            if (i >= N) {
15772                list.add(new Intent(intent));
15773            }
15774        }
15775
15776        int[] users;
15777        if (userId == UserHandle.USER_ALL) {
15778            // Caller wants broadcast to go to all started users.
15779            users = mStartedUserArray;
15780        } else {
15781            // Caller wants broadcast to go to one specific user.
15782            users = new int[] {userId};
15783        }
15784
15785        // Figure out who all will receive this broadcast.
15786        List receivers = null;
15787        List<BroadcastFilter> registeredReceivers = null;
15788        // Need to resolve the intent to interested receivers...
15789        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15790                 == 0) {
15791            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15792        }
15793        if (intent.getComponent() == null) {
15794            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15795                // Query one target user at a time, excluding shell-restricted users
15796                UserManagerService ums = getUserManagerLocked();
15797                for (int i = 0; i < users.length; i++) {
15798                    if (ums.hasUserRestriction(
15799                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15800                        continue;
15801                    }
15802                    List<BroadcastFilter> registeredReceiversForUser =
15803                            mReceiverResolver.queryIntent(intent,
15804                                    resolvedType, false, users[i]);
15805                    if (registeredReceivers == null) {
15806                        registeredReceivers = registeredReceiversForUser;
15807                    } else if (registeredReceiversForUser != null) {
15808                        registeredReceivers.addAll(registeredReceiversForUser);
15809                    }
15810                }
15811            } else {
15812                registeredReceivers = mReceiverResolver.queryIntent(intent,
15813                        resolvedType, false, userId);
15814            }
15815        }
15816
15817        final boolean replacePending =
15818                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15819
15820        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15821                + " replacePending=" + replacePending);
15822
15823        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15824        if (!ordered && NR > 0) {
15825            // If we are not serializing this broadcast, then send the
15826            // registered receivers separately so they don't wait for the
15827            // components to be launched.
15828            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15829            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15830                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15831                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15832                    ordered, sticky, false, userId);
15833            if (DEBUG_BROADCAST) Slog.v(
15834                    TAG, "Enqueueing parallel broadcast " + r);
15835            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15836            if (!replaced) {
15837                queue.enqueueParallelBroadcastLocked(r);
15838                queue.scheduleBroadcastsLocked();
15839            }
15840            registeredReceivers = null;
15841            NR = 0;
15842        }
15843
15844        // Merge into one list.
15845        int ir = 0;
15846        if (receivers != null) {
15847            // A special case for PACKAGE_ADDED: do not allow the package
15848            // being added to see this broadcast.  This prevents them from
15849            // using this as a back door to get run as soon as they are
15850            // installed.  Maybe in the future we want to have a special install
15851            // broadcast or such for apps, but we'd like to deliberately make
15852            // this decision.
15853            String skipPackages[] = null;
15854            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15855                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15856                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15857                Uri data = intent.getData();
15858                if (data != null) {
15859                    String pkgName = data.getSchemeSpecificPart();
15860                    if (pkgName != null) {
15861                        skipPackages = new String[] { pkgName };
15862                    }
15863                }
15864            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15865                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15866            }
15867            if (skipPackages != null && (skipPackages.length > 0)) {
15868                for (String skipPackage : skipPackages) {
15869                    if (skipPackage != null) {
15870                        int NT = receivers.size();
15871                        for (int it=0; it<NT; it++) {
15872                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15873                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15874                                receivers.remove(it);
15875                                it--;
15876                                NT--;
15877                            }
15878                        }
15879                    }
15880                }
15881            }
15882
15883            int NT = receivers != null ? receivers.size() : 0;
15884            int it = 0;
15885            ResolveInfo curt = null;
15886            BroadcastFilter curr = null;
15887            while (it < NT && ir < NR) {
15888                if (curt == null) {
15889                    curt = (ResolveInfo)receivers.get(it);
15890                }
15891                if (curr == null) {
15892                    curr = registeredReceivers.get(ir);
15893                }
15894                if (curr.getPriority() >= curt.priority) {
15895                    // Insert this broadcast record into the final list.
15896                    receivers.add(it, curr);
15897                    ir++;
15898                    curr = null;
15899                    it++;
15900                    NT++;
15901                } else {
15902                    // Skip to the next ResolveInfo in the final list.
15903                    it++;
15904                    curt = null;
15905                }
15906            }
15907        }
15908        while (ir < NR) {
15909            if (receivers == null) {
15910                receivers = new ArrayList();
15911            }
15912            receivers.add(registeredReceivers.get(ir));
15913            ir++;
15914        }
15915
15916        if ((receivers != null && receivers.size() > 0)
15917                || resultTo != null) {
15918            BroadcastQueue queue = broadcastQueueForIntent(intent);
15919            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15920                    callerPackage, callingPid, callingUid, resolvedType,
15921                    requiredPermission, appOp, receivers, resultTo, resultCode,
15922                    resultData, map, ordered, sticky, false, userId);
15923            if (DEBUG_BROADCAST) Slog.v(
15924                    TAG, "Enqueueing ordered broadcast " + r
15925                    + ": prev had " + queue.mOrderedBroadcasts.size());
15926            if (DEBUG_BROADCAST) {
15927                int seq = r.intent.getIntExtra("seq", -1);
15928                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15929            }
15930            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15931            if (!replaced) {
15932                queue.enqueueOrderedBroadcastLocked(r);
15933                queue.scheduleBroadcastsLocked();
15934            }
15935        }
15936
15937        return ActivityManager.BROADCAST_SUCCESS;
15938    }
15939
15940    final Intent verifyBroadcastLocked(Intent intent) {
15941        // Refuse possible leaked file descriptors
15942        if (intent != null && intent.hasFileDescriptors() == true) {
15943            throw new IllegalArgumentException("File descriptors passed in Intent");
15944        }
15945
15946        int flags = intent.getFlags();
15947
15948        if (!mProcessesReady) {
15949            // if the caller really truly claims to know what they're doing, go
15950            // ahead and allow the broadcast without launching any receivers
15951            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15952                intent = new Intent(intent);
15953                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15954            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15955                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15956                        + " before boot completion");
15957                throw new IllegalStateException("Cannot broadcast before boot completed");
15958            }
15959        }
15960
15961        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15962            throw new IllegalArgumentException(
15963                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15964        }
15965
15966        return intent;
15967    }
15968
15969    public final int broadcastIntent(IApplicationThread caller,
15970            Intent intent, String resolvedType, IIntentReceiver resultTo,
15971            int resultCode, String resultData, Bundle map,
15972            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15973        enforceNotIsolatedCaller("broadcastIntent");
15974        synchronized(this) {
15975            intent = verifyBroadcastLocked(intent);
15976
15977            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15978            final int callingPid = Binder.getCallingPid();
15979            final int callingUid = Binder.getCallingUid();
15980            final long origId = Binder.clearCallingIdentity();
15981            int res = broadcastIntentLocked(callerApp,
15982                    callerApp != null ? callerApp.info.packageName : null,
15983                    intent, resolvedType, resultTo,
15984                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15985                    callingPid, callingUid, userId);
15986            Binder.restoreCallingIdentity(origId);
15987            return res;
15988        }
15989    }
15990
15991    int broadcastIntentInPackage(String packageName, int uid,
15992            Intent intent, String resolvedType, IIntentReceiver resultTo,
15993            int resultCode, String resultData, Bundle map,
15994            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15995        synchronized(this) {
15996            intent = verifyBroadcastLocked(intent);
15997
15998            final long origId = Binder.clearCallingIdentity();
15999            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16000                    resultTo, resultCode, resultData, map, requiredPermission,
16001                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16002            Binder.restoreCallingIdentity(origId);
16003            return res;
16004        }
16005    }
16006
16007    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16008        // Refuse possible leaked file descriptors
16009        if (intent != null && intent.hasFileDescriptors() == true) {
16010            throw new IllegalArgumentException("File descriptors passed in Intent");
16011        }
16012
16013        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16014                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16015
16016        synchronized(this) {
16017            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16018                    != PackageManager.PERMISSION_GRANTED) {
16019                String msg = "Permission Denial: unbroadcastIntent() from pid="
16020                        + Binder.getCallingPid()
16021                        + ", uid=" + Binder.getCallingUid()
16022                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16023                Slog.w(TAG, msg);
16024                throw new SecurityException(msg);
16025            }
16026            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16027            if (stickies != null) {
16028                ArrayList<Intent> list = stickies.get(intent.getAction());
16029                if (list != null) {
16030                    int N = list.size();
16031                    int i;
16032                    for (i=0; i<N; i++) {
16033                        if (intent.filterEquals(list.get(i))) {
16034                            list.remove(i);
16035                            break;
16036                        }
16037                    }
16038                    if (list.size() <= 0) {
16039                        stickies.remove(intent.getAction());
16040                    }
16041                }
16042                if (stickies.size() <= 0) {
16043                    mStickyBroadcasts.remove(userId);
16044                }
16045            }
16046        }
16047    }
16048
16049    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16050            String resultData, Bundle resultExtras, boolean resultAbort) {
16051        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16052        if (r == null) {
16053            Slog.w(TAG, "finishReceiver called but not found on queue");
16054            return false;
16055        }
16056
16057        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16058    }
16059
16060    void backgroundServicesFinishedLocked(int userId) {
16061        for (BroadcastQueue queue : mBroadcastQueues) {
16062            queue.backgroundServicesFinishedLocked(userId);
16063        }
16064    }
16065
16066    public void finishReceiver(IBinder who, int resultCode, String resultData,
16067            Bundle resultExtras, boolean resultAbort) {
16068        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16069
16070        // Refuse possible leaked file descriptors
16071        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16072            throw new IllegalArgumentException("File descriptors passed in Bundle");
16073        }
16074
16075        final long origId = Binder.clearCallingIdentity();
16076        try {
16077            boolean doNext = false;
16078            BroadcastRecord r;
16079
16080            synchronized(this) {
16081                r = broadcastRecordForReceiverLocked(who);
16082                if (r != null) {
16083                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16084                        resultData, resultExtras, resultAbort, true);
16085                }
16086            }
16087
16088            if (doNext) {
16089                r.queue.processNextBroadcast(false);
16090            }
16091            trimApplications();
16092        } finally {
16093            Binder.restoreCallingIdentity(origId);
16094        }
16095    }
16096
16097    // =========================================================
16098    // INSTRUMENTATION
16099    // =========================================================
16100
16101    public boolean startInstrumentation(ComponentName className,
16102            String profileFile, int flags, Bundle arguments,
16103            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16104            int userId, String abiOverride) {
16105        enforceNotIsolatedCaller("startInstrumentation");
16106        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16107                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16108        // Refuse possible leaked file descriptors
16109        if (arguments != null && arguments.hasFileDescriptors()) {
16110            throw new IllegalArgumentException("File descriptors passed in Bundle");
16111        }
16112
16113        synchronized(this) {
16114            InstrumentationInfo ii = null;
16115            ApplicationInfo ai = null;
16116            try {
16117                ii = mContext.getPackageManager().getInstrumentationInfo(
16118                    className, STOCK_PM_FLAGS);
16119                ai = AppGlobals.getPackageManager().getApplicationInfo(
16120                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16121            } catch (PackageManager.NameNotFoundException e) {
16122            } catch (RemoteException e) {
16123            }
16124            if (ii == null) {
16125                reportStartInstrumentationFailure(watcher, className,
16126                        "Unable to find instrumentation info for: " + className);
16127                return false;
16128            }
16129            if (ai == null) {
16130                reportStartInstrumentationFailure(watcher, className,
16131                        "Unable to find instrumentation target package: " + ii.targetPackage);
16132                return false;
16133            }
16134
16135            int match = mContext.getPackageManager().checkSignatures(
16136                    ii.targetPackage, ii.packageName);
16137            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16138                String msg = "Permission Denial: starting instrumentation "
16139                        + className + " from pid="
16140                        + Binder.getCallingPid()
16141                        + ", uid=" + Binder.getCallingPid()
16142                        + " not allowed because package " + ii.packageName
16143                        + " does not have a signature matching the target "
16144                        + ii.targetPackage;
16145                reportStartInstrumentationFailure(watcher, className, msg);
16146                throw new SecurityException(msg);
16147            }
16148
16149            final long origId = Binder.clearCallingIdentity();
16150            // Instrumentation can kill and relaunch even persistent processes
16151            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16152                    "start instr");
16153            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16154            app.instrumentationClass = className;
16155            app.instrumentationInfo = ai;
16156            app.instrumentationProfileFile = profileFile;
16157            app.instrumentationArguments = arguments;
16158            app.instrumentationWatcher = watcher;
16159            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16160            app.instrumentationResultClass = className;
16161            Binder.restoreCallingIdentity(origId);
16162        }
16163
16164        return true;
16165    }
16166
16167    /**
16168     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16169     * error to the logs, but if somebody is watching, send the report there too.  This enables
16170     * the "am" command to report errors with more information.
16171     *
16172     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16173     * @param cn The component name of the instrumentation.
16174     * @param report The error report.
16175     */
16176    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16177            ComponentName cn, String report) {
16178        Slog.w(TAG, report);
16179        try {
16180            if (watcher != null) {
16181                Bundle results = new Bundle();
16182                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16183                results.putString("Error", report);
16184                watcher.instrumentationStatus(cn, -1, results);
16185            }
16186        } catch (RemoteException e) {
16187            Slog.w(TAG, e);
16188        }
16189    }
16190
16191    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16192        if (app.instrumentationWatcher != null) {
16193            try {
16194                // NOTE:  IInstrumentationWatcher *must* be oneway here
16195                app.instrumentationWatcher.instrumentationFinished(
16196                    app.instrumentationClass,
16197                    resultCode,
16198                    results);
16199            } catch (RemoteException e) {
16200            }
16201        }
16202        if (app.instrumentationUiAutomationConnection != null) {
16203            try {
16204                app.instrumentationUiAutomationConnection.shutdown();
16205            } catch (RemoteException re) {
16206                /* ignore */
16207            }
16208            // Only a UiAutomation can set this flag and now that
16209            // it is finished we make sure it is reset to its default.
16210            mUserIsMonkey = false;
16211        }
16212        app.instrumentationWatcher = null;
16213        app.instrumentationUiAutomationConnection = null;
16214        app.instrumentationClass = null;
16215        app.instrumentationInfo = null;
16216        app.instrumentationProfileFile = null;
16217        app.instrumentationArguments = null;
16218
16219        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16220                "finished inst");
16221    }
16222
16223    public void finishInstrumentation(IApplicationThread target,
16224            int resultCode, Bundle results) {
16225        int userId = UserHandle.getCallingUserId();
16226        // Refuse possible leaked file descriptors
16227        if (results != null && results.hasFileDescriptors()) {
16228            throw new IllegalArgumentException("File descriptors passed in Intent");
16229        }
16230
16231        synchronized(this) {
16232            ProcessRecord app = getRecordForAppLocked(target);
16233            if (app == null) {
16234                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16235                return;
16236            }
16237            final long origId = Binder.clearCallingIdentity();
16238            finishInstrumentationLocked(app, resultCode, results);
16239            Binder.restoreCallingIdentity(origId);
16240        }
16241    }
16242
16243    // =========================================================
16244    // CONFIGURATION
16245    // =========================================================
16246
16247    public ConfigurationInfo getDeviceConfigurationInfo() {
16248        ConfigurationInfo config = new ConfigurationInfo();
16249        synchronized (this) {
16250            config.reqTouchScreen = mConfiguration.touchscreen;
16251            config.reqKeyboardType = mConfiguration.keyboard;
16252            config.reqNavigation = mConfiguration.navigation;
16253            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16254                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16255                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16256            }
16257            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16258                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16259                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16260            }
16261            config.reqGlEsVersion = GL_ES_VERSION;
16262        }
16263        return config;
16264    }
16265
16266    ActivityStack getFocusedStack() {
16267        return mStackSupervisor.getFocusedStack();
16268    }
16269
16270    public Configuration getConfiguration() {
16271        Configuration ci;
16272        synchronized(this) {
16273            ci = new Configuration(mConfiguration);
16274        }
16275        return ci;
16276    }
16277
16278    public void updatePersistentConfiguration(Configuration values) {
16279        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16280                "updateConfiguration()");
16281        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16282                "updateConfiguration()");
16283        if (values == null) {
16284            throw new NullPointerException("Configuration must not be null");
16285        }
16286
16287        synchronized(this) {
16288            final long origId = Binder.clearCallingIdentity();
16289            updateConfigurationLocked(values, null, true, false);
16290            Binder.restoreCallingIdentity(origId);
16291        }
16292    }
16293
16294    public void updateConfiguration(Configuration values) {
16295        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16296                "updateConfiguration()");
16297
16298        synchronized(this) {
16299            if (values == null && mWindowManager != null) {
16300                // sentinel: fetch the current configuration from the window manager
16301                values = mWindowManager.computeNewConfiguration();
16302            }
16303
16304            if (mWindowManager != null) {
16305                mProcessList.applyDisplaySize(mWindowManager);
16306            }
16307
16308            final long origId = Binder.clearCallingIdentity();
16309            if (values != null) {
16310                Settings.System.clearConfiguration(values);
16311            }
16312            updateConfigurationLocked(values, null, false, false);
16313            Binder.restoreCallingIdentity(origId);
16314        }
16315    }
16316
16317    /**
16318     * Do either or both things: (1) change the current configuration, and (2)
16319     * make sure the given activity is running with the (now) current
16320     * configuration.  Returns true if the activity has been left running, or
16321     * false if <var>starting</var> is being destroyed to match the new
16322     * configuration.
16323     * @param persistent TODO
16324     */
16325    boolean updateConfigurationLocked(Configuration values,
16326            ActivityRecord starting, boolean persistent, boolean initLocale) {
16327        int changes = 0;
16328
16329        if (values != null) {
16330            Configuration newConfig = new Configuration(mConfiguration);
16331            changes = newConfig.updateFrom(values);
16332            if (changes != 0) {
16333                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16334                    Slog.i(TAG, "Updating configuration to: " + values);
16335                }
16336
16337                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16338
16339                if (values.locale != null && !initLocale) {
16340                    saveLocaleLocked(values.locale,
16341                                     !values.locale.equals(mConfiguration.locale),
16342                                     values.userSetLocale);
16343                }
16344
16345                mConfigurationSeq++;
16346                if (mConfigurationSeq <= 0) {
16347                    mConfigurationSeq = 1;
16348                }
16349                newConfig.seq = mConfigurationSeq;
16350                mConfiguration = newConfig;
16351                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16352                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16353                //mUsageStatsService.noteStartConfig(newConfig);
16354
16355                final Configuration configCopy = new Configuration(mConfiguration);
16356
16357                // TODO: If our config changes, should we auto dismiss any currently
16358                // showing dialogs?
16359                mShowDialogs = shouldShowDialogs(newConfig);
16360
16361                AttributeCache ac = AttributeCache.instance();
16362                if (ac != null) {
16363                    ac.updateConfiguration(configCopy);
16364                }
16365
16366                // Make sure all resources in our process are updated
16367                // right now, so that anyone who is going to retrieve
16368                // resource values after we return will be sure to get
16369                // the new ones.  This is especially important during
16370                // boot, where the first config change needs to guarantee
16371                // all resources have that config before following boot
16372                // code is executed.
16373                mSystemThread.applyConfigurationToResources(configCopy);
16374
16375                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16376                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16377                    msg.obj = new Configuration(configCopy);
16378                    mHandler.sendMessage(msg);
16379                }
16380
16381                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16382                    ProcessRecord app = mLruProcesses.get(i);
16383                    try {
16384                        if (app.thread != null) {
16385                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16386                                    + app.processName + " new config " + mConfiguration);
16387                            app.thread.scheduleConfigurationChanged(configCopy);
16388                        }
16389                    } catch (Exception e) {
16390                    }
16391                }
16392                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16393                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16394                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16395                        | Intent.FLAG_RECEIVER_FOREGROUND);
16396                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16397                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16398                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16399                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16400                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16401                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16402                    broadcastIntentLocked(null, null, intent,
16403                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16404                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16405                }
16406            }
16407        }
16408
16409        boolean kept = true;
16410        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16411        // mainStack is null during startup.
16412        if (mainStack != null) {
16413            if (changes != 0 && starting == null) {
16414                // If the configuration changed, and the caller is not already
16415                // in the process of starting an activity, then find the top
16416                // activity to check if its configuration needs to change.
16417                starting = mainStack.topRunningActivityLocked(null);
16418            }
16419
16420            if (starting != null) {
16421                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16422                // And we need to make sure at this point that all other activities
16423                // are made visible with the correct configuration.
16424                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16425            }
16426        }
16427
16428        if (values != null && mWindowManager != null) {
16429            mWindowManager.setNewConfiguration(mConfiguration);
16430        }
16431
16432        return kept;
16433    }
16434
16435    /**
16436     * Decide based on the configuration whether we should shouw the ANR,
16437     * crash, etc dialogs.  The idea is that if there is no affordnace to
16438     * press the on-screen buttons, we shouldn't show the dialog.
16439     *
16440     * A thought: SystemUI might also want to get told about this, the Power
16441     * dialog / global actions also might want different behaviors.
16442     */
16443    private static final boolean shouldShowDialogs(Configuration config) {
16444        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16445                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16446    }
16447
16448    /**
16449     * Save the locale.  You must be inside a synchronized (this) block.
16450     */
16451    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16452        if(isDiff) {
16453            SystemProperties.set("user.language", l.getLanguage());
16454            SystemProperties.set("user.region", l.getCountry());
16455        }
16456
16457        if(isPersist) {
16458            SystemProperties.set("persist.sys.language", l.getLanguage());
16459            SystemProperties.set("persist.sys.country", l.getCountry());
16460            SystemProperties.set("persist.sys.localevar", l.getVariant());
16461
16462            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16463        }
16464    }
16465
16466    @Override
16467    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16468        synchronized (this) {
16469            ActivityRecord srec = ActivityRecord.forToken(token);
16470            if (srec.task != null && srec.task.stack != null) {
16471                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16472            }
16473        }
16474        return false;
16475    }
16476
16477    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16478            Intent resultData) {
16479
16480        synchronized (this) {
16481            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16482            if (stack != null) {
16483                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16484            }
16485            return false;
16486        }
16487    }
16488
16489    public int getLaunchedFromUid(IBinder activityToken) {
16490        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16491        if (srec == null) {
16492            return -1;
16493        }
16494        return srec.launchedFromUid;
16495    }
16496
16497    public String getLaunchedFromPackage(IBinder activityToken) {
16498        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16499        if (srec == null) {
16500            return null;
16501        }
16502        return srec.launchedFromPackage;
16503    }
16504
16505    // =========================================================
16506    // LIFETIME MANAGEMENT
16507    // =========================================================
16508
16509    // Returns which broadcast queue the app is the current [or imminent] receiver
16510    // on, or 'null' if the app is not an active broadcast recipient.
16511    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16512        BroadcastRecord r = app.curReceiver;
16513        if (r != null) {
16514            return r.queue;
16515        }
16516
16517        // It's not the current receiver, but it might be starting up to become one
16518        synchronized (this) {
16519            for (BroadcastQueue queue : mBroadcastQueues) {
16520                r = queue.mPendingBroadcast;
16521                if (r != null && r.curApp == app) {
16522                    // found it; report which queue it's in
16523                    return queue;
16524                }
16525            }
16526        }
16527
16528        return null;
16529    }
16530
16531    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16532            boolean doingAll, long now) {
16533        if (mAdjSeq == app.adjSeq) {
16534            // This adjustment has already been computed.
16535            return app.curRawAdj;
16536        }
16537
16538        if (app.thread == null) {
16539            app.adjSeq = mAdjSeq;
16540            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16541            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16542            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16543        }
16544
16545        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16546        app.adjSource = null;
16547        app.adjTarget = null;
16548        app.empty = false;
16549        app.cached = false;
16550
16551        final int activitiesSize = app.activities.size();
16552
16553        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16554            // The max adjustment doesn't allow this app to be anything
16555            // below foreground, so it is not worth doing work for it.
16556            app.adjType = "fixed";
16557            app.adjSeq = mAdjSeq;
16558            app.curRawAdj = app.maxAdj;
16559            app.foregroundActivities = false;
16560            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16561            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16562            // System processes can do UI, and when they do we want to have
16563            // them trim their memory after the user leaves the UI.  To
16564            // facilitate this, here we need to determine whether or not it
16565            // is currently showing UI.
16566            app.systemNoUi = true;
16567            if (app == TOP_APP) {
16568                app.systemNoUi = false;
16569            } else if (activitiesSize > 0) {
16570                for (int j = 0; j < activitiesSize; j++) {
16571                    final ActivityRecord r = app.activities.get(j);
16572                    if (r.visible) {
16573                        app.systemNoUi = false;
16574                    }
16575                }
16576            }
16577            if (!app.systemNoUi) {
16578                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16579            }
16580            return (app.curAdj=app.maxAdj);
16581        }
16582
16583        app.systemNoUi = false;
16584
16585        // Determine the importance of the process, starting with most
16586        // important to least, and assign an appropriate OOM adjustment.
16587        int adj;
16588        int schedGroup;
16589        int procState;
16590        boolean foregroundActivities = false;
16591        BroadcastQueue queue;
16592        if (app == TOP_APP) {
16593            // The last app on the list is the foreground app.
16594            adj = ProcessList.FOREGROUND_APP_ADJ;
16595            schedGroup = Process.THREAD_GROUP_DEFAULT;
16596            app.adjType = "top-activity";
16597            foregroundActivities = true;
16598            procState = ActivityManager.PROCESS_STATE_TOP;
16599        } else if (app.instrumentationClass != null) {
16600            // Don't want to kill running instrumentation.
16601            adj = ProcessList.FOREGROUND_APP_ADJ;
16602            schedGroup = Process.THREAD_GROUP_DEFAULT;
16603            app.adjType = "instrumentation";
16604            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16605        } else if ((queue = isReceivingBroadcast(app)) != null) {
16606            // An app that is currently receiving a broadcast also
16607            // counts as being in the foreground for OOM killer purposes.
16608            // It's placed in a sched group based on the nature of the
16609            // broadcast as reflected by which queue it's active in.
16610            adj = ProcessList.FOREGROUND_APP_ADJ;
16611            schedGroup = (queue == mFgBroadcastQueue)
16612                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16613            app.adjType = "broadcast";
16614            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16615        } else if (app.executingServices.size() > 0) {
16616            // An app that is currently executing a service callback also
16617            // counts as being in the foreground.
16618            adj = ProcessList.FOREGROUND_APP_ADJ;
16619            schedGroup = app.execServicesFg ?
16620                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16621            app.adjType = "exec-service";
16622            procState = ActivityManager.PROCESS_STATE_SERVICE;
16623            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16624        } else {
16625            // As far as we know the process is empty.  We may change our mind later.
16626            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16627            // At this point we don't actually know the adjustment.  Use the cached adj
16628            // value that the caller wants us to.
16629            adj = cachedAdj;
16630            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16631            app.cached = true;
16632            app.empty = true;
16633            app.adjType = "cch-empty";
16634        }
16635
16636        // Examine all activities if not already foreground.
16637        if (!foregroundActivities && activitiesSize > 0) {
16638            for (int j = 0; j < activitiesSize; j++) {
16639                final ActivityRecord r = app.activities.get(j);
16640                if (r.app != app) {
16641                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16642                            + app + "?!?");
16643                    continue;
16644                }
16645                if (r.visible) {
16646                    // App has a visible activity; only upgrade adjustment.
16647                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16648                        adj = ProcessList.VISIBLE_APP_ADJ;
16649                        app.adjType = "visible";
16650                    }
16651                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16652                        procState = ActivityManager.PROCESS_STATE_TOP;
16653                    }
16654                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16655                    app.cached = false;
16656                    app.empty = false;
16657                    foregroundActivities = true;
16658                    break;
16659                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16660                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16661                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16662                        app.adjType = "pausing";
16663                    }
16664                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16665                        procState = ActivityManager.PROCESS_STATE_TOP;
16666                    }
16667                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16668                    app.cached = false;
16669                    app.empty = false;
16670                    foregroundActivities = true;
16671                } else if (r.state == ActivityState.STOPPING) {
16672                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16673                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16674                        app.adjType = "stopping";
16675                    }
16676                    // For the process state, we will at this point consider the
16677                    // process to be cached.  It will be cached either as an activity
16678                    // or empty depending on whether the activity is finishing.  We do
16679                    // this so that we can treat the process as cached for purposes of
16680                    // memory trimming (determing current memory level, trim command to
16681                    // send to process) since there can be an arbitrary number of stopping
16682                    // processes and they should soon all go into the cached state.
16683                    if (!r.finishing) {
16684                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16685                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16686                        }
16687                    }
16688                    app.cached = false;
16689                    app.empty = false;
16690                    foregroundActivities = true;
16691                } else {
16692                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16693                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16694                        app.adjType = "cch-act";
16695                    }
16696                }
16697            }
16698        }
16699
16700        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16701            if (app.foregroundServices) {
16702                // The user is aware of this app, so make it visible.
16703                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16704                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16705                app.cached = false;
16706                app.adjType = "fg-service";
16707                schedGroup = Process.THREAD_GROUP_DEFAULT;
16708            } else if (app.forcingToForeground != null) {
16709                // The user is aware of this app, so make it visible.
16710                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16711                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16712                app.cached = false;
16713                app.adjType = "force-fg";
16714                app.adjSource = app.forcingToForeground;
16715                schedGroup = Process.THREAD_GROUP_DEFAULT;
16716            }
16717        }
16718
16719        if (app == mHeavyWeightProcess) {
16720            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16721                // We don't want to kill the current heavy-weight process.
16722                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16723                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16724                app.cached = false;
16725                app.adjType = "heavy";
16726            }
16727            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16728                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16729            }
16730        }
16731
16732        if (app == mHomeProcess) {
16733            if (adj > ProcessList.HOME_APP_ADJ) {
16734                // This process is hosting what we currently consider to be the
16735                // home app, so we don't want to let it go into the background.
16736                adj = ProcessList.HOME_APP_ADJ;
16737                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16738                app.cached = false;
16739                app.adjType = "home";
16740            }
16741            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16742                procState = ActivityManager.PROCESS_STATE_HOME;
16743            }
16744        }
16745
16746        if (app == mPreviousProcess && app.activities.size() > 0) {
16747            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16748                // This was the previous process that showed UI to the user.
16749                // We want to try to keep it around more aggressively, to give
16750                // a good experience around switching between two apps.
16751                adj = ProcessList.PREVIOUS_APP_ADJ;
16752                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16753                app.cached = false;
16754                app.adjType = "previous";
16755            }
16756            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16757                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16758            }
16759        }
16760
16761        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16762                + " reason=" + app.adjType);
16763
16764        // By default, we use the computed adjustment.  It may be changed if
16765        // there are applications dependent on our services or providers, but
16766        // this gives us a baseline and makes sure we don't get into an
16767        // infinite recursion.
16768        app.adjSeq = mAdjSeq;
16769        app.curRawAdj = adj;
16770        app.hasStartedServices = false;
16771
16772        if (mBackupTarget != null && app == mBackupTarget.app) {
16773            // If possible we want to avoid killing apps while they're being backed up
16774            if (adj > ProcessList.BACKUP_APP_ADJ) {
16775                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16776                adj = ProcessList.BACKUP_APP_ADJ;
16777                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16778                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16779                }
16780                app.adjType = "backup";
16781                app.cached = false;
16782            }
16783            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16784                procState = ActivityManager.PROCESS_STATE_BACKUP;
16785            }
16786        }
16787
16788        boolean mayBeTop = false;
16789
16790        for (int is = app.services.size()-1;
16791                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16792                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16793                        || procState > ActivityManager.PROCESS_STATE_TOP);
16794                is--) {
16795            ServiceRecord s = app.services.valueAt(is);
16796            if (s.startRequested) {
16797                app.hasStartedServices = true;
16798                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16799                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16800                }
16801                if (app.hasShownUi && app != mHomeProcess) {
16802                    // If this process has shown some UI, let it immediately
16803                    // go to the LRU list because it may be pretty heavy with
16804                    // UI stuff.  We'll tag it with a label just to help
16805                    // debug and understand what is going on.
16806                    if (adj > ProcessList.SERVICE_ADJ) {
16807                        app.adjType = "cch-started-ui-services";
16808                    }
16809                } else {
16810                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16811                        // This service has seen some activity within
16812                        // recent memory, so we will keep its process ahead
16813                        // of the background processes.
16814                        if (adj > ProcessList.SERVICE_ADJ) {
16815                            adj = ProcessList.SERVICE_ADJ;
16816                            app.adjType = "started-services";
16817                            app.cached = false;
16818                        }
16819                    }
16820                    // If we have let the service slide into the background
16821                    // state, still have some text describing what it is doing
16822                    // even though the service no longer has an impact.
16823                    if (adj > ProcessList.SERVICE_ADJ) {
16824                        app.adjType = "cch-started-services";
16825                    }
16826                }
16827            }
16828            for (int conni = s.connections.size()-1;
16829                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16830                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16831                            || procState > ActivityManager.PROCESS_STATE_TOP);
16832                    conni--) {
16833                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16834                for (int i = 0;
16835                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16836                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16837                                || procState > ActivityManager.PROCESS_STATE_TOP);
16838                        i++) {
16839                    // XXX should compute this based on the max of
16840                    // all connected clients.
16841                    ConnectionRecord cr = clist.get(i);
16842                    if (cr.binding.client == app) {
16843                        // Binding to ourself is not interesting.
16844                        continue;
16845                    }
16846                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16847                        ProcessRecord client = cr.binding.client;
16848                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16849                                TOP_APP, doingAll, now);
16850                        int clientProcState = client.curProcState;
16851                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16852                            // If the other app is cached for any reason, for purposes here
16853                            // we are going to consider it empty.  The specific cached state
16854                            // doesn't propagate except under certain conditions.
16855                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16856                        }
16857                        String adjType = null;
16858                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16859                            // Not doing bind OOM management, so treat
16860                            // this guy more like a started service.
16861                            if (app.hasShownUi && app != mHomeProcess) {
16862                                // If this process has shown some UI, let it immediately
16863                                // go to the LRU list because it may be pretty heavy with
16864                                // UI stuff.  We'll tag it with a label just to help
16865                                // debug and understand what is going on.
16866                                if (adj > clientAdj) {
16867                                    adjType = "cch-bound-ui-services";
16868                                }
16869                                app.cached = false;
16870                                clientAdj = adj;
16871                                clientProcState = procState;
16872                            } else {
16873                                if (now >= (s.lastActivity
16874                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16875                                    // This service has not seen activity within
16876                                    // recent memory, so allow it to drop to the
16877                                    // LRU list if there is no other reason to keep
16878                                    // it around.  We'll also tag it with a label just
16879                                    // to help debug and undertand what is going on.
16880                                    if (adj > clientAdj) {
16881                                        adjType = "cch-bound-services";
16882                                    }
16883                                    clientAdj = adj;
16884                                }
16885                            }
16886                        }
16887                        if (adj > clientAdj) {
16888                            // If this process has recently shown UI, and
16889                            // the process that is binding to it is less
16890                            // important than being visible, then we don't
16891                            // care about the binding as much as we care
16892                            // about letting this process get into the LRU
16893                            // list to be killed and restarted if needed for
16894                            // memory.
16895                            if (app.hasShownUi && app != mHomeProcess
16896                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16897                                adjType = "cch-bound-ui-services";
16898                            } else {
16899                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16900                                        |Context.BIND_IMPORTANT)) != 0) {
16901                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16902                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16903                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16904                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16905                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16906                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16907                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16908                                    adj = clientAdj;
16909                                } else {
16910                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16911                                        adj = ProcessList.VISIBLE_APP_ADJ;
16912                                    }
16913                                }
16914                                if (!client.cached) {
16915                                    app.cached = false;
16916                                }
16917                                adjType = "service";
16918                            }
16919                        }
16920                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16921                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16922                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16923                            }
16924                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16925                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16926                                    // Special handling of clients who are in the top state.
16927                                    // We *may* want to consider this process to be in the
16928                                    // top state as well, but only if there is not another
16929                                    // reason for it to be running.  Being on the top is a
16930                                    // special state, meaning you are specifically running
16931                                    // for the current top app.  If the process is already
16932                                    // running in the background for some other reason, it
16933                                    // is more important to continue considering it to be
16934                                    // in the background state.
16935                                    mayBeTop = true;
16936                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16937                                } else {
16938                                    // Special handling for above-top states (persistent
16939                                    // processes).  These should not bring the current process
16940                                    // into the top state, since they are not on top.  Instead
16941                                    // give them the best state after that.
16942                                    clientProcState =
16943                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16944                                }
16945                            }
16946                        } else {
16947                            if (clientProcState <
16948                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16949                                clientProcState =
16950                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16951                            }
16952                        }
16953                        if (procState > clientProcState) {
16954                            procState = clientProcState;
16955                        }
16956                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16957                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16958                            app.pendingUiClean = true;
16959                        }
16960                        if (adjType != null) {
16961                            app.adjType = adjType;
16962                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16963                                    .REASON_SERVICE_IN_USE;
16964                            app.adjSource = cr.binding.client;
16965                            app.adjSourceProcState = clientProcState;
16966                            app.adjTarget = s.name;
16967                        }
16968                    }
16969                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16970                        app.treatLikeActivity = true;
16971                    }
16972                    final ActivityRecord a = cr.activity;
16973                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16974                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16975                                (a.visible || a.state == ActivityState.RESUMED
16976                                 || a.state == ActivityState.PAUSING)) {
16977                            adj = ProcessList.FOREGROUND_APP_ADJ;
16978                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16979                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16980                            }
16981                            app.cached = false;
16982                            app.adjType = "service";
16983                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16984                                    .REASON_SERVICE_IN_USE;
16985                            app.adjSource = a;
16986                            app.adjSourceProcState = procState;
16987                            app.adjTarget = s.name;
16988                        }
16989                    }
16990                }
16991            }
16992        }
16993
16994        for (int provi = app.pubProviders.size()-1;
16995                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16996                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16997                        || procState > ActivityManager.PROCESS_STATE_TOP);
16998                provi--) {
16999            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17000            for (int i = cpr.connections.size()-1;
17001                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17002                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17003                            || procState > ActivityManager.PROCESS_STATE_TOP);
17004                    i--) {
17005                ContentProviderConnection conn = cpr.connections.get(i);
17006                ProcessRecord client = conn.client;
17007                if (client == app) {
17008                    // Being our own client is not interesting.
17009                    continue;
17010                }
17011                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17012                int clientProcState = client.curProcState;
17013                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17014                    // If the other app is cached for any reason, for purposes here
17015                    // we are going to consider it empty.
17016                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17017                }
17018                if (adj > clientAdj) {
17019                    if (app.hasShownUi && app != mHomeProcess
17020                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17021                        app.adjType = "cch-ui-provider";
17022                    } else {
17023                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17024                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17025                        app.adjType = "provider";
17026                    }
17027                    app.cached &= client.cached;
17028                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17029                            .REASON_PROVIDER_IN_USE;
17030                    app.adjSource = client;
17031                    app.adjSourceProcState = clientProcState;
17032                    app.adjTarget = cpr.name;
17033                }
17034                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17035                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17036                        // Special handling of clients who are in the top state.
17037                        // We *may* want to consider this process to be in the
17038                        // top state as well, but only if there is not another
17039                        // reason for it to be running.  Being on the top is a
17040                        // special state, meaning you are specifically running
17041                        // for the current top app.  If the process is already
17042                        // running in the background for some other reason, it
17043                        // is more important to continue considering it to be
17044                        // in the background state.
17045                        mayBeTop = true;
17046                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17047                    } else {
17048                        // Special handling for above-top states (persistent
17049                        // processes).  These should not bring the current process
17050                        // into the top state, since they are not on top.  Instead
17051                        // give them the best state after that.
17052                        clientProcState =
17053                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17054                    }
17055                }
17056                if (procState > clientProcState) {
17057                    procState = clientProcState;
17058                }
17059                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17060                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17061                }
17062            }
17063            // If the provider has external (non-framework) process
17064            // dependencies, ensure that its adjustment is at least
17065            // FOREGROUND_APP_ADJ.
17066            if (cpr.hasExternalProcessHandles()) {
17067                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17068                    adj = ProcessList.FOREGROUND_APP_ADJ;
17069                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17070                    app.cached = false;
17071                    app.adjType = "provider";
17072                    app.adjTarget = cpr.name;
17073                }
17074                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17075                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17076                }
17077            }
17078        }
17079
17080        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17081            // A client of one of our services or providers is in the top state.  We
17082            // *may* want to be in the top state, but not if we are already running in
17083            // the background for some other reason.  For the decision here, we are going
17084            // to pick out a few specific states that we want to remain in when a client
17085            // is top (states that tend to be longer-term) and otherwise allow it to go
17086            // to the top state.
17087            switch (procState) {
17088                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17089                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17090                case ActivityManager.PROCESS_STATE_SERVICE:
17091                    // These all are longer-term states, so pull them up to the top
17092                    // of the background states, but not all the way to the top state.
17093                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17094                    break;
17095                default:
17096                    // Otherwise, top is a better choice, so take it.
17097                    procState = ActivityManager.PROCESS_STATE_TOP;
17098                    break;
17099            }
17100        }
17101
17102        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17103            if (app.hasClientActivities) {
17104                // This is a cached process, but with client activities.  Mark it so.
17105                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17106                app.adjType = "cch-client-act";
17107            } else if (app.treatLikeActivity) {
17108                // This is a cached process, but somebody wants us to treat it like it has
17109                // an activity, okay!
17110                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17111                app.adjType = "cch-as-act";
17112            }
17113        }
17114
17115        if (adj == ProcessList.SERVICE_ADJ) {
17116            if (doingAll) {
17117                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17118                mNewNumServiceProcs++;
17119                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17120                if (!app.serviceb) {
17121                    // This service isn't far enough down on the LRU list to
17122                    // normally be a B service, but if we are low on RAM and it
17123                    // is large we want to force it down since we would prefer to
17124                    // keep launcher over it.
17125                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17126                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17127                        app.serviceHighRam = true;
17128                        app.serviceb = true;
17129                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17130                    } else {
17131                        mNewNumAServiceProcs++;
17132                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17133                    }
17134                } else {
17135                    app.serviceHighRam = false;
17136                }
17137            }
17138            if (app.serviceb) {
17139                adj = ProcessList.SERVICE_B_ADJ;
17140            }
17141        }
17142
17143        app.curRawAdj = adj;
17144
17145        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17146        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17147        if (adj > app.maxAdj) {
17148            adj = app.maxAdj;
17149            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17150                schedGroup = Process.THREAD_GROUP_DEFAULT;
17151            }
17152        }
17153
17154        // Do final modification to adj.  Everything we do between here and applying
17155        // the final setAdj must be done in this function, because we will also use
17156        // it when computing the final cached adj later.  Note that we don't need to
17157        // worry about this for max adj above, since max adj will always be used to
17158        // keep it out of the cached vaues.
17159        app.curAdj = app.modifyRawOomAdj(adj);
17160        app.curSchedGroup = schedGroup;
17161        app.curProcState = procState;
17162        app.foregroundActivities = foregroundActivities;
17163
17164        return app.curRawAdj;
17165    }
17166
17167    /**
17168     * Schedule PSS collection of a process.
17169     */
17170    void requestPssLocked(ProcessRecord proc, int procState) {
17171        if (mPendingPssProcesses.contains(proc)) {
17172            return;
17173        }
17174        if (mPendingPssProcesses.size() == 0) {
17175            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17176        }
17177        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17178        proc.pssProcState = procState;
17179        mPendingPssProcesses.add(proc);
17180    }
17181
17182    /**
17183     * Schedule PSS collection of all processes.
17184     */
17185    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17186        if (!always) {
17187            if (now < (mLastFullPssTime +
17188                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17189                return;
17190            }
17191        }
17192        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17193        mLastFullPssTime = now;
17194        mFullPssPending = true;
17195        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17196        mPendingPssProcesses.clear();
17197        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17198            ProcessRecord app = mLruProcesses.get(i);
17199            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17200                app.pssProcState = app.setProcState;
17201                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17202                        isSleeping(), now);
17203                mPendingPssProcesses.add(app);
17204            }
17205        }
17206        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17207    }
17208
17209    /**
17210     * Ask a given process to GC right now.
17211     */
17212    final void performAppGcLocked(ProcessRecord app) {
17213        try {
17214            app.lastRequestedGc = SystemClock.uptimeMillis();
17215            if (app.thread != null) {
17216                if (app.reportLowMemory) {
17217                    app.reportLowMemory = false;
17218                    app.thread.scheduleLowMemory();
17219                } else {
17220                    app.thread.processInBackground();
17221                }
17222            }
17223        } catch (Exception e) {
17224            // whatever.
17225        }
17226    }
17227
17228    /**
17229     * Returns true if things are idle enough to perform GCs.
17230     */
17231    private final boolean canGcNowLocked() {
17232        boolean processingBroadcasts = false;
17233        for (BroadcastQueue q : mBroadcastQueues) {
17234            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17235                processingBroadcasts = true;
17236            }
17237        }
17238        return !processingBroadcasts
17239                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17240    }
17241
17242    /**
17243     * Perform GCs on all processes that are waiting for it, but only
17244     * if things are idle.
17245     */
17246    final void performAppGcsLocked() {
17247        final int N = mProcessesToGc.size();
17248        if (N <= 0) {
17249            return;
17250        }
17251        if (canGcNowLocked()) {
17252            while (mProcessesToGc.size() > 0) {
17253                ProcessRecord proc = mProcessesToGc.remove(0);
17254                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17255                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17256                            <= SystemClock.uptimeMillis()) {
17257                        // To avoid spamming the system, we will GC processes one
17258                        // at a time, waiting a few seconds between each.
17259                        performAppGcLocked(proc);
17260                        scheduleAppGcsLocked();
17261                        return;
17262                    } else {
17263                        // It hasn't been long enough since we last GCed this
17264                        // process...  put it in the list to wait for its time.
17265                        addProcessToGcListLocked(proc);
17266                        break;
17267                    }
17268                }
17269            }
17270
17271            scheduleAppGcsLocked();
17272        }
17273    }
17274
17275    /**
17276     * If all looks good, perform GCs on all processes waiting for them.
17277     */
17278    final void performAppGcsIfAppropriateLocked() {
17279        if (canGcNowLocked()) {
17280            performAppGcsLocked();
17281            return;
17282        }
17283        // Still not idle, wait some more.
17284        scheduleAppGcsLocked();
17285    }
17286
17287    /**
17288     * Schedule the execution of all pending app GCs.
17289     */
17290    final void scheduleAppGcsLocked() {
17291        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17292
17293        if (mProcessesToGc.size() > 0) {
17294            // Schedule a GC for the time to the next process.
17295            ProcessRecord proc = mProcessesToGc.get(0);
17296            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17297
17298            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17299            long now = SystemClock.uptimeMillis();
17300            if (when < (now+GC_TIMEOUT)) {
17301                when = now + GC_TIMEOUT;
17302            }
17303            mHandler.sendMessageAtTime(msg, when);
17304        }
17305    }
17306
17307    /**
17308     * Add a process to the array of processes waiting to be GCed.  Keeps the
17309     * list in sorted order by the last GC time.  The process can't already be
17310     * on the list.
17311     */
17312    final void addProcessToGcListLocked(ProcessRecord proc) {
17313        boolean added = false;
17314        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17315            if (mProcessesToGc.get(i).lastRequestedGc <
17316                    proc.lastRequestedGc) {
17317                added = true;
17318                mProcessesToGc.add(i+1, proc);
17319                break;
17320            }
17321        }
17322        if (!added) {
17323            mProcessesToGc.add(0, proc);
17324        }
17325    }
17326
17327    /**
17328     * Set up to ask a process to GC itself.  This will either do it
17329     * immediately, or put it on the list of processes to gc the next
17330     * time things are idle.
17331     */
17332    final void scheduleAppGcLocked(ProcessRecord app) {
17333        long now = SystemClock.uptimeMillis();
17334        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17335            return;
17336        }
17337        if (!mProcessesToGc.contains(app)) {
17338            addProcessToGcListLocked(app);
17339            scheduleAppGcsLocked();
17340        }
17341    }
17342
17343    final void checkExcessivePowerUsageLocked(boolean doKills) {
17344        updateCpuStatsNow();
17345
17346        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17347        boolean doWakeKills = doKills;
17348        boolean doCpuKills = doKills;
17349        if (mLastPowerCheckRealtime == 0) {
17350            doWakeKills = false;
17351        }
17352        if (mLastPowerCheckUptime == 0) {
17353            doCpuKills = false;
17354        }
17355        if (stats.isScreenOn()) {
17356            doWakeKills = false;
17357        }
17358        final long curRealtime = SystemClock.elapsedRealtime();
17359        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17360        final long curUptime = SystemClock.uptimeMillis();
17361        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17362        mLastPowerCheckRealtime = curRealtime;
17363        mLastPowerCheckUptime = curUptime;
17364        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17365            doWakeKills = false;
17366        }
17367        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17368            doCpuKills = false;
17369        }
17370        int i = mLruProcesses.size();
17371        while (i > 0) {
17372            i--;
17373            ProcessRecord app = mLruProcesses.get(i);
17374            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17375                long wtime;
17376                synchronized (stats) {
17377                    wtime = stats.getProcessWakeTime(app.info.uid,
17378                            app.pid, curRealtime);
17379                }
17380                long wtimeUsed = wtime - app.lastWakeTime;
17381                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17382                if (DEBUG_POWER) {
17383                    StringBuilder sb = new StringBuilder(128);
17384                    sb.append("Wake for ");
17385                    app.toShortString(sb);
17386                    sb.append(": over ");
17387                    TimeUtils.formatDuration(realtimeSince, sb);
17388                    sb.append(" used ");
17389                    TimeUtils.formatDuration(wtimeUsed, sb);
17390                    sb.append(" (");
17391                    sb.append((wtimeUsed*100)/realtimeSince);
17392                    sb.append("%)");
17393                    Slog.i(TAG, sb.toString());
17394                    sb.setLength(0);
17395                    sb.append("CPU for ");
17396                    app.toShortString(sb);
17397                    sb.append(": over ");
17398                    TimeUtils.formatDuration(uptimeSince, sb);
17399                    sb.append(" used ");
17400                    TimeUtils.formatDuration(cputimeUsed, sb);
17401                    sb.append(" (");
17402                    sb.append((cputimeUsed*100)/uptimeSince);
17403                    sb.append("%)");
17404                    Slog.i(TAG, sb.toString());
17405                }
17406                // If a process has held a wake lock for more
17407                // than 50% of the time during this period,
17408                // that sounds bad.  Kill!
17409                if (doWakeKills && realtimeSince > 0
17410                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17411                    synchronized (stats) {
17412                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17413                                realtimeSince, wtimeUsed);
17414                    }
17415                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17416                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17417                } else if (doCpuKills && uptimeSince > 0
17418                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17419                    synchronized (stats) {
17420                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17421                                uptimeSince, cputimeUsed);
17422                    }
17423                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17424                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17425                } else {
17426                    app.lastWakeTime = wtime;
17427                    app.lastCpuTime = app.curCpuTime;
17428                }
17429            }
17430        }
17431    }
17432
17433    private final boolean applyOomAdjLocked(ProcessRecord app,
17434            ProcessRecord TOP_APP, boolean doingAll, long now) {
17435        boolean success = true;
17436
17437        if (app.curRawAdj != app.setRawAdj) {
17438            app.setRawAdj = app.curRawAdj;
17439        }
17440
17441        int changes = 0;
17442
17443        if (app.curAdj != app.setAdj) {
17444            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17445            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17446                TAG, "Set " + app.pid + " " + app.processName +
17447                " adj " + app.curAdj + ": " + app.adjType);
17448            app.setAdj = app.curAdj;
17449        }
17450
17451        if (app.setSchedGroup != app.curSchedGroup) {
17452            app.setSchedGroup = app.curSchedGroup;
17453            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17454                    "Setting process group of " + app.processName
17455                    + " to " + app.curSchedGroup);
17456            if (app.waitingToKill != null &&
17457                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17458                app.kill(app.waitingToKill, true);
17459                success = false;
17460            } else {
17461                if (true) {
17462                    long oldId = Binder.clearCallingIdentity();
17463                    try {
17464                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17465                    } catch (Exception e) {
17466                        Slog.w(TAG, "Failed setting process group of " + app.pid
17467                                + " to " + app.curSchedGroup);
17468                        e.printStackTrace();
17469                    } finally {
17470                        Binder.restoreCallingIdentity(oldId);
17471                    }
17472                } else {
17473                    if (app.thread != null) {
17474                        try {
17475                            app.thread.setSchedulingGroup(app.curSchedGroup);
17476                        } catch (RemoteException e) {
17477                        }
17478                    }
17479                }
17480                Process.setSwappiness(app.pid,
17481                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17482            }
17483        }
17484        if (app.repForegroundActivities != app.foregroundActivities) {
17485            app.repForegroundActivities = app.foregroundActivities;
17486            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17487        }
17488        if (app.repProcState != app.curProcState) {
17489            app.repProcState = app.curProcState;
17490            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17491            if (app.thread != null) {
17492                try {
17493                    if (false) {
17494                        //RuntimeException h = new RuntimeException("here");
17495                        Slog.i(TAG, "Sending new process state " + app.repProcState
17496                                + " to " + app /*, h*/);
17497                    }
17498                    app.thread.setProcessState(app.repProcState);
17499                } catch (RemoteException e) {
17500                }
17501            }
17502        }
17503        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17504                app.setProcState)) {
17505            app.lastStateTime = now;
17506            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17507                    isSleeping(), now);
17508            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17509                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17510                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17511                    + (app.nextPssTime-now) + ": " + app);
17512        } else {
17513            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17514                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17515                requestPssLocked(app, app.setProcState);
17516                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17517                        isSleeping(), now);
17518            } else if (false && DEBUG_PSS) {
17519                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17520            }
17521        }
17522        if (app.setProcState != app.curProcState) {
17523            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17524                    "Proc state change of " + app.processName
17525                    + " to " + app.curProcState);
17526            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17527            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17528            if (setImportant && !curImportant) {
17529                // This app is no longer something we consider important enough to allow to
17530                // use arbitrary amounts of battery power.  Note
17531                // its current wake lock time to later know to kill it if
17532                // it is not behaving well.
17533                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17534                synchronized (stats) {
17535                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17536                            app.pid, SystemClock.elapsedRealtime());
17537                }
17538                app.lastCpuTime = app.curCpuTime;
17539
17540            }
17541            app.setProcState = app.curProcState;
17542            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17543                app.notCachedSinceIdle = false;
17544            }
17545            if (!doingAll) {
17546                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17547            } else {
17548                app.procStateChanged = true;
17549            }
17550        }
17551
17552        if (changes != 0) {
17553            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17554            int i = mPendingProcessChanges.size()-1;
17555            ProcessChangeItem item = null;
17556            while (i >= 0) {
17557                item = mPendingProcessChanges.get(i);
17558                if (item.pid == app.pid) {
17559                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17560                    break;
17561                }
17562                i--;
17563            }
17564            if (i < 0) {
17565                // No existing item in pending changes; need a new one.
17566                final int NA = mAvailProcessChanges.size();
17567                if (NA > 0) {
17568                    item = mAvailProcessChanges.remove(NA-1);
17569                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17570                } else {
17571                    item = new ProcessChangeItem();
17572                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17573                }
17574                item.changes = 0;
17575                item.pid = app.pid;
17576                item.uid = app.info.uid;
17577                if (mPendingProcessChanges.size() == 0) {
17578                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17579                            "*** Enqueueing dispatch processes changed!");
17580                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17581                }
17582                mPendingProcessChanges.add(item);
17583            }
17584            item.changes |= changes;
17585            item.processState = app.repProcState;
17586            item.foregroundActivities = app.repForegroundActivities;
17587            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17588                    + Integer.toHexString(System.identityHashCode(item))
17589                    + " " + app.toShortString() + ": changes=" + item.changes
17590                    + " procState=" + item.processState
17591                    + " foreground=" + item.foregroundActivities
17592                    + " type=" + app.adjType + " source=" + app.adjSource
17593                    + " target=" + app.adjTarget);
17594        }
17595
17596        return success;
17597    }
17598
17599    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17600        if (proc.thread != null) {
17601            if (proc.baseProcessTracker != null) {
17602                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17603            }
17604            if (proc.repProcState >= 0) {
17605                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17606                        proc.repProcState);
17607            }
17608        }
17609    }
17610
17611    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17612            ProcessRecord TOP_APP, boolean doingAll, long now) {
17613        if (app.thread == null) {
17614            return false;
17615        }
17616
17617        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17618
17619        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17620    }
17621
17622    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17623            boolean oomAdj) {
17624        if (isForeground != proc.foregroundServices) {
17625            proc.foregroundServices = isForeground;
17626            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17627                    proc.info.uid);
17628            if (isForeground) {
17629                if (curProcs == null) {
17630                    curProcs = new ArrayList<ProcessRecord>();
17631                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17632                }
17633                if (!curProcs.contains(proc)) {
17634                    curProcs.add(proc);
17635                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17636                            proc.info.packageName, proc.info.uid);
17637                }
17638            } else {
17639                if (curProcs != null) {
17640                    if (curProcs.remove(proc)) {
17641                        mBatteryStatsService.noteEvent(
17642                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17643                                proc.info.packageName, proc.info.uid);
17644                        if (curProcs.size() <= 0) {
17645                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17646                        }
17647                    }
17648                }
17649            }
17650            if (oomAdj) {
17651                updateOomAdjLocked();
17652            }
17653        }
17654    }
17655
17656    private final ActivityRecord resumedAppLocked() {
17657        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17658        String pkg;
17659        int uid;
17660        if (act != null) {
17661            pkg = act.packageName;
17662            uid = act.info.applicationInfo.uid;
17663        } else {
17664            pkg = null;
17665            uid = -1;
17666        }
17667        // Has the UID or resumed package name changed?
17668        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17669                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17670            if (mCurResumedPackage != null) {
17671                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17672                        mCurResumedPackage, mCurResumedUid);
17673            }
17674            mCurResumedPackage = pkg;
17675            mCurResumedUid = uid;
17676            if (mCurResumedPackage != null) {
17677                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17678                        mCurResumedPackage, mCurResumedUid);
17679            }
17680        }
17681        return act;
17682    }
17683
17684    final boolean updateOomAdjLocked(ProcessRecord app) {
17685        final ActivityRecord TOP_ACT = resumedAppLocked();
17686        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17687        final boolean wasCached = app.cached;
17688
17689        mAdjSeq++;
17690
17691        // This is the desired cached adjusment we want to tell it to use.
17692        // If our app is currently cached, we know it, and that is it.  Otherwise,
17693        // we don't know it yet, and it needs to now be cached we will then
17694        // need to do a complete oom adj.
17695        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17696                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17697        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17698                SystemClock.uptimeMillis());
17699        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17700            // Changed to/from cached state, so apps after it in the LRU
17701            // list may also be changed.
17702            updateOomAdjLocked();
17703        }
17704        return success;
17705    }
17706
17707    final void updateOomAdjLocked() {
17708        final ActivityRecord TOP_ACT = resumedAppLocked();
17709        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17710        final long now = SystemClock.uptimeMillis();
17711        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17712        final int N = mLruProcesses.size();
17713
17714        if (false) {
17715            RuntimeException e = new RuntimeException();
17716            e.fillInStackTrace();
17717            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17718        }
17719
17720        mAdjSeq++;
17721        mNewNumServiceProcs = 0;
17722        mNewNumAServiceProcs = 0;
17723
17724        final int emptyProcessLimit;
17725        final int cachedProcessLimit;
17726        if (mProcessLimit <= 0) {
17727            emptyProcessLimit = cachedProcessLimit = 0;
17728        } else if (mProcessLimit == 1) {
17729            emptyProcessLimit = 1;
17730            cachedProcessLimit = 0;
17731        } else {
17732            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17733            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17734        }
17735
17736        // Let's determine how many processes we have running vs.
17737        // how many slots we have for background processes; we may want
17738        // to put multiple processes in a slot of there are enough of
17739        // them.
17740        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17741                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17742        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17743        if (numEmptyProcs > cachedProcessLimit) {
17744            // If there are more empty processes than our limit on cached
17745            // processes, then use the cached process limit for the factor.
17746            // This ensures that the really old empty processes get pushed
17747            // down to the bottom, so if we are running low on memory we will
17748            // have a better chance at keeping around more cached processes
17749            // instead of a gazillion empty processes.
17750            numEmptyProcs = cachedProcessLimit;
17751        }
17752        int emptyFactor = numEmptyProcs/numSlots;
17753        if (emptyFactor < 1) emptyFactor = 1;
17754        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17755        if (cachedFactor < 1) cachedFactor = 1;
17756        int stepCached = 0;
17757        int stepEmpty = 0;
17758        int numCached = 0;
17759        int numEmpty = 0;
17760        int numTrimming = 0;
17761
17762        mNumNonCachedProcs = 0;
17763        mNumCachedHiddenProcs = 0;
17764
17765        // First update the OOM adjustment for each of the
17766        // application processes based on their current state.
17767        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17768        int nextCachedAdj = curCachedAdj+1;
17769        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17770        int nextEmptyAdj = curEmptyAdj+2;
17771        for (int i=N-1; i>=0; i--) {
17772            ProcessRecord app = mLruProcesses.get(i);
17773            if (!app.killedByAm && app.thread != null) {
17774                app.procStateChanged = false;
17775                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17776
17777                // If we haven't yet assigned the final cached adj
17778                // to the process, do that now.
17779                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17780                    switch (app.curProcState) {
17781                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17782                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17783                            // This process is a cached process holding activities...
17784                            // assign it the next cached value for that type, and then
17785                            // step that cached level.
17786                            app.curRawAdj = curCachedAdj;
17787                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17788                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17789                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17790                                    + ")");
17791                            if (curCachedAdj != nextCachedAdj) {
17792                                stepCached++;
17793                                if (stepCached >= cachedFactor) {
17794                                    stepCached = 0;
17795                                    curCachedAdj = nextCachedAdj;
17796                                    nextCachedAdj += 2;
17797                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17798                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17799                                    }
17800                                }
17801                            }
17802                            break;
17803                        default:
17804                            // For everything else, assign next empty cached process
17805                            // level and bump that up.  Note that this means that
17806                            // long-running services that have dropped down to the
17807                            // cached level will be treated as empty (since their process
17808                            // state is still as a service), which is what we want.
17809                            app.curRawAdj = curEmptyAdj;
17810                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17811                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17812                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17813                                    + ")");
17814                            if (curEmptyAdj != nextEmptyAdj) {
17815                                stepEmpty++;
17816                                if (stepEmpty >= emptyFactor) {
17817                                    stepEmpty = 0;
17818                                    curEmptyAdj = nextEmptyAdj;
17819                                    nextEmptyAdj += 2;
17820                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17821                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17822                                    }
17823                                }
17824                            }
17825                            break;
17826                    }
17827                }
17828
17829                applyOomAdjLocked(app, TOP_APP, true, now);
17830
17831                // Count the number of process types.
17832                switch (app.curProcState) {
17833                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17834                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17835                        mNumCachedHiddenProcs++;
17836                        numCached++;
17837                        if (numCached > cachedProcessLimit) {
17838                            app.kill("cached #" + numCached, true);
17839                        }
17840                        break;
17841                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17842                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17843                                && app.lastActivityTime < oldTime) {
17844                            app.kill("empty for "
17845                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17846                                    / 1000) + "s", true);
17847                        } else {
17848                            numEmpty++;
17849                            if (numEmpty > emptyProcessLimit) {
17850                                app.kill("empty #" + numEmpty, true);
17851                            }
17852                        }
17853                        break;
17854                    default:
17855                        mNumNonCachedProcs++;
17856                        break;
17857                }
17858
17859                if (app.isolated && app.services.size() <= 0) {
17860                    // If this is an isolated process, and there are no
17861                    // services running in it, then the process is no longer
17862                    // needed.  We agressively kill these because we can by
17863                    // definition not re-use the same process again, and it is
17864                    // good to avoid having whatever code was running in them
17865                    // left sitting around after no longer needed.
17866                    app.kill("isolated not needed", true);
17867                }
17868
17869                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17870                        && !app.killedByAm) {
17871                    numTrimming++;
17872                }
17873            }
17874        }
17875
17876        mNumServiceProcs = mNewNumServiceProcs;
17877
17878        // Now determine the memory trimming level of background processes.
17879        // Unfortunately we need to start at the back of the list to do this
17880        // properly.  We only do this if the number of background apps we
17881        // are managing to keep around is less than half the maximum we desire;
17882        // if we are keeping a good number around, we'll let them use whatever
17883        // memory they want.
17884        final int numCachedAndEmpty = numCached + numEmpty;
17885        int memFactor;
17886        if (numCached <= ProcessList.TRIM_CACHED_APPS
17887                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17888            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17889                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17890            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17891                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17892            } else {
17893                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17894            }
17895        } else {
17896            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17897        }
17898        // We always allow the memory level to go up (better).  We only allow it to go
17899        // down if we are in a state where that is allowed, *and* the total number of processes
17900        // has gone down since last time.
17901        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17902                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17903                + " last=" + mLastNumProcesses);
17904        if (memFactor > mLastMemoryLevel) {
17905            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17906                memFactor = mLastMemoryLevel;
17907                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17908            }
17909        }
17910        mLastMemoryLevel = memFactor;
17911        mLastNumProcesses = mLruProcesses.size();
17912        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17913        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17914        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17915            if (mLowRamStartTime == 0) {
17916                mLowRamStartTime = now;
17917            }
17918            int step = 0;
17919            int fgTrimLevel;
17920            switch (memFactor) {
17921                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17922                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17923                    break;
17924                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17925                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17926                    break;
17927                default:
17928                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17929                    break;
17930            }
17931            int factor = numTrimming/3;
17932            int minFactor = 2;
17933            if (mHomeProcess != null) minFactor++;
17934            if (mPreviousProcess != null) minFactor++;
17935            if (factor < minFactor) factor = minFactor;
17936            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17937            for (int i=N-1; i>=0; i--) {
17938                ProcessRecord app = mLruProcesses.get(i);
17939                if (allChanged || app.procStateChanged) {
17940                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17941                    app.procStateChanged = false;
17942                }
17943                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17944                        && !app.killedByAm) {
17945                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17946                        try {
17947                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17948                                    "Trimming memory of " + app.processName
17949                                    + " to " + curLevel);
17950                            app.thread.scheduleTrimMemory(curLevel);
17951                        } catch (RemoteException e) {
17952                        }
17953                        if (false) {
17954                            // For now we won't do this; our memory trimming seems
17955                            // to be good enough at this point that destroying
17956                            // activities causes more harm than good.
17957                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17958                                    && app != mHomeProcess && app != mPreviousProcess) {
17959                                // Need to do this on its own message because the stack may not
17960                                // be in a consistent state at this point.
17961                                // For these apps we will also finish their activities
17962                                // to help them free memory.
17963                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17964                            }
17965                        }
17966                    }
17967                    app.trimMemoryLevel = curLevel;
17968                    step++;
17969                    if (step >= factor) {
17970                        step = 0;
17971                        switch (curLevel) {
17972                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17973                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17974                                break;
17975                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17976                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17977                                break;
17978                        }
17979                    }
17980                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17981                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17982                            && app.thread != null) {
17983                        try {
17984                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17985                                    "Trimming memory of heavy-weight " + app.processName
17986                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17987                            app.thread.scheduleTrimMemory(
17988                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17989                        } catch (RemoteException e) {
17990                        }
17991                    }
17992                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17993                } else {
17994                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17995                            || app.systemNoUi) && app.pendingUiClean) {
17996                        // If this application is now in the background and it
17997                        // had done UI, then give it the special trim level to
17998                        // have it free UI resources.
17999                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18000                        if (app.trimMemoryLevel < level && app.thread != null) {
18001                            try {
18002                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18003                                        "Trimming memory of bg-ui " + app.processName
18004                                        + " to " + level);
18005                                app.thread.scheduleTrimMemory(level);
18006                            } catch (RemoteException e) {
18007                            }
18008                        }
18009                        app.pendingUiClean = false;
18010                    }
18011                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18012                        try {
18013                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18014                                    "Trimming memory of fg " + app.processName
18015                                    + " to " + fgTrimLevel);
18016                            app.thread.scheduleTrimMemory(fgTrimLevel);
18017                        } catch (RemoteException e) {
18018                        }
18019                    }
18020                    app.trimMemoryLevel = fgTrimLevel;
18021                }
18022            }
18023        } else {
18024            if (mLowRamStartTime != 0) {
18025                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18026                mLowRamStartTime = 0;
18027            }
18028            for (int i=N-1; i>=0; i--) {
18029                ProcessRecord app = mLruProcesses.get(i);
18030                if (allChanged || app.procStateChanged) {
18031                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18032                    app.procStateChanged = false;
18033                }
18034                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18035                        || app.systemNoUi) && app.pendingUiClean) {
18036                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18037                            && app.thread != null) {
18038                        try {
18039                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18040                                    "Trimming memory of ui hidden " + app.processName
18041                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18042                            app.thread.scheduleTrimMemory(
18043                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18044                        } catch (RemoteException e) {
18045                        }
18046                    }
18047                    app.pendingUiClean = false;
18048                }
18049                app.trimMemoryLevel = 0;
18050            }
18051        }
18052
18053        if (mAlwaysFinishActivities) {
18054            // Need to do this on its own message because the stack may not
18055            // be in a consistent state at this point.
18056            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18057        }
18058
18059        if (allChanged) {
18060            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18061        }
18062
18063        if (mProcessStats.shouldWriteNowLocked(now)) {
18064            mHandler.post(new Runnable() {
18065                @Override public void run() {
18066                    synchronized (ActivityManagerService.this) {
18067                        mProcessStats.writeStateAsyncLocked();
18068                    }
18069                }
18070            });
18071        }
18072
18073        if (DEBUG_OOM_ADJ) {
18074            if (false) {
18075                RuntimeException here = new RuntimeException("here");
18076                here.fillInStackTrace();
18077                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18078            } else {
18079                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18080            }
18081        }
18082    }
18083
18084    final void trimApplications() {
18085        synchronized (this) {
18086            int i;
18087
18088            // First remove any unused application processes whose package
18089            // has been removed.
18090            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18091                final ProcessRecord app = mRemovedProcesses.get(i);
18092                if (app.activities.size() == 0
18093                        && app.curReceiver == null && app.services.size() == 0) {
18094                    Slog.i(
18095                        TAG, "Exiting empty application process "
18096                        + app.processName + " ("
18097                        + (app.thread != null ? app.thread.asBinder() : null)
18098                        + ")\n");
18099                    if (app.pid > 0 && app.pid != MY_PID) {
18100                        app.kill("empty", false);
18101                    } else {
18102                        try {
18103                            app.thread.scheduleExit();
18104                        } catch (Exception e) {
18105                            // Ignore exceptions.
18106                        }
18107                    }
18108                    cleanUpApplicationRecordLocked(app, false, true, -1);
18109                    mRemovedProcesses.remove(i);
18110
18111                    if (app.persistent) {
18112                        addAppLocked(app.info, false, null /* ABI override */);
18113                    }
18114                }
18115            }
18116
18117            // Now update the oom adj for all processes.
18118            updateOomAdjLocked();
18119        }
18120    }
18121
18122    /** This method sends the specified signal to each of the persistent apps */
18123    public void signalPersistentProcesses(int sig) throws RemoteException {
18124        if (sig != Process.SIGNAL_USR1) {
18125            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18126        }
18127
18128        synchronized (this) {
18129            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18130                    != PackageManager.PERMISSION_GRANTED) {
18131                throw new SecurityException("Requires permission "
18132                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18133            }
18134
18135            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18136                ProcessRecord r = mLruProcesses.get(i);
18137                if (r.thread != null && r.persistent) {
18138                    Process.sendSignal(r.pid, sig);
18139                }
18140            }
18141        }
18142    }
18143
18144    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18145        if (proc == null || proc == mProfileProc) {
18146            proc = mProfileProc;
18147            profileType = mProfileType;
18148            clearProfilerLocked();
18149        }
18150        if (proc == null) {
18151            return;
18152        }
18153        try {
18154            proc.thread.profilerControl(false, null, profileType);
18155        } catch (RemoteException e) {
18156            throw new IllegalStateException("Process disappeared");
18157        }
18158    }
18159
18160    private void clearProfilerLocked() {
18161        if (mProfileFd != null) {
18162            try {
18163                mProfileFd.close();
18164            } catch (IOException e) {
18165            }
18166        }
18167        mProfileApp = null;
18168        mProfileProc = null;
18169        mProfileFile = null;
18170        mProfileType = 0;
18171        mAutoStopProfiler = false;
18172        mSamplingInterval = 0;
18173    }
18174
18175    public boolean profileControl(String process, int userId, boolean start,
18176            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18177
18178        try {
18179            synchronized (this) {
18180                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18181                // its own permission.
18182                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18183                        != PackageManager.PERMISSION_GRANTED) {
18184                    throw new SecurityException("Requires permission "
18185                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18186                }
18187
18188                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18189                    throw new IllegalArgumentException("null profile info or fd");
18190                }
18191
18192                ProcessRecord proc = null;
18193                if (process != null) {
18194                    proc = findProcessLocked(process, userId, "profileControl");
18195                }
18196
18197                if (start && (proc == null || proc.thread == null)) {
18198                    throw new IllegalArgumentException("Unknown process: " + process);
18199                }
18200
18201                if (start) {
18202                    stopProfilerLocked(null, 0);
18203                    setProfileApp(proc.info, proc.processName, profilerInfo);
18204                    mProfileProc = proc;
18205                    mProfileType = profileType;
18206                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18207                    try {
18208                        fd = fd.dup();
18209                    } catch (IOException e) {
18210                        fd = null;
18211                    }
18212                    profilerInfo.profileFd = fd;
18213                    proc.thread.profilerControl(start, profilerInfo, profileType);
18214                    fd = null;
18215                    mProfileFd = null;
18216                } else {
18217                    stopProfilerLocked(proc, profileType);
18218                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18219                        try {
18220                            profilerInfo.profileFd.close();
18221                        } catch (IOException e) {
18222                        }
18223                    }
18224                }
18225
18226                return true;
18227            }
18228        } catch (RemoteException e) {
18229            throw new IllegalStateException("Process disappeared");
18230        } finally {
18231            if (profilerInfo != null && profilerInfo.profileFd != null) {
18232                try {
18233                    profilerInfo.profileFd.close();
18234                } catch (IOException e) {
18235                }
18236            }
18237        }
18238    }
18239
18240    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18241        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18242                userId, true, ALLOW_FULL_ONLY, callName, null);
18243        ProcessRecord proc = null;
18244        try {
18245            int pid = Integer.parseInt(process);
18246            synchronized (mPidsSelfLocked) {
18247                proc = mPidsSelfLocked.get(pid);
18248            }
18249        } catch (NumberFormatException e) {
18250        }
18251
18252        if (proc == null) {
18253            ArrayMap<String, SparseArray<ProcessRecord>> all
18254                    = mProcessNames.getMap();
18255            SparseArray<ProcessRecord> procs = all.get(process);
18256            if (procs != null && procs.size() > 0) {
18257                proc = procs.valueAt(0);
18258                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18259                    for (int i=1; i<procs.size(); i++) {
18260                        ProcessRecord thisProc = procs.valueAt(i);
18261                        if (thisProc.userId == userId) {
18262                            proc = thisProc;
18263                            break;
18264                        }
18265                    }
18266                }
18267            }
18268        }
18269
18270        return proc;
18271    }
18272
18273    public boolean dumpHeap(String process, int userId, boolean managed,
18274            String path, ParcelFileDescriptor fd) throws RemoteException {
18275
18276        try {
18277            synchronized (this) {
18278                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18279                // its own permission (same as profileControl).
18280                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18281                        != PackageManager.PERMISSION_GRANTED) {
18282                    throw new SecurityException("Requires permission "
18283                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18284                }
18285
18286                if (fd == null) {
18287                    throw new IllegalArgumentException("null fd");
18288                }
18289
18290                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18291                if (proc == null || proc.thread == null) {
18292                    throw new IllegalArgumentException("Unknown process: " + process);
18293                }
18294
18295                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18296                if (!isDebuggable) {
18297                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18298                        throw new SecurityException("Process not debuggable: " + proc);
18299                    }
18300                }
18301
18302                proc.thread.dumpHeap(managed, path, fd);
18303                fd = null;
18304                return true;
18305            }
18306        } catch (RemoteException e) {
18307            throw new IllegalStateException("Process disappeared");
18308        } finally {
18309            if (fd != null) {
18310                try {
18311                    fd.close();
18312                } catch (IOException e) {
18313                }
18314            }
18315        }
18316    }
18317
18318    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18319    public void monitor() {
18320        synchronized (this) { }
18321    }
18322
18323    void onCoreSettingsChange(Bundle settings) {
18324        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18325            ProcessRecord processRecord = mLruProcesses.get(i);
18326            try {
18327                if (processRecord.thread != null) {
18328                    processRecord.thread.setCoreSettings(settings);
18329                }
18330            } catch (RemoteException re) {
18331                /* ignore */
18332            }
18333        }
18334    }
18335
18336    // Multi-user methods
18337
18338    /**
18339     * Start user, if its not already running, but don't bring it to foreground.
18340     */
18341    @Override
18342    public boolean startUserInBackground(final int userId) {
18343        return startUser(userId, /* foreground */ false);
18344    }
18345
18346    /**
18347     * Start user, if its not already running, and bring it to foreground.
18348     */
18349    boolean startUserInForeground(final int userId, Dialog dlg) {
18350        boolean result = startUser(userId, /* foreground */ true);
18351        dlg.dismiss();
18352        return result;
18353    }
18354
18355    /**
18356     * Refreshes the list of users related to the current user when either a
18357     * user switch happens or when a new related user is started in the
18358     * background.
18359     */
18360    private void updateCurrentProfileIdsLocked() {
18361        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18362                mCurrentUserId, false /* enabledOnly */);
18363        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18364        for (int i = 0; i < currentProfileIds.length; i++) {
18365            currentProfileIds[i] = profiles.get(i).id;
18366        }
18367        mCurrentProfileIds = currentProfileIds;
18368
18369        synchronized (mUserProfileGroupIdsSelfLocked) {
18370            mUserProfileGroupIdsSelfLocked.clear();
18371            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18372            for (int i = 0; i < users.size(); i++) {
18373                UserInfo user = users.get(i);
18374                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18375                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18376                }
18377            }
18378        }
18379    }
18380
18381    private Set getProfileIdsLocked(int userId) {
18382        Set userIds = new HashSet<Integer>();
18383        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18384                userId, false /* enabledOnly */);
18385        for (UserInfo user : profiles) {
18386            userIds.add(Integer.valueOf(user.id));
18387        }
18388        return userIds;
18389    }
18390
18391    @Override
18392    public boolean switchUser(final int userId) {
18393        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18394        String userName;
18395        synchronized (this) {
18396            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18397            if (userInfo == null) {
18398                Slog.w(TAG, "No user info for user #" + userId);
18399                return false;
18400            }
18401            if (userInfo.isManagedProfile()) {
18402                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18403                return false;
18404            }
18405            userName = userInfo.name;
18406            mTargetUserId = userId;
18407        }
18408        mHandler.removeMessages(START_USER_SWITCH_MSG);
18409        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18410        return true;
18411    }
18412
18413    private void showUserSwitchDialog(int userId, String userName) {
18414        // The dialog will show and then initiate the user switch by calling startUserInForeground
18415        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18416                true /* above system */);
18417        d.show();
18418    }
18419
18420    private boolean startUser(final int userId, final boolean foreground) {
18421        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18422                != PackageManager.PERMISSION_GRANTED) {
18423            String msg = "Permission Denial: switchUser() from pid="
18424                    + Binder.getCallingPid()
18425                    + ", uid=" + Binder.getCallingUid()
18426                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18427            Slog.w(TAG, msg);
18428            throw new SecurityException(msg);
18429        }
18430
18431        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18432
18433        final long ident = Binder.clearCallingIdentity();
18434        try {
18435            synchronized (this) {
18436                final int oldUserId = mCurrentUserId;
18437                if (oldUserId == userId) {
18438                    return true;
18439                }
18440
18441                mStackSupervisor.setLockTaskModeLocked(null, false);
18442
18443                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18444                if (userInfo == null) {
18445                    Slog.w(TAG, "No user info for user #" + userId);
18446                    return false;
18447                }
18448                if (foreground && userInfo.isManagedProfile()) {
18449                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18450                    return false;
18451                }
18452
18453                if (foreground) {
18454                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18455                            R.anim.screen_user_enter);
18456                }
18457
18458                boolean needStart = false;
18459
18460                // If the user we are switching to is not currently started, then
18461                // we need to start it now.
18462                if (mStartedUsers.get(userId) == null) {
18463                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18464                    updateStartedUserArrayLocked();
18465                    needStart = true;
18466                }
18467
18468                final Integer userIdInt = Integer.valueOf(userId);
18469                mUserLru.remove(userIdInt);
18470                mUserLru.add(userIdInt);
18471
18472                if (foreground) {
18473                    mCurrentUserId = userId;
18474                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18475                    updateCurrentProfileIdsLocked();
18476                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18477                    // Once the internal notion of the active user has switched, we lock the device
18478                    // with the option to show the user switcher on the keyguard.
18479                    mWindowManager.lockNow(null);
18480                } else {
18481                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18482                    updateCurrentProfileIdsLocked();
18483                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18484                    mUserLru.remove(currentUserIdInt);
18485                    mUserLru.add(currentUserIdInt);
18486                }
18487
18488                final UserStartedState uss = mStartedUsers.get(userId);
18489
18490                // Make sure user is in the started state.  If it is currently
18491                // stopping, we need to knock that off.
18492                if (uss.mState == UserStartedState.STATE_STOPPING) {
18493                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18494                    // so we can just fairly silently bring the user back from
18495                    // the almost-dead.
18496                    uss.mState = UserStartedState.STATE_RUNNING;
18497                    updateStartedUserArrayLocked();
18498                    needStart = true;
18499                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18500                    // This means ACTION_SHUTDOWN has been sent, so we will
18501                    // need to treat this as a new boot of the user.
18502                    uss.mState = UserStartedState.STATE_BOOTING;
18503                    updateStartedUserArrayLocked();
18504                    needStart = true;
18505                }
18506
18507                if (uss.mState == UserStartedState.STATE_BOOTING) {
18508                    // Booting up a new user, need to tell system services about it.
18509                    // Note that this is on the same handler as scheduling of broadcasts,
18510                    // which is important because it needs to go first.
18511                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18512                }
18513
18514                if (foreground) {
18515                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18516                            oldUserId));
18517                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18518                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18519                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18520                            oldUserId, userId, uss));
18521                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18522                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18523                }
18524
18525                if (needStart) {
18526                    // Send USER_STARTED broadcast
18527                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18528                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18529                            | Intent.FLAG_RECEIVER_FOREGROUND);
18530                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18531                    broadcastIntentLocked(null, null, intent,
18532                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18533                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18534                }
18535
18536                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18537                    if (userId != UserHandle.USER_OWNER) {
18538                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18539                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18540                        broadcastIntentLocked(null, null, intent, null,
18541                                new IIntentReceiver.Stub() {
18542                                    public void performReceive(Intent intent, int resultCode,
18543                                            String data, Bundle extras, boolean ordered,
18544                                            boolean sticky, int sendingUser) {
18545                                        onUserInitialized(uss, foreground, oldUserId, userId);
18546                                    }
18547                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18548                                true, false, MY_PID, Process.SYSTEM_UID,
18549                                userId);
18550                        uss.initializing = true;
18551                    } else {
18552                        getUserManagerLocked().makeInitialized(userInfo.id);
18553                    }
18554                }
18555
18556                if (foreground) {
18557                    if (!uss.initializing) {
18558                        moveUserToForeground(uss, oldUserId, userId);
18559                    }
18560                } else {
18561                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18562                }
18563
18564                if (needStart) {
18565                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18566                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18567                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18568                    broadcastIntentLocked(null, null, intent,
18569                            null, new IIntentReceiver.Stub() {
18570                                @Override
18571                                public void performReceive(Intent intent, int resultCode, String data,
18572                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18573                                        throws RemoteException {
18574                                }
18575                            }, 0, null, null,
18576                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18577                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18578                }
18579            }
18580        } finally {
18581            Binder.restoreCallingIdentity(ident);
18582        }
18583
18584        return true;
18585    }
18586
18587    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18588        long ident = Binder.clearCallingIdentity();
18589        try {
18590            Intent intent;
18591            if (oldUserId >= 0) {
18592                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18593                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18594                int count = profiles.size();
18595                for (int i = 0; i < count; i++) {
18596                    int profileUserId = profiles.get(i).id;
18597                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18598                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18599                            | Intent.FLAG_RECEIVER_FOREGROUND);
18600                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18601                    broadcastIntentLocked(null, null, intent,
18602                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18603                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18604                }
18605            }
18606            if (newUserId >= 0) {
18607                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18608                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18609                int count = profiles.size();
18610                for (int i = 0; i < count; i++) {
18611                    int profileUserId = profiles.get(i).id;
18612                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18613                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18614                            | Intent.FLAG_RECEIVER_FOREGROUND);
18615                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18616                    broadcastIntentLocked(null, null, intent,
18617                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18618                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18619                }
18620                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18621                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18622                        | Intent.FLAG_RECEIVER_FOREGROUND);
18623                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18624                broadcastIntentLocked(null, null, intent,
18625                        null, null, 0, null, null,
18626                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18627                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18628            }
18629        } finally {
18630            Binder.restoreCallingIdentity(ident);
18631        }
18632    }
18633
18634    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18635            final int newUserId) {
18636        final int N = mUserSwitchObservers.beginBroadcast();
18637        if (N > 0) {
18638            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18639                int mCount = 0;
18640                @Override
18641                public void sendResult(Bundle data) throws RemoteException {
18642                    synchronized (ActivityManagerService.this) {
18643                        if (mCurUserSwitchCallback == this) {
18644                            mCount++;
18645                            if (mCount == N) {
18646                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18647                            }
18648                        }
18649                    }
18650                }
18651            };
18652            synchronized (this) {
18653                uss.switching = true;
18654                mCurUserSwitchCallback = callback;
18655            }
18656            for (int i=0; i<N; i++) {
18657                try {
18658                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18659                            newUserId, callback);
18660                } catch (RemoteException e) {
18661                }
18662            }
18663        } else {
18664            synchronized (this) {
18665                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18666            }
18667        }
18668        mUserSwitchObservers.finishBroadcast();
18669    }
18670
18671    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18672        synchronized (this) {
18673            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18674            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18675        }
18676    }
18677
18678    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18679        mCurUserSwitchCallback = null;
18680        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18681        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18682                oldUserId, newUserId, uss));
18683    }
18684
18685    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18686        synchronized (this) {
18687            if (foreground) {
18688                moveUserToForeground(uss, oldUserId, newUserId);
18689            }
18690        }
18691
18692        completeSwitchAndInitalize(uss, newUserId, true, false);
18693    }
18694
18695    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18696        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18697        if (homeInFront) {
18698            startHomeActivityLocked(newUserId);
18699        } else {
18700            mStackSupervisor.resumeTopActivitiesLocked();
18701        }
18702        EventLogTags.writeAmSwitchUser(newUserId);
18703        getUserManagerLocked().userForeground(newUserId);
18704        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18705    }
18706
18707    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18708        completeSwitchAndInitalize(uss, newUserId, false, true);
18709    }
18710
18711    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18712            boolean clearInitializing, boolean clearSwitching) {
18713        boolean unfrozen = false;
18714        synchronized (this) {
18715            if (clearInitializing) {
18716                uss.initializing = false;
18717                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18718            }
18719            if (clearSwitching) {
18720                uss.switching = false;
18721            }
18722            if (!uss.switching && !uss.initializing) {
18723                mWindowManager.stopFreezingScreen();
18724                unfrozen = true;
18725            }
18726        }
18727        if (unfrozen) {
18728            final int N = mUserSwitchObservers.beginBroadcast();
18729            for (int i=0; i<N; i++) {
18730                try {
18731                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18732                } catch (RemoteException e) {
18733                }
18734            }
18735            mUserSwitchObservers.finishBroadcast();
18736        }
18737    }
18738
18739    void scheduleStartProfilesLocked() {
18740        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18741            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18742                    DateUtils.SECOND_IN_MILLIS);
18743        }
18744    }
18745
18746    void startProfilesLocked() {
18747        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18748        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18749                mCurrentUserId, false /* enabledOnly */);
18750        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18751        for (UserInfo user : profiles) {
18752            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18753                    && user.id != mCurrentUserId) {
18754                toStart.add(user);
18755            }
18756        }
18757        final int n = toStart.size();
18758        int i = 0;
18759        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18760            startUserInBackground(toStart.get(i).id);
18761        }
18762        if (i < n) {
18763            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18764        }
18765    }
18766
18767    void finishUserBoot(UserStartedState uss) {
18768        synchronized (this) {
18769            if (uss.mState == UserStartedState.STATE_BOOTING
18770                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18771                uss.mState = UserStartedState.STATE_RUNNING;
18772                final int userId = uss.mHandle.getIdentifier();
18773                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18774                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18775                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18776                broadcastIntentLocked(null, null, intent,
18777                        null, null, 0, null, null,
18778                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18779                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18780            }
18781        }
18782    }
18783
18784    void finishUserSwitch(UserStartedState uss) {
18785        synchronized (this) {
18786            finishUserBoot(uss);
18787
18788            startProfilesLocked();
18789
18790            int num = mUserLru.size();
18791            int i = 0;
18792            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18793                Integer oldUserId = mUserLru.get(i);
18794                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18795                if (oldUss == null) {
18796                    // Shouldn't happen, but be sane if it does.
18797                    mUserLru.remove(i);
18798                    num--;
18799                    continue;
18800                }
18801                if (oldUss.mState == UserStartedState.STATE_STOPPING
18802                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18803                    // This user is already stopping, doesn't count.
18804                    num--;
18805                    i++;
18806                    continue;
18807                }
18808                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18809                    // Owner and current can't be stopped, but count as running.
18810                    i++;
18811                    continue;
18812                }
18813                // This is a user to be stopped.
18814                stopUserLocked(oldUserId, null);
18815                num--;
18816                i++;
18817            }
18818        }
18819    }
18820
18821    @Override
18822    public int stopUser(final int userId, final IStopUserCallback callback) {
18823        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18824                != PackageManager.PERMISSION_GRANTED) {
18825            String msg = "Permission Denial: switchUser() from pid="
18826                    + Binder.getCallingPid()
18827                    + ", uid=" + Binder.getCallingUid()
18828                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18829            Slog.w(TAG, msg);
18830            throw new SecurityException(msg);
18831        }
18832        if (userId <= 0) {
18833            throw new IllegalArgumentException("Can't stop primary user " + userId);
18834        }
18835        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18836        synchronized (this) {
18837            return stopUserLocked(userId, callback);
18838        }
18839    }
18840
18841    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18842        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18843        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18844            return ActivityManager.USER_OP_IS_CURRENT;
18845        }
18846
18847        final UserStartedState uss = mStartedUsers.get(userId);
18848        if (uss == null) {
18849            // User is not started, nothing to do...  but we do need to
18850            // callback if requested.
18851            if (callback != null) {
18852                mHandler.post(new Runnable() {
18853                    @Override
18854                    public void run() {
18855                        try {
18856                            callback.userStopped(userId);
18857                        } catch (RemoteException e) {
18858                        }
18859                    }
18860                });
18861            }
18862            return ActivityManager.USER_OP_SUCCESS;
18863        }
18864
18865        if (callback != null) {
18866            uss.mStopCallbacks.add(callback);
18867        }
18868
18869        if (uss.mState != UserStartedState.STATE_STOPPING
18870                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18871            uss.mState = UserStartedState.STATE_STOPPING;
18872            updateStartedUserArrayLocked();
18873
18874            long ident = Binder.clearCallingIdentity();
18875            try {
18876                // We are going to broadcast ACTION_USER_STOPPING and then
18877                // once that is done send a final ACTION_SHUTDOWN and then
18878                // stop the user.
18879                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18880                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18881                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18882                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18883                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18884                // This is the result receiver for the final shutdown broadcast.
18885                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18886                    @Override
18887                    public void performReceive(Intent intent, int resultCode, String data,
18888                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18889                        finishUserStop(uss);
18890                    }
18891                };
18892                // This is the result receiver for the initial stopping broadcast.
18893                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18894                    @Override
18895                    public void performReceive(Intent intent, int resultCode, String data,
18896                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18897                        // On to the next.
18898                        synchronized (ActivityManagerService.this) {
18899                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18900                                // Whoops, we are being started back up.  Abort, abort!
18901                                return;
18902                            }
18903                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18904                        }
18905                        mBatteryStatsService.noteEvent(
18906                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18907                                Integer.toString(userId), userId);
18908                        mSystemServiceManager.stopUser(userId);
18909                        broadcastIntentLocked(null, null, shutdownIntent,
18910                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18911                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18912                    }
18913                };
18914                // Kick things off.
18915                broadcastIntentLocked(null, null, stoppingIntent,
18916                        null, stoppingReceiver, 0, null, null,
18917                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18918                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18919            } finally {
18920                Binder.restoreCallingIdentity(ident);
18921            }
18922        }
18923
18924        return ActivityManager.USER_OP_SUCCESS;
18925    }
18926
18927    void finishUserStop(UserStartedState uss) {
18928        final int userId = uss.mHandle.getIdentifier();
18929        boolean stopped;
18930        ArrayList<IStopUserCallback> callbacks;
18931        synchronized (this) {
18932            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18933            if (mStartedUsers.get(userId) != uss) {
18934                stopped = false;
18935            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18936                stopped = false;
18937            } else {
18938                stopped = true;
18939                // User can no longer run.
18940                mStartedUsers.remove(userId);
18941                mUserLru.remove(Integer.valueOf(userId));
18942                updateStartedUserArrayLocked();
18943
18944                // Clean up all state and processes associated with the user.
18945                // Kill all the processes for the user.
18946                forceStopUserLocked(userId, "finish user");
18947            }
18948
18949            // Explicitly remove the old information in mRecentTasks.
18950            removeRecentTasksForUserLocked(userId);
18951        }
18952
18953        for (int i=0; i<callbacks.size(); i++) {
18954            try {
18955                if (stopped) callbacks.get(i).userStopped(userId);
18956                else callbacks.get(i).userStopAborted(userId);
18957            } catch (RemoteException e) {
18958            }
18959        }
18960
18961        if (stopped) {
18962            mSystemServiceManager.cleanupUser(userId);
18963            synchronized (this) {
18964                mStackSupervisor.removeUserLocked(userId);
18965            }
18966        }
18967    }
18968
18969    @Override
18970    public UserInfo getCurrentUser() {
18971        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18972                != PackageManager.PERMISSION_GRANTED) && (
18973                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18974                != PackageManager.PERMISSION_GRANTED)) {
18975            String msg = "Permission Denial: getCurrentUser() from pid="
18976                    + Binder.getCallingPid()
18977                    + ", uid=" + Binder.getCallingUid()
18978                    + " requires " + INTERACT_ACROSS_USERS;
18979            Slog.w(TAG, msg);
18980            throw new SecurityException(msg);
18981        }
18982        synchronized (this) {
18983            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18984            return getUserManagerLocked().getUserInfo(userId);
18985        }
18986    }
18987
18988    int getCurrentUserIdLocked() {
18989        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18990    }
18991
18992    @Override
18993    public boolean isUserRunning(int userId, boolean orStopped) {
18994        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18995                != PackageManager.PERMISSION_GRANTED) {
18996            String msg = "Permission Denial: isUserRunning() from pid="
18997                    + Binder.getCallingPid()
18998                    + ", uid=" + Binder.getCallingUid()
18999                    + " requires " + INTERACT_ACROSS_USERS;
19000            Slog.w(TAG, msg);
19001            throw new SecurityException(msg);
19002        }
19003        synchronized (this) {
19004            return isUserRunningLocked(userId, orStopped);
19005        }
19006    }
19007
19008    boolean isUserRunningLocked(int userId, boolean orStopped) {
19009        UserStartedState state = mStartedUsers.get(userId);
19010        if (state == null) {
19011            return false;
19012        }
19013        if (orStopped) {
19014            return true;
19015        }
19016        return state.mState != UserStartedState.STATE_STOPPING
19017                && state.mState != UserStartedState.STATE_SHUTDOWN;
19018    }
19019
19020    @Override
19021    public int[] getRunningUserIds() {
19022        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19023                != PackageManager.PERMISSION_GRANTED) {
19024            String msg = "Permission Denial: isUserRunning() from pid="
19025                    + Binder.getCallingPid()
19026                    + ", uid=" + Binder.getCallingUid()
19027                    + " requires " + INTERACT_ACROSS_USERS;
19028            Slog.w(TAG, msg);
19029            throw new SecurityException(msg);
19030        }
19031        synchronized (this) {
19032            return mStartedUserArray;
19033        }
19034    }
19035
19036    private void updateStartedUserArrayLocked() {
19037        int num = 0;
19038        for (int i=0; i<mStartedUsers.size();  i++) {
19039            UserStartedState uss = mStartedUsers.valueAt(i);
19040            // This list does not include stopping users.
19041            if (uss.mState != UserStartedState.STATE_STOPPING
19042                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19043                num++;
19044            }
19045        }
19046        mStartedUserArray = new int[num];
19047        num = 0;
19048        for (int i=0; i<mStartedUsers.size();  i++) {
19049            UserStartedState uss = mStartedUsers.valueAt(i);
19050            if (uss.mState != UserStartedState.STATE_STOPPING
19051                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19052                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19053                num++;
19054            }
19055        }
19056    }
19057
19058    @Override
19059    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19060        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19061                != PackageManager.PERMISSION_GRANTED) {
19062            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19063                    + Binder.getCallingPid()
19064                    + ", uid=" + Binder.getCallingUid()
19065                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19066            Slog.w(TAG, msg);
19067            throw new SecurityException(msg);
19068        }
19069
19070        mUserSwitchObservers.register(observer);
19071    }
19072
19073    @Override
19074    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19075        mUserSwitchObservers.unregister(observer);
19076    }
19077
19078    private boolean userExists(int userId) {
19079        if (userId == 0) {
19080            return true;
19081        }
19082        UserManagerService ums = getUserManagerLocked();
19083        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19084    }
19085
19086    int[] getUsersLocked() {
19087        UserManagerService ums = getUserManagerLocked();
19088        return ums != null ? ums.getUserIds() : new int[] { 0 };
19089    }
19090
19091    UserManagerService getUserManagerLocked() {
19092        if (mUserManager == null) {
19093            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19094            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19095        }
19096        return mUserManager;
19097    }
19098
19099    private int applyUserId(int uid, int userId) {
19100        return UserHandle.getUid(userId, uid);
19101    }
19102
19103    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19104        if (info == null) return null;
19105        ApplicationInfo newInfo = new ApplicationInfo(info);
19106        newInfo.uid = applyUserId(info.uid, userId);
19107        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19108                + info.packageName;
19109        return newInfo;
19110    }
19111
19112    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19113        if (aInfo == null
19114                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19115            return aInfo;
19116        }
19117
19118        ActivityInfo info = new ActivityInfo(aInfo);
19119        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19120        return info;
19121    }
19122
19123    private final class LocalService extends ActivityManagerInternal {
19124        @Override
19125        public void goingToSleep() {
19126            ActivityManagerService.this.goingToSleep();
19127        }
19128
19129        @Override
19130        public void wakingUp() {
19131            ActivityManagerService.this.wakingUp();
19132        }
19133
19134        @Override
19135        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19136                String processName, String abiOverride, int uid, Runnable crashHandler) {
19137            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19138                    processName, abiOverride, uid, crashHandler);
19139        }
19140    }
19141
19142    /**
19143     * An implementation of IAppTask, that allows an app to manage its own tasks via
19144     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19145     * only the process that calls getAppTasks() can call the AppTask methods.
19146     */
19147    class AppTaskImpl extends IAppTask.Stub {
19148        private int mTaskId;
19149        private int mCallingUid;
19150
19151        public AppTaskImpl(int taskId, int callingUid) {
19152            mTaskId = taskId;
19153            mCallingUid = callingUid;
19154        }
19155
19156        private void checkCaller() {
19157            if (mCallingUid != Binder.getCallingUid()) {
19158                throw new SecurityException("Caller " + mCallingUid
19159                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19160            }
19161        }
19162
19163        @Override
19164        public void finishAndRemoveTask() {
19165            checkCaller();
19166
19167            synchronized (ActivityManagerService.this) {
19168                long origId = Binder.clearCallingIdentity();
19169                try {
19170                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19171                    if (tr == null) {
19172                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19173                    }
19174                    // Only kill the process if we are not a new document
19175                    int flags = tr.getBaseIntent().getFlags();
19176                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19177                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19178                    removeTaskByIdLocked(mTaskId,
19179                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19180                } finally {
19181                    Binder.restoreCallingIdentity(origId);
19182                }
19183            }
19184        }
19185
19186        @Override
19187        public ActivityManager.RecentTaskInfo getTaskInfo() {
19188            checkCaller();
19189
19190            synchronized (ActivityManagerService.this) {
19191                long origId = Binder.clearCallingIdentity();
19192                try {
19193                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19194                    if (tr == null) {
19195                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19196                    }
19197                    return createRecentTaskInfoFromTaskRecord(tr);
19198                } finally {
19199                    Binder.restoreCallingIdentity(origId);
19200                }
19201            }
19202        }
19203
19204        @Override
19205        public void moveToFront() {
19206            checkCaller();
19207
19208            final TaskRecord tr;
19209            synchronized (ActivityManagerService.this) {
19210                tr = recentTaskForIdLocked(mTaskId);
19211                if (tr == null) {
19212                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19213                }
19214                if (tr.getRootActivity() != null) {
19215                    moveTaskToFrontLocked(tr.taskId, 0, null);
19216                    return;
19217                }
19218            }
19219
19220            startActivityFromRecentsInner(tr.taskId, null);
19221        }
19222
19223        @Override
19224        public int startActivity(IBinder whoThread, String callingPackage,
19225                Intent intent, String resolvedType, Bundle options) {
19226            checkCaller();
19227
19228            int callingUser = UserHandle.getCallingUserId();
19229            TaskRecord tr;
19230            IApplicationThread appThread;
19231            synchronized (ActivityManagerService.this) {
19232                tr = recentTaskForIdLocked(mTaskId);
19233                if (tr == null) {
19234                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19235                }
19236                appThread = ApplicationThreadNative.asInterface(whoThread);
19237                if (appThread == null) {
19238                    throw new IllegalArgumentException("Bad app thread " + appThread);
19239                }
19240            }
19241            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19242                    resolvedType, null, null, null, null, 0, 0, null, null,
19243                    null, options, callingUser, null, tr);
19244        }
19245
19246        @Override
19247        public void setExcludeFromRecents(boolean exclude) {
19248            checkCaller();
19249
19250            synchronized (ActivityManagerService.this) {
19251                long origId = Binder.clearCallingIdentity();
19252                try {
19253                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19254                    if (tr == null) {
19255                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19256                    }
19257                    Intent intent = tr.getBaseIntent();
19258                    if (exclude) {
19259                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19260                    } else {
19261                        intent.setFlags(intent.getFlags()
19262                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19263                    }
19264                } finally {
19265                    Binder.restoreCallingIdentity(origId);
19266                }
19267            }
19268        }
19269    }
19270}
19271