ActivityManagerService.java revision 42d04db459e5a510c8c815c38e17e419c3e3b404
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    static final int LOCK_SCREEN_HIDDEN = 0;
956    static final int LOCK_SCREEN_LEAVING = 1;
957    static final int LOCK_SCREEN_SHOWN = 2;
958    /**
959     * State of external call telling us if the lock screen is shown.
960     */
961    int mLockScreenShown = LOCK_SCREEN_HIDDEN;
962
963    /**
964     * Set if we are shutting down the system, similar to sleeping.
965     */
966    boolean mShuttingDown = false;
967
968    /**
969     * Current sequence id for oom_adj computation traversal.
970     */
971    int mAdjSeq = 0;
972
973    /**
974     * Current sequence id for process LRU updating.
975     */
976    int mLruSeq = 0;
977
978    /**
979     * Keep track of the non-cached/empty process we last found, to help
980     * determine how to distribute cached/empty processes next time.
981     */
982    int mNumNonCachedProcs = 0;
983
984    /**
985     * Keep track of the number of cached hidden procs, to balance oom adj
986     * distribution between those and empty procs.
987     */
988    int mNumCachedHiddenProcs = 0;
989
990    /**
991     * Keep track of the number of service processes we last found, to
992     * determine on the next iteration which should be B services.
993     */
994    int mNumServiceProcs = 0;
995    int mNewNumAServiceProcs = 0;
996    int mNewNumServiceProcs = 0;
997
998    /**
999     * Allow the current computed overall memory level of the system to go down?
1000     * This is set to false when we are killing processes for reasons other than
1001     * memory management, so that the now smaller process list will not be taken as
1002     * an indication that memory is tighter.
1003     */
1004    boolean mAllowLowerMemLevel = false;
1005
1006    /**
1007     * The last computed memory level, for holding when we are in a state that
1008     * processes are going away for other reasons.
1009     */
1010    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1011
1012    /**
1013     * The last total number of process we have, to determine if changes actually look
1014     * like a shrinking number of process due to lower RAM.
1015     */
1016    int mLastNumProcesses;
1017
1018    /**
1019     * The uptime of the last time we performed idle maintenance.
1020     */
1021    long mLastIdleTime = SystemClock.uptimeMillis();
1022
1023    /**
1024     * Total time spent with RAM that has been added in the past since the last idle time.
1025     */
1026    long mLowRamTimeSinceLastIdle = 0;
1027
1028    /**
1029     * If RAM is currently low, when that horrible situation started.
1030     */
1031    long mLowRamStartTime = 0;
1032
1033    /**
1034     * For reporting to battery stats the current top application.
1035     */
1036    private String mCurResumedPackage = null;
1037    private int mCurResumedUid = -1;
1038
1039    /**
1040     * For reporting to battery stats the apps currently running foreground
1041     * service.  The ProcessMap is package/uid tuples; each of these contain
1042     * an array of the currently foreground processes.
1043     */
1044    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1045            = new ProcessMap<ArrayList<ProcessRecord>>();
1046
1047    /**
1048     * This is set if we had to do a delayed dexopt of an app before launching
1049     * it, to increase the ANR timeouts in that case.
1050     */
1051    boolean mDidDexOpt;
1052
1053    /**
1054     * Set if the systemServer made a call to enterSafeMode.
1055     */
1056    boolean mSafeMode;
1057
1058    String mDebugApp = null;
1059    boolean mWaitForDebugger = false;
1060    boolean mDebugTransient = false;
1061    String mOrigDebugApp = null;
1062    boolean mOrigWaitForDebugger = false;
1063    boolean mAlwaysFinishActivities = false;
1064    IActivityController mController = null;
1065    String mProfileApp = null;
1066    ProcessRecord mProfileProc = null;
1067    String mProfileFile;
1068    ParcelFileDescriptor mProfileFd;
1069    int mSamplingInterval = 0;
1070    boolean mAutoStopProfiler = false;
1071    int mProfileType = 0;
1072    String mOpenGlTraceApp = null;
1073
1074    static class ProcessChangeItem {
1075        static final int CHANGE_ACTIVITIES = 1<<0;
1076        static final int CHANGE_PROCESS_STATE = 1<<1;
1077        int changes;
1078        int uid;
1079        int pid;
1080        int processState;
1081        boolean foregroundActivities;
1082    }
1083
1084    final RemoteCallbackList<IProcessObserver> mProcessObservers
1085            = new RemoteCallbackList<IProcessObserver>();
1086    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1087
1088    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1089            = new ArrayList<ProcessChangeItem>();
1090    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1091            = new ArrayList<ProcessChangeItem>();
1092
1093    /**
1094     * Runtime CPU use collection thread.  This object's lock is used to
1095     * perform synchronization with the thread (notifying it to run).
1096     */
1097    final Thread mProcessCpuThread;
1098
1099    /**
1100     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1101     * Must acquire this object's lock when accessing it.
1102     * NOTE: this lock will be held while doing long operations (trawling
1103     * through all processes in /proc), so it should never be acquired by
1104     * any critical paths such as when holding the main activity manager lock.
1105     */
1106    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1107            MONITOR_THREAD_CPU_USAGE);
1108    final AtomicLong mLastCpuTime = new AtomicLong(0);
1109    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1110
1111    long mLastWriteTime = 0;
1112
1113    /**
1114     * Used to retain an update lock when the foreground activity is in
1115     * immersive mode.
1116     */
1117    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1118
1119    /**
1120     * Set to true after the system has finished booting.
1121     */
1122    boolean mBooted = false;
1123
1124    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1125    int mProcessLimitOverride = -1;
1126
1127    WindowManagerService mWindowManager;
1128
1129    final ActivityThread mSystemThread;
1130
1131    // Holds the current foreground user's id
1132    int mCurrentUserId = 0;
1133    // Holds the target user's id during a user switch
1134    int mTargetUserId = UserHandle.USER_NULL;
1135    // If there are multiple profiles for the current user, their ids are here
1136    // Currently only the primary user can have managed profiles
1137    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1138
1139    /**
1140     * Mapping from each known user ID to the profile group ID it is associated with.
1141     */
1142    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1143
1144    private UserManagerService mUserManager;
1145
1146    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1147        final ProcessRecord mApp;
1148        final int mPid;
1149        final IApplicationThread mAppThread;
1150
1151        AppDeathRecipient(ProcessRecord app, int pid,
1152                IApplicationThread thread) {
1153            if (localLOGV) Slog.v(
1154                TAG, "New death recipient " + this
1155                + " for thread " + thread.asBinder());
1156            mApp = app;
1157            mPid = pid;
1158            mAppThread = thread;
1159        }
1160
1161        @Override
1162        public void binderDied() {
1163            if (localLOGV) Slog.v(
1164                TAG, "Death received in " + this
1165                + " for thread " + mAppThread.asBinder());
1166            synchronized(ActivityManagerService.this) {
1167                appDiedLocked(mApp, mPid, mAppThread);
1168            }
1169        }
1170    }
1171
1172    static final int SHOW_ERROR_MSG = 1;
1173    static final int SHOW_NOT_RESPONDING_MSG = 2;
1174    static final int SHOW_FACTORY_ERROR_MSG = 3;
1175    static final int UPDATE_CONFIGURATION_MSG = 4;
1176    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1177    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1178    static final int SERVICE_TIMEOUT_MSG = 12;
1179    static final int UPDATE_TIME_ZONE = 13;
1180    static final int SHOW_UID_ERROR_MSG = 14;
1181    static final int IM_FEELING_LUCKY_MSG = 15;
1182    static final int PROC_START_TIMEOUT_MSG = 20;
1183    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1184    static final int KILL_APPLICATION_MSG = 22;
1185    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1186    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1187    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1188    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1189    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1190    static final int CLEAR_DNS_CACHE_MSG = 28;
1191    static final int UPDATE_HTTP_PROXY_MSG = 29;
1192    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1193    static final int DISPATCH_PROCESSES_CHANGED = 31;
1194    static final int DISPATCH_PROCESS_DIED = 32;
1195    static final int REPORT_MEM_USAGE_MSG = 33;
1196    static final int REPORT_USER_SWITCH_MSG = 34;
1197    static final int CONTINUE_USER_SWITCH_MSG = 35;
1198    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1199    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1200    static final int PERSIST_URI_GRANTS_MSG = 38;
1201    static final int REQUEST_ALL_PSS_MSG = 39;
1202    static final int START_PROFILES_MSG = 40;
1203    static final int UPDATE_TIME = 41;
1204    static final int SYSTEM_USER_START_MSG = 42;
1205    static final int SYSTEM_USER_CURRENT_MSG = 43;
1206    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1207    static final int FINISH_BOOTING_MSG = 45;
1208    static final int START_USER_SWITCH_MSG = 46;
1209    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1210
1211    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1212    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1213    static final int FIRST_COMPAT_MODE_MSG = 300;
1214    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1215
1216    AlertDialog mUidAlert;
1217    CompatModeDialog mCompatModeDialog;
1218    long mLastMemUsageReportTime = 0;
1219
1220    private LockToAppRequestDialog mLockToAppRequest;
1221
1222    /**
1223     * Flag whether the current user is a "monkey", i.e. whether
1224     * the UI is driven by a UI automation tool.
1225     */
1226    private boolean mUserIsMonkey;
1227
1228    /** Flag whether the device has a Recents UI */
1229    boolean mHasRecents;
1230
1231    /** The dimensions of the thumbnails in the Recents UI. */
1232    int mThumbnailWidth;
1233    int mThumbnailHeight;
1234
1235    final ServiceThread mHandlerThread;
1236    final MainHandler mHandler;
1237
1238    final class MainHandler extends Handler {
1239        public MainHandler(Looper looper) {
1240            super(looper, null, true);
1241        }
1242
1243        @Override
1244        public void handleMessage(Message msg) {
1245            switch (msg.what) {
1246            case SHOW_ERROR_MSG: {
1247                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1248                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1249                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1250                synchronized (ActivityManagerService.this) {
1251                    ProcessRecord proc = (ProcessRecord)data.get("app");
1252                    AppErrorResult res = (AppErrorResult) data.get("result");
1253                    if (proc != null && proc.crashDialog != null) {
1254                        Slog.e(TAG, "App already has crash dialog: " + proc);
1255                        if (res != null) {
1256                            res.set(0);
1257                        }
1258                        return;
1259                    }
1260                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1261                            >= Process.FIRST_APPLICATION_UID
1262                            && proc.pid != MY_PID);
1263                    for (int userId : mCurrentProfileIds) {
1264                        isBackground &= (proc.userId != userId);
1265                    }
1266                    if (isBackground && !showBackground) {
1267                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1268                        if (res != null) {
1269                            res.set(0);
1270                        }
1271                        return;
1272                    }
1273                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1274                        Dialog d = new AppErrorDialog(mContext,
1275                                ActivityManagerService.this, res, proc);
1276                        d.show();
1277                        proc.crashDialog = d;
1278                    } else {
1279                        // The device is asleep, so just pretend that the user
1280                        // saw a crash dialog and hit "force quit".
1281                        if (res != null) {
1282                            res.set(0);
1283                        }
1284                    }
1285                }
1286
1287                ensureBootCompleted();
1288            } break;
1289            case SHOW_NOT_RESPONDING_MSG: {
1290                synchronized (ActivityManagerService.this) {
1291                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1292                    ProcessRecord proc = (ProcessRecord)data.get("app");
1293                    if (proc != null && proc.anrDialog != null) {
1294                        Slog.e(TAG, "App already has anr dialog: " + proc);
1295                        return;
1296                    }
1297
1298                    Intent intent = new Intent("android.intent.action.ANR");
1299                    if (!mProcessesReady) {
1300                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1301                                | Intent.FLAG_RECEIVER_FOREGROUND);
1302                    }
1303                    broadcastIntentLocked(null, null, intent,
1304                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1305                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1306
1307                    if (mShowDialogs) {
1308                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1309                                mContext, proc, (ActivityRecord)data.get("activity"),
1310                                msg.arg1 != 0);
1311                        d.show();
1312                        proc.anrDialog = d;
1313                    } else {
1314                        // Just kill the app if there is no dialog to be shown.
1315                        killAppAtUsersRequest(proc, null);
1316                    }
1317                }
1318
1319                ensureBootCompleted();
1320            } break;
1321            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1322                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1323                synchronized (ActivityManagerService.this) {
1324                    ProcessRecord proc = (ProcessRecord) data.get("app");
1325                    if (proc == null) {
1326                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1327                        break;
1328                    }
1329                    if (proc.crashDialog != null) {
1330                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1331                        return;
1332                    }
1333                    AppErrorResult res = (AppErrorResult) data.get("result");
1334                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1335                        Dialog d = new StrictModeViolationDialog(mContext,
1336                                ActivityManagerService.this, res, proc);
1337                        d.show();
1338                        proc.crashDialog = d;
1339                    } else {
1340                        // The device is asleep, so just pretend that the user
1341                        // saw a crash dialog and hit "force quit".
1342                        res.set(0);
1343                    }
1344                }
1345                ensureBootCompleted();
1346            } break;
1347            case SHOW_FACTORY_ERROR_MSG: {
1348                Dialog d = new FactoryErrorDialog(
1349                    mContext, msg.getData().getCharSequence("msg"));
1350                d.show();
1351                ensureBootCompleted();
1352            } break;
1353            case UPDATE_CONFIGURATION_MSG: {
1354                final ContentResolver resolver = mContext.getContentResolver();
1355                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1356            } break;
1357            case GC_BACKGROUND_PROCESSES_MSG: {
1358                synchronized (ActivityManagerService.this) {
1359                    performAppGcsIfAppropriateLocked();
1360                }
1361            } break;
1362            case WAIT_FOR_DEBUGGER_MSG: {
1363                synchronized (ActivityManagerService.this) {
1364                    ProcessRecord app = (ProcessRecord)msg.obj;
1365                    if (msg.arg1 != 0) {
1366                        if (!app.waitedForDebugger) {
1367                            Dialog d = new AppWaitingForDebuggerDialog(
1368                                    ActivityManagerService.this,
1369                                    mContext, app);
1370                            app.waitDialog = d;
1371                            app.waitedForDebugger = true;
1372                            d.show();
1373                        }
1374                    } else {
1375                        if (app.waitDialog != null) {
1376                            app.waitDialog.dismiss();
1377                            app.waitDialog = null;
1378                        }
1379                    }
1380                }
1381            } break;
1382            case SERVICE_TIMEOUT_MSG: {
1383                if (mDidDexOpt) {
1384                    mDidDexOpt = false;
1385                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1386                    nmsg.obj = msg.obj;
1387                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1388                    return;
1389                }
1390                mServices.serviceTimeout((ProcessRecord)msg.obj);
1391            } break;
1392            case UPDATE_TIME_ZONE: {
1393                synchronized (ActivityManagerService.this) {
1394                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1395                        ProcessRecord r = mLruProcesses.get(i);
1396                        if (r.thread != null) {
1397                            try {
1398                                r.thread.updateTimeZone();
1399                            } catch (RemoteException ex) {
1400                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1401                            }
1402                        }
1403                    }
1404                }
1405            } break;
1406            case CLEAR_DNS_CACHE_MSG: {
1407                synchronized (ActivityManagerService.this) {
1408                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1409                        ProcessRecord r = mLruProcesses.get(i);
1410                        if (r.thread != null) {
1411                            try {
1412                                r.thread.clearDnsCache();
1413                            } catch (RemoteException ex) {
1414                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1415                            }
1416                        }
1417                    }
1418                }
1419            } break;
1420            case UPDATE_HTTP_PROXY_MSG: {
1421                ProxyInfo proxy = (ProxyInfo)msg.obj;
1422                String host = "";
1423                String port = "";
1424                String exclList = "";
1425                Uri pacFileUrl = Uri.EMPTY;
1426                if (proxy != null) {
1427                    host = proxy.getHost();
1428                    port = Integer.toString(proxy.getPort());
1429                    exclList = proxy.getExclusionListAsString();
1430                    pacFileUrl = proxy.getPacFileUrl();
1431                }
1432                synchronized (ActivityManagerService.this) {
1433                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1434                        ProcessRecord r = mLruProcesses.get(i);
1435                        if (r.thread != null) {
1436                            try {
1437                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1438                            } catch (RemoteException ex) {
1439                                Slog.w(TAG, "Failed to update http proxy for: " +
1440                                        r.info.processName);
1441                            }
1442                        }
1443                    }
1444                }
1445            } break;
1446            case SHOW_UID_ERROR_MSG: {
1447                String title = "System UIDs Inconsistent";
1448                String text = "UIDs on the system are inconsistent, you need to wipe your"
1449                        + " data partition or your device will be unstable.";
1450                Log.e(TAG, title + ": " + text);
1451                if (mShowDialogs) {
1452                    // XXX This is a temporary dialog, no need to localize.
1453                    AlertDialog d = new BaseErrorDialog(mContext);
1454                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1455                    d.setCancelable(false);
1456                    d.setTitle(title);
1457                    d.setMessage(text);
1458                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1459                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1460                    mUidAlert = d;
1461                    d.show();
1462                }
1463            } break;
1464            case IM_FEELING_LUCKY_MSG: {
1465                if (mUidAlert != null) {
1466                    mUidAlert.dismiss();
1467                    mUidAlert = null;
1468                }
1469            } break;
1470            case PROC_START_TIMEOUT_MSG: {
1471                if (mDidDexOpt) {
1472                    mDidDexOpt = false;
1473                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1474                    nmsg.obj = msg.obj;
1475                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1476                    return;
1477                }
1478                ProcessRecord app = (ProcessRecord)msg.obj;
1479                synchronized (ActivityManagerService.this) {
1480                    processStartTimedOutLocked(app);
1481                }
1482            } break;
1483            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1484                synchronized (ActivityManagerService.this) {
1485                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1486                }
1487            } break;
1488            case KILL_APPLICATION_MSG: {
1489                synchronized (ActivityManagerService.this) {
1490                    int appid = msg.arg1;
1491                    boolean restart = (msg.arg2 == 1);
1492                    Bundle bundle = (Bundle)msg.obj;
1493                    String pkg = bundle.getString("pkg");
1494                    String reason = bundle.getString("reason");
1495                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1496                            false, UserHandle.USER_ALL, reason);
1497                }
1498            } break;
1499            case FINALIZE_PENDING_INTENT_MSG: {
1500                ((PendingIntentRecord)msg.obj).completeFinalize();
1501            } break;
1502            case POST_HEAVY_NOTIFICATION_MSG: {
1503                INotificationManager inm = NotificationManager.getService();
1504                if (inm == null) {
1505                    return;
1506                }
1507
1508                ActivityRecord root = (ActivityRecord)msg.obj;
1509                ProcessRecord process = root.app;
1510                if (process == null) {
1511                    return;
1512                }
1513
1514                try {
1515                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1516                    String text = mContext.getString(R.string.heavy_weight_notification,
1517                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1518                    Notification notification = new Notification();
1519                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1520                    notification.when = 0;
1521                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1522                    notification.tickerText = text;
1523                    notification.defaults = 0; // please be quiet
1524                    notification.sound = null;
1525                    notification.vibrate = null;
1526                    notification.color = mContext.getResources().getColor(
1527                            com.android.internal.R.color.system_notification_accent_color);
1528                    notification.setLatestEventInfo(context, text,
1529                            mContext.getText(R.string.heavy_weight_notification_detail),
1530                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1531                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1532                                    new UserHandle(root.userId)));
1533
1534                    try {
1535                        int[] outId = new int[1];
1536                        inm.enqueueNotificationWithTag("android", "android", null,
1537                                R.string.heavy_weight_notification,
1538                                notification, outId, root.userId);
1539                    } catch (RuntimeException e) {
1540                        Slog.w(ActivityManagerService.TAG,
1541                                "Error showing notification for heavy-weight app", e);
1542                    } catch (RemoteException e) {
1543                    }
1544                } catch (NameNotFoundException e) {
1545                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1546                }
1547            } break;
1548            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1549                INotificationManager inm = NotificationManager.getService();
1550                if (inm == null) {
1551                    return;
1552                }
1553                try {
1554                    inm.cancelNotificationWithTag("android", null,
1555                            R.string.heavy_weight_notification,  msg.arg1);
1556                } catch (RuntimeException e) {
1557                    Slog.w(ActivityManagerService.TAG,
1558                            "Error canceling notification for service", e);
1559                } catch (RemoteException e) {
1560                }
1561            } break;
1562            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1563                synchronized (ActivityManagerService.this) {
1564                    checkExcessivePowerUsageLocked(true);
1565                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1566                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1567                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1568                }
1569            } break;
1570            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1571                synchronized (ActivityManagerService.this) {
1572                    ActivityRecord ar = (ActivityRecord)msg.obj;
1573                    if (mCompatModeDialog != null) {
1574                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1575                                ar.info.applicationInfo.packageName)) {
1576                            return;
1577                        }
1578                        mCompatModeDialog.dismiss();
1579                        mCompatModeDialog = null;
1580                    }
1581                    if (ar != null && false) {
1582                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1583                                ar.packageName)) {
1584                            int mode = mCompatModePackages.computeCompatModeLocked(
1585                                    ar.info.applicationInfo);
1586                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1587                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1588                                mCompatModeDialog = new CompatModeDialog(
1589                                        ActivityManagerService.this, mContext,
1590                                        ar.info.applicationInfo);
1591                                mCompatModeDialog.show();
1592                            }
1593                        }
1594                    }
1595                }
1596                break;
1597            }
1598            case DISPATCH_PROCESSES_CHANGED: {
1599                dispatchProcessesChanged();
1600                break;
1601            }
1602            case DISPATCH_PROCESS_DIED: {
1603                final int pid = msg.arg1;
1604                final int uid = msg.arg2;
1605                dispatchProcessDied(pid, uid);
1606                break;
1607            }
1608            case REPORT_MEM_USAGE_MSG: {
1609                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1610                Thread thread = new Thread() {
1611                    @Override public void run() {
1612                        reportMemUsage(memInfos);
1613                    }
1614                };
1615                thread.start();
1616                break;
1617            }
1618            case START_USER_SWITCH_MSG: {
1619                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1620                break;
1621            }
1622            case REPORT_USER_SWITCH_MSG: {
1623                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1624                break;
1625            }
1626            case CONTINUE_USER_SWITCH_MSG: {
1627                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1628                break;
1629            }
1630            case USER_SWITCH_TIMEOUT_MSG: {
1631                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1632                break;
1633            }
1634            case IMMERSIVE_MODE_LOCK_MSG: {
1635                final boolean nextState = (msg.arg1 != 0);
1636                if (mUpdateLock.isHeld() != nextState) {
1637                    if (DEBUG_IMMERSIVE) {
1638                        final ActivityRecord r = (ActivityRecord) msg.obj;
1639                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1640                    }
1641                    if (nextState) {
1642                        mUpdateLock.acquire();
1643                    } else {
1644                        mUpdateLock.release();
1645                    }
1646                }
1647                break;
1648            }
1649            case PERSIST_URI_GRANTS_MSG: {
1650                writeGrantedUriPermissions();
1651                break;
1652            }
1653            case REQUEST_ALL_PSS_MSG: {
1654                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1655                break;
1656            }
1657            case START_PROFILES_MSG: {
1658                synchronized (ActivityManagerService.this) {
1659                    startProfilesLocked();
1660                }
1661                break;
1662            }
1663            case UPDATE_TIME: {
1664                synchronized (ActivityManagerService.this) {
1665                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1666                        ProcessRecord r = mLruProcesses.get(i);
1667                        if (r.thread != null) {
1668                            try {
1669                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1670                            } catch (RemoteException ex) {
1671                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1672                            }
1673                        }
1674                    }
1675                }
1676                break;
1677            }
1678            case SYSTEM_USER_START_MSG: {
1679                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1680                        Integer.toString(msg.arg1), msg.arg1);
1681                mSystemServiceManager.startUser(msg.arg1);
1682                break;
1683            }
1684            case SYSTEM_USER_CURRENT_MSG: {
1685                mBatteryStatsService.noteEvent(
1686                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1687                        Integer.toString(msg.arg2), msg.arg2);
1688                mBatteryStatsService.noteEvent(
1689                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1690                        Integer.toString(msg.arg1), msg.arg1);
1691                mSystemServiceManager.switchUser(msg.arg1);
1692                mLockToAppRequest.clearPrompt();
1693                break;
1694            }
1695            case ENTER_ANIMATION_COMPLETE_MSG: {
1696                synchronized (ActivityManagerService.this) {
1697                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1698                    if (r != null && r.app != null && r.app.thread != null) {
1699                        try {
1700                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1701                        } catch (RemoteException e) {
1702                        }
1703                    }
1704                }
1705                break;
1706            }
1707            case FINISH_BOOTING_MSG: {
1708                if (msg.arg1 != 0) {
1709                    finishBooting();
1710                }
1711                if (msg.arg2 != 0) {
1712                    enableScreenAfterBoot();
1713                }
1714                break;
1715            }
1716            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1717                try {
1718                    Locale l = (Locale) msg.obj;
1719                    IBinder service = ServiceManager.getService("mount");
1720                    IMountService mountService = IMountService.Stub.asInterface(service);
1721                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1722                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1723                } catch (RemoteException e) {
1724                    Log.e(TAG, "Error storing locale for decryption UI", e);
1725                }
1726                break;
1727            }
1728            }
1729        }
1730    };
1731
1732    static final int COLLECT_PSS_BG_MSG = 1;
1733
1734    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1735        @Override
1736        public void handleMessage(Message msg) {
1737            switch (msg.what) {
1738            case COLLECT_PSS_BG_MSG: {
1739                long start = SystemClock.uptimeMillis();
1740                MemInfoReader memInfo = null;
1741                synchronized (ActivityManagerService.this) {
1742                    if (mFullPssPending) {
1743                        mFullPssPending = false;
1744                        memInfo = new MemInfoReader();
1745                    }
1746                }
1747                if (memInfo != null) {
1748                    updateCpuStatsNow();
1749                    long nativeTotalPss = 0;
1750                    synchronized (mProcessCpuTracker) {
1751                        final int N = mProcessCpuTracker.countStats();
1752                        for (int j=0; j<N; j++) {
1753                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1754                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1755                                // This is definitely an application process; skip it.
1756                                continue;
1757                            }
1758                            synchronized (mPidsSelfLocked) {
1759                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1760                                    // This is one of our own processes; skip it.
1761                                    continue;
1762                                }
1763                            }
1764                            nativeTotalPss += Debug.getPss(st.pid, null);
1765                        }
1766                    }
1767                    memInfo.readMemInfo();
1768                    synchronized (ActivityManagerService.this) {
1769                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1770                                + (SystemClock.uptimeMillis()-start) + "ms");
1771                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1772                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1773                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1774                    }
1775                }
1776
1777                int i=0, num=0;
1778                long[] tmp = new long[1];
1779                do {
1780                    ProcessRecord proc;
1781                    int procState;
1782                    int pid;
1783                    synchronized (ActivityManagerService.this) {
1784                        if (i >= mPendingPssProcesses.size()) {
1785                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1786                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1787                            mPendingPssProcesses.clear();
1788                            return;
1789                        }
1790                        proc = mPendingPssProcesses.get(i);
1791                        procState = proc.pssProcState;
1792                        if (proc.thread != null && procState == proc.setProcState) {
1793                            pid = proc.pid;
1794                        } else {
1795                            proc = null;
1796                            pid = 0;
1797                        }
1798                        i++;
1799                    }
1800                    if (proc != null) {
1801                        long pss = Debug.getPss(pid, tmp);
1802                        synchronized (ActivityManagerService.this) {
1803                            if (proc.thread != null && proc.setProcState == procState
1804                                    && proc.pid == pid) {
1805                                num++;
1806                                proc.lastPssTime = SystemClock.uptimeMillis();
1807                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1808                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1809                                        + ": " + pss + " lastPss=" + proc.lastPss
1810                                        + " state=" + ProcessList.makeProcStateString(procState));
1811                                if (proc.initialIdlePss == 0) {
1812                                    proc.initialIdlePss = pss;
1813                                }
1814                                proc.lastPss = pss;
1815                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1816                                    proc.lastCachedPss = pss;
1817                                }
1818                            }
1819                        }
1820                    }
1821                } while (true);
1822            }
1823            }
1824        }
1825    };
1826
1827    /**
1828     * Monitor for package changes and update our internal state.
1829     */
1830    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1831        @Override
1832        public void onPackageRemoved(String packageName, int uid) {
1833            // Remove all tasks with activities in the specified package from the list of recent tasks
1834            final int eventUserId = getChangingUserId();
1835            synchronized (ActivityManagerService.this) {
1836                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1837                    TaskRecord tr = mRecentTasks.get(i);
1838                    if (tr.userId != eventUserId) continue;
1839
1840                    ComponentName cn = tr.intent.getComponent();
1841                    if (cn != null && cn.getPackageName().equals(packageName)) {
1842                        // If the package name matches, remove the task
1843                        removeTaskByIdLocked(tr.taskId, true);
1844                    }
1845                }
1846            }
1847        }
1848
1849        @Override
1850        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1851            onPackageModified(packageName);
1852            return true;
1853        }
1854
1855        @Override
1856        public void onPackageModified(String packageName) {
1857            final int eventUserId = getChangingUserId();
1858            final IPackageManager pm = AppGlobals.getPackageManager();
1859            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1860                    new ArrayList<Pair<Intent, Integer>>();
1861            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1862            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1863            // Copy the list of recent tasks so that we don't hold onto the lock on
1864            // ActivityManagerService for long periods while checking if components exist.
1865            synchronized (ActivityManagerService.this) {
1866                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1867                    TaskRecord tr = mRecentTasks.get(i);
1868                    if (tr.userId != eventUserId) continue;
1869
1870                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1871                }
1872            }
1873            // Check the recent tasks and filter out all tasks with components that no longer exist.
1874            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1875                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1876                ComponentName cn = p.first.getComponent();
1877                if (cn != null && cn.getPackageName().equals(packageName)) {
1878                    if (componentsKnownToExist.contains(cn)) {
1879                        // If we know that the component still exists in the package, then skip
1880                        continue;
1881                    }
1882                    try {
1883                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1884                        if (info != null) {
1885                            componentsKnownToExist.add(cn);
1886                        } else {
1887                            tasksToRemove.add(p.second);
1888                        }
1889                    } catch (RemoteException e) {
1890                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1891                    }
1892                }
1893            }
1894            // Prune all the tasks with removed components from the list of recent tasks
1895            synchronized (ActivityManagerService.this) {
1896                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1897                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1898                }
1899            }
1900        }
1901
1902        @Override
1903        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1904            // Force stop the specified packages
1905            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1906            if (packages != null) {
1907                for (String pkg : packages) {
1908                    synchronized (ActivityManagerService.this) {
1909                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1910                                userId, "finished booting")) {
1911                            return true;
1912                        }
1913                    }
1914                }
1915            }
1916            return false;
1917        }
1918    };
1919
1920    public void setSystemProcess() {
1921        try {
1922            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1923            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1924            ServiceManager.addService("meminfo", new MemBinder(this));
1925            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1926            ServiceManager.addService("dbinfo", new DbBinder(this));
1927            if (MONITOR_CPU_USAGE) {
1928                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1929            }
1930            ServiceManager.addService("permission", new PermissionController(this));
1931
1932            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1933                    "android", STOCK_PM_FLAGS);
1934            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1935
1936            synchronized (this) {
1937                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1938                app.persistent = true;
1939                app.pid = MY_PID;
1940                app.maxAdj = ProcessList.SYSTEM_ADJ;
1941                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1942                mProcessNames.put(app.processName, app.uid, app);
1943                synchronized (mPidsSelfLocked) {
1944                    mPidsSelfLocked.put(app.pid, app);
1945                }
1946                updateLruProcessLocked(app, false, null);
1947                updateOomAdjLocked();
1948            }
1949        } catch (PackageManager.NameNotFoundException e) {
1950            throw new RuntimeException(
1951                    "Unable to find android system package", e);
1952        }
1953    }
1954
1955    public void setWindowManager(WindowManagerService wm) {
1956        mWindowManager = wm;
1957        mStackSupervisor.setWindowManager(wm);
1958    }
1959
1960    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1961        mUsageStatsService = usageStatsManager;
1962    }
1963
1964    public void startObservingNativeCrashes() {
1965        final NativeCrashListener ncl = new NativeCrashListener(this);
1966        ncl.start();
1967    }
1968
1969    public IAppOpsService getAppOpsService() {
1970        return mAppOpsService;
1971    }
1972
1973    static class MemBinder extends Binder {
1974        ActivityManagerService mActivityManagerService;
1975        MemBinder(ActivityManagerService activityManagerService) {
1976            mActivityManagerService = activityManagerService;
1977        }
1978
1979        @Override
1980        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1981            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1982                    != PackageManager.PERMISSION_GRANTED) {
1983                pw.println("Permission Denial: can't dump meminfo from from pid="
1984                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1985                        + " without permission " + android.Manifest.permission.DUMP);
1986                return;
1987            }
1988
1989            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1990        }
1991    }
1992
1993    static class GraphicsBinder extends Binder {
1994        ActivityManagerService mActivityManagerService;
1995        GraphicsBinder(ActivityManagerService activityManagerService) {
1996            mActivityManagerService = activityManagerService;
1997        }
1998
1999        @Override
2000        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2001            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2002                    != PackageManager.PERMISSION_GRANTED) {
2003                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2004                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2005                        + " without permission " + android.Manifest.permission.DUMP);
2006                return;
2007            }
2008
2009            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2010        }
2011    }
2012
2013    static class DbBinder extends Binder {
2014        ActivityManagerService mActivityManagerService;
2015        DbBinder(ActivityManagerService activityManagerService) {
2016            mActivityManagerService = activityManagerService;
2017        }
2018
2019        @Override
2020        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2021            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2022                    != PackageManager.PERMISSION_GRANTED) {
2023                pw.println("Permission Denial: can't dump dbinfo from from pid="
2024                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2025                        + " without permission " + android.Manifest.permission.DUMP);
2026                return;
2027            }
2028
2029            mActivityManagerService.dumpDbInfo(fd, pw, args);
2030        }
2031    }
2032
2033    static class CpuBinder extends Binder {
2034        ActivityManagerService mActivityManagerService;
2035        CpuBinder(ActivityManagerService activityManagerService) {
2036            mActivityManagerService = activityManagerService;
2037        }
2038
2039        @Override
2040        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2041            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2042                    != PackageManager.PERMISSION_GRANTED) {
2043                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2044                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2045                        + " without permission " + android.Manifest.permission.DUMP);
2046                return;
2047            }
2048
2049            synchronized (mActivityManagerService.mProcessCpuTracker) {
2050                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2051                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2052                        SystemClock.uptimeMillis()));
2053            }
2054        }
2055    }
2056
2057    public static final class Lifecycle extends SystemService {
2058        private final ActivityManagerService mService;
2059
2060        public Lifecycle(Context context) {
2061            super(context);
2062            mService = new ActivityManagerService(context);
2063        }
2064
2065        @Override
2066        public void onStart() {
2067            mService.start();
2068        }
2069
2070        public ActivityManagerService getService() {
2071            return mService;
2072        }
2073    }
2074
2075    // Note: This method is invoked on the main thread but may need to attach various
2076    // handlers to other threads.  So take care to be explicit about the looper.
2077    public ActivityManagerService(Context systemContext) {
2078        mContext = systemContext;
2079        mFactoryTest = FactoryTest.getMode();
2080        mSystemThread = ActivityThread.currentActivityThread();
2081
2082        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2083
2084        mHandlerThread = new ServiceThread(TAG,
2085                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2086        mHandlerThread.start();
2087        mHandler = new MainHandler(mHandlerThread.getLooper());
2088
2089        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2090                "foreground", BROADCAST_FG_TIMEOUT, false);
2091        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2092                "background", BROADCAST_BG_TIMEOUT, true);
2093        mBroadcastQueues[0] = mFgBroadcastQueue;
2094        mBroadcastQueues[1] = mBgBroadcastQueue;
2095
2096        mServices = new ActiveServices(this);
2097        mProviderMap = new ProviderMap(this);
2098
2099        // TODO: Move creation of battery stats service outside of activity manager service.
2100        File dataDir = Environment.getDataDirectory();
2101        File systemDir = new File(dataDir, "system");
2102        systemDir.mkdirs();
2103        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2104        mBatteryStatsService.getActiveStatistics().readLocked();
2105        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2106        mOnBattery = DEBUG_POWER ? true
2107                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2108        mBatteryStatsService.getActiveStatistics().setCallback(this);
2109
2110        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2111
2112        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2113
2114        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2115
2116        // User 0 is the first and only user that runs at boot.
2117        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2118        mUserLru.add(Integer.valueOf(0));
2119        updateStartedUserArrayLocked();
2120
2121        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2122            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2123
2124        mConfiguration.setToDefaults();
2125        mConfiguration.setLocale(Locale.getDefault());
2126
2127        mConfigurationSeq = mConfiguration.seq = 1;
2128        mProcessCpuTracker.init();
2129
2130        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2131        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2132        mStackSupervisor = new ActivityStackSupervisor(this);
2133        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2134
2135        mProcessCpuThread = new Thread("CpuTracker") {
2136            @Override
2137            public void run() {
2138                while (true) {
2139                    try {
2140                        try {
2141                            synchronized(this) {
2142                                final long now = SystemClock.uptimeMillis();
2143                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2144                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2145                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2146                                //        + ", write delay=" + nextWriteDelay);
2147                                if (nextWriteDelay < nextCpuDelay) {
2148                                    nextCpuDelay = nextWriteDelay;
2149                                }
2150                                if (nextCpuDelay > 0) {
2151                                    mProcessCpuMutexFree.set(true);
2152                                    this.wait(nextCpuDelay);
2153                                }
2154                            }
2155                        } catch (InterruptedException e) {
2156                        }
2157                        updateCpuStatsNow();
2158                    } catch (Exception e) {
2159                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2160                    }
2161                }
2162            }
2163        };
2164
2165        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2166
2167        Watchdog.getInstance().addMonitor(this);
2168        Watchdog.getInstance().addThread(mHandler);
2169    }
2170
2171    public void setSystemServiceManager(SystemServiceManager mgr) {
2172        mSystemServiceManager = mgr;
2173    }
2174
2175    private void start() {
2176        Process.removeAllProcessGroups();
2177        mProcessCpuThread.start();
2178
2179        mBatteryStatsService.publish(mContext);
2180        mAppOpsService.publish(mContext);
2181        Slog.d("AppOps", "AppOpsService published");
2182        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2183    }
2184
2185    public void initPowerManagement() {
2186        mStackSupervisor.initPowerManagement();
2187        mBatteryStatsService.initPowerManagement();
2188    }
2189
2190    @Override
2191    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2192            throws RemoteException {
2193        if (code == SYSPROPS_TRANSACTION) {
2194            // We need to tell all apps about the system property change.
2195            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2196            synchronized(this) {
2197                final int NP = mProcessNames.getMap().size();
2198                for (int ip=0; ip<NP; ip++) {
2199                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2200                    final int NA = apps.size();
2201                    for (int ia=0; ia<NA; ia++) {
2202                        ProcessRecord app = apps.valueAt(ia);
2203                        if (app.thread != null) {
2204                            procs.add(app.thread.asBinder());
2205                        }
2206                    }
2207                }
2208            }
2209
2210            int N = procs.size();
2211            for (int i=0; i<N; i++) {
2212                Parcel data2 = Parcel.obtain();
2213                try {
2214                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2215                } catch (RemoteException e) {
2216                }
2217                data2.recycle();
2218            }
2219        }
2220        try {
2221            return super.onTransact(code, data, reply, flags);
2222        } catch (RuntimeException e) {
2223            // The activity manager only throws security exceptions, so let's
2224            // log all others.
2225            if (!(e instanceof SecurityException)) {
2226                Slog.wtf(TAG, "Activity Manager Crash", e);
2227            }
2228            throw e;
2229        }
2230    }
2231
2232    void updateCpuStats() {
2233        final long now = SystemClock.uptimeMillis();
2234        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2235            return;
2236        }
2237        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2238            synchronized (mProcessCpuThread) {
2239                mProcessCpuThread.notify();
2240            }
2241        }
2242    }
2243
2244    void updateCpuStatsNow() {
2245        synchronized (mProcessCpuTracker) {
2246            mProcessCpuMutexFree.set(false);
2247            final long now = SystemClock.uptimeMillis();
2248            boolean haveNewCpuStats = false;
2249
2250            if (MONITOR_CPU_USAGE &&
2251                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2252                mLastCpuTime.set(now);
2253                haveNewCpuStats = true;
2254                mProcessCpuTracker.update();
2255                //Slog.i(TAG, mProcessCpu.printCurrentState());
2256                //Slog.i(TAG, "Total CPU usage: "
2257                //        + mProcessCpu.getTotalCpuPercent() + "%");
2258
2259                // Slog the cpu usage if the property is set.
2260                if ("true".equals(SystemProperties.get("events.cpu"))) {
2261                    int user = mProcessCpuTracker.getLastUserTime();
2262                    int system = mProcessCpuTracker.getLastSystemTime();
2263                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2264                    int irq = mProcessCpuTracker.getLastIrqTime();
2265                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2266                    int idle = mProcessCpuTracker.getLastIdleTime();
2267
2268                    int total = user + system + iowait + irq + softIrq + idle;
2269                    if (total == 0) total = 1;
2270
2271                    EventLog.writeEvent(EventLogTags.CPU,
2272                            ((user+system+iowait+irq+softIrq) * 100) / total,
2273                            (user * 100) / total,
2274                            (system * 100) / total,
2275                            (iowait * 100) / total,
2276                            (irq * 100) / total,
2277                            (softIrq * 100) / total);
2278                }
2279            }
2280
2281            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2282            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2283            synchronized(bstats) {
2284                synchronized(mPidsSelfLocked) {
2285                    if (haveNewCpuStats) {
2286                        if (mOnBattery) {
2287                            int perc = bstats.startAddingCpuLocked();
2288                            int totalUTime = 0;
2289                            int totalSTime = 0;
2290                            final int N = mProcessCpuTracker.countStats();
2291                            for (int i=0; i<N; i++) {
2292                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2293                                if (!st.working) {
2294                                    continue;
2295                                }
2296                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2297                                int otherUTime = (st.rel_utime*perc)/100;
2298                                int otherSTime = (st.rel_stime*perc)/100;
2299                                totalUTime += otherUTime;
2300                                totalSTime += otherSTime;
2301                                if (pr != null) {
2302                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2303                                    if (ps == null || !ps.isActive()) {
2304                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2305                                                pr.info.uid, pr.processName);
2306                                    }
2307                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2308                                            st.rel_stime-otherSTime);
2309                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2310                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2311                                } else {
2312                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2313                                    if (ps == null || !ps.isActive()) {
2314                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2315                                                bstats.mapUid(st.uid), st.name);
2316                                    }
2317                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2318                                            st.rel_stime-otherSTime);
2319                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2320                                }
2321                            }
2322                            bstats.finishAddingCpuLocked(perc, totalUTime,
2323                                    totalSTime, cpuSpeedTimes);
2324                        }
2325                    }
2326                }
2327
2328                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2329                    mLastWriteTime = now;
2330                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2331                }
2332            }
2333        }
2334    }
2335
2336    @Override
2337    public void batteryNeedsCpuUpdate() {
2338        updateCpuStatsNow();
2339    }
2340
2341    @Override
2342    public void batteryPowerChanged(boolean onBattery) {
2343        // When plugging in, update the CPU stats first before changing
2344        // the plug state.
2345        updateCpuStatsNow();
2346        synchronized (this) {
2347            synchronized(mPidsSelfLocked) {
2348                mOnBattery = DEBUG_POWER ? true : onBattery;
2349            }
2350        }
2351    }
2352
2353    /**
2354     * Initialize the application bind args. These are passed to each
2355     * process when the bindApplication() IPC is sent to the process. They're
2356     * lazily setup to make sure the services are running when they're asked for.
2357     */
2358    private HashMap<String, IBinder> getCommonServicesLocked() {
2359        if (mAppBindArgs == null) {
2360            mAppBindArgs = new HashMap<String, IBinder>();
2361
2362            // Setup the application init args
2363            mAppBindArgs.put("package", ServiceManager.getService("package"));
2364            mAppBindArgs.put("window", ServiceManager.getService("window"));
2365            mAppBindArgs.put(Context.ALARM_SERVICE,
2366                    ServiceManager.getService(Context.ALARM_SERVICE));
2367        }
2368        return mAppBindArgs;
2369    }
2370
2371    final void setFocusedActivityLocked(ActivityRecord r) {
2372        if (mFocusedActivity != r) {
2373            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2374            mFocusedActivity = r;
2375            if (r.task != null && r.task.voiceInteractor != null) {
2376                startRunningVoiceLocked();
2377            } else {
2378                finishRunningVoiceLocked();
2379            }
2380            mStackSupervisor.setFocusedStack(r);
2381            if (r != null) {
2382                mWindowManager.setFocusedApp(r.appToken, true);
2383            }
2384            applyUpdateLockStateLocked(r);
2385        }
2386    }
2387
2388    final void clearFocusedActivity(ActivityRecord r) {
2389        if (mFocusedActivity == r) {
2390            mFocusedActivity = null;
2391        }
2392    }
2393
2394    @Override
2395    public void setFocusedStack(int stackId) {
2396        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2397        synchronized (ActivityManagerService.this) {
2398            ActivityStack stack = mStackSupervisor.getStack(stackId);
2399            if (stack != null) {
2400                ActivityRecord r = stack.topRunningActivityLocked(null);
2401                if (r != null) {
2402                    setFocusedActivityLocked(r);
2403                }
2404            }
2405        }
2406    }
2407
2408    @Override
2409    public void notifyActivityDrawn(IBinder token) {
2410        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2411        synchronized (this) {
2412            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2413            if (r != null) {
2414                r.task.stack.notifyActivityDrawnLocked(r);
2415            }
2416        }
2417    }
2418
2419    final void applyUpdateLockStateLocked(ActivityRecord r) {
2420        // Modifications to the UpdateLock state are done on our handler, outside
2421        // the activity manager's locks.  The new state is determined based on the
2422        // state *now* of the relevant activity record.  The object is passed to
2423        // the handler solely for logging detail, not to be consulted/modified.
2424        final boolean nextState = r != null && r.immersive;
2425        mHandler.sendMessage(
2426                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2427    }
2428
2429    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2430        Message msg = Message.obtain();
2431        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2432        msg.obj = r.task.askedCompatMode ? null : r;
2433        mHandler.sendMessage(msg);
2434    }
2435
2436    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2437            String what, Object obj, ProcessRecord srcApp) {
2438        app.lastActivityTime = now;
2439
2440        if (app.activities.size() > 0) {
2441            // Don't want to touch dependent processes that are hosting activities.
2442            return index;
2443        }
2444
2445        int lrui = mLruProcesses.lastIndexOf(app);
2446        if (lrui < 0) {
2447            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2448                    + what + " " + obj + " from " + srcApp);
2449            return index;
2450        }
2451
2452        if (lrui >= index) {
2453            // Don't want to cause this to move dependent processes *back* in the
2454            // list as if they were less frequently used.
2455            return index;
2456        }
2457
2458        if (lrui >= mLruProcessActivityStart) {
2459            // Don't want to touch dependent processes that are hosting activities.
2460            return index;
2461        }
2462
2463        mLruProcesses.remove(lrui);
2464        if (index > 0) {
2465            index--;
2466        }
2467        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2468                + " in LRU list: " + app);
2469        mLruProcesses.add(index, app);
2470        return index;
2471    }
2472
2473    final void removeLruProcessLocked(ProcessRecord app) {
2474        int lrui = mLruProcesses.lastIndexOf(app);
2475        if (lrui >= 0) {
2476            if (!app.killed) {
2477                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2478                Process.killProcessQuiet(app.pid);
2479                Process.killProcessGroup(app.info.uid, app.pid);
2480            }
2481            if (lrui <= mLruProcessActivityStart) {
2482                mLruProcessActivityStart--;
2483            }
2484            if (lrui <= mLruProcessServiceStart) {
2485                mLruProcessServiceStart--;
2486            }
2487            mLruProcesses.remove(lrui);
2488        }
2489    }
2490
2491    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2492            ProcessRecord client) {
2493        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2494                || app.treatLikeActivity;
2495        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2496        if (!activityChange && hasActivity) {
2497            // The process has activities, so we are only allowing activity-based adjustments
2498            // to move it.  It should be kept in the front of the list with other
2499            // processes that have activities, and we don't want those to change their
2500            // order except due to activity operations.
2501            return;
2502        }
2503
2504        mLruSeq++;
2505        final long now = SystemClock.uptimeMillis();
2506        app.lastActivityTime = now;
2507
2508        // First a quick reject: if the app is already at the position we will
2509        // put it, then there is nothing to do.
2510        if (hasActivity) {
2511            final int N = mLruProcesses.size();
2512            if (N > 0 && mLruProcesses.get(N-1) == app) {
2513                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2514                return;
2515            }
2516        } else {
2517            if (mLruProcessServiceStart > 0
2518                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2519                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2520                return;
2521            }
2522        }
2523
2524        int lrui = mLruProcesses.lastIndexOf(app);
2525
2526        if (app.persistent && lrui >= 0) {
2527            // We don't care about the position of persistent processes, as long as
2528            // they are in the list.
2529            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2530            return;
2531        }
2532
2533        /* In progress: compute new position first, so we can avoid doing work
2534           if the process is not actually going to move.  Not yet working.
2535        int addIndex;
2536        int nextIndex;
2537        boolean inActivity = false, inService = false;
2538        if (hasActivity) {
2539            // Process has activities, put it at the very tipsy-top.
2540            addIndex = mLruProcesses.size();
2541            nextIndex = mLruProcessServiceStart;
2542            inActivity = true;
2543        } else if (hasService) {
2544            // Process has services, put it at the top of the service list.
2545            addIndex = mLruProcessActivityStart;
2546            nextIndex = mLruProcessServiceStart;
2547            inActivity = true;
2548            inService = true;
2549        } else  {
2550            // Process not otherwise of interest, it goes to the top of the non-service area.
2551            addIndex = mLruProcessServiceStart;
2552            if (client != null) {
2553                int clientIndex = mLruProcesses.lastIndexOf(client);
2554                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2555                        + app);
2556                if (clientIndex >= 0 && addIndex > clientIndex) {
2557                    addIndex = clientIndex;
2558                }
2559            }
2560            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2561        }
2562
2563        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2564                + mLruProcessActivityStart + "): " + app);
2565        */
2566
2567        if (lrui >= 0) {
2568            if (lrui < mLruProcessActivityStart) {
2569                mLruProcessActivityStart--;
2570            }
2571            if (lrui < mLruProcessServiceStart) {
2572                mLruProcessServiceStart--;
2573            }
2574            /*
2575            if (addIndex > lrui) {
2576                addIndex--;
2577            }
2578            if (nextIndex > lrui) {
2579                nextIndex--;
2580            }
2581            */
2582            mLruProcesses.remove(lrui);
2583        }
2584
2585        /*
2586        mLruProcesses.add(addIndex, app);
2587        if (inActivity) {
2588            mLruProcessActivityStart++;
2589        }
2590        if (inService) {
2591            mLruProcessActivityStart++;
2592        }
2593        */
2594
2595        int nextIndex;
2596        if (hasActivity) {
2597            final int N = mLruProcesses.size();
2598            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2599                // Process doesn't have activities, but has clients with
2600                // activities...  move it up, but one below the top (the top
2601                // should always have a real activity).
2602                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2603                mLruProcesses.add(N-1, app);
2604                // To keep it from spamming the LRU list (by making a bunch of clients),
2605                // we will push down any other entries owned by the app.
2606                final int uid = app.info.uid;
2607                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2608                    ProcessRecord subProc = mLruProcesses.get(i);
2609                    if (subProc.info.uid == uid) {
2610                        // We want to push this one down the list.  If the process after
2611                        // it is for the same uid, however, don't do so, because we don't
2612                        // want them internally to be re-ordered.
2613                        if (mLruProcesses.get(i-1).info.uid != uid) {
2614                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2615                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2616                            ProcessRecord tmp = mLruProcesses.get(i);
2617                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2618                            mLruProcesses.set(i-1, tmp);
2619                            i--;
2620                        }
2621                    } else {
2622                        // A gap, we can stop here.
2623                        break;
2624                    }
2625                }
2626            } else {
2627                // Process has activities, put it at the very tipsy-top.
2628                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2629                mLruProcesses.add(app);
2630            }
2631            nextIndex = mLruProcessServiceStart;
2632        } else if (hasService) {
2633            // Process has services, put it at the top of the service list.
2634            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2635            mLruProcesses.add(mLruProcessActivityStart, app);
2636            nextIndex = mLruProcessServiceStart;
2637            mLruProcessActivityStart++;
2638        } else  {
2639            // Process not otherwise of interest, it goes to the top of the non-service area.
2640            int index = mLruProcessServiceStart;
2641            if (client != null) {
2642                // If there is a client, don't allow the process to be moved up higher
2643                // in the list than that client.
2644                int clientIndex = mLruProcesses.lastIndexOf(client);
2645                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2646                        + " when updating " + app);
2647                if (clientIndex <= lrui) {
2648                    // Don't allow the client index restriction to push it down farther in the
2649                    // list than it already is.
2650                    clientIndex = lrui;
2651                }
2652                if (clientIndex >= 0 && index > clientIndex) {
2653                    index = clientIndex;
2654                }
2655            }
2656            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2657            mLruProcesses.add(index, app);
2658            nextIndex = index-1;
2659            mLruProcessActivityStart++;
2660            mLruProcessServiceStart++;
2661        }
2662
2663        // If the app is currently using a content provider or service,
2664        // bump those processes as well.
2665        for (int j=app.connections.size()-1; j>=0; j--) {
2666            ConnectionRecord cr = app.connections.valueAt(j);
2667            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2668                    && cr.binding.service.app != null
2669                    && cr.binding.service.app.lruSeq != mLruSeq
2670                    && !cr.binding.service.app.persistent) {
2671                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2672                        "service connection", cr, app);
2673            }
2674        }
2675        for (int j=app.conProviders.size()-1; j>=0; j--) {
2676            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2677            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2678                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2679                        "provider reference", cpr, app);
2680            }
2681        }
2682    }
2683
2684    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2685        if (uid == Process.SYSTEM_UID) {
2686            // The system gets to run in any process.  If there are multiple
2687            // processes with the same uid, just pick the first (this
2688            // should never happen).
2689            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2690            if (procs == null) return null;
2691            final int N = procs.size();
2692            for (int i = 0; i < N; i++) {
2693                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2694            }
2695        }
2696        ProcessRecord proc = mProcessNames.get(processName, uid);
2697        if (false && proc != null && !keepIfLarge
2698                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2699                && proc.lastCachedPss >= 4000) {
2700            // Turn this condition on to cause killing to happen regularly, for testing.
2701            if (proc.baseProcessTracker != null) {
2702                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2703            }
2704            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2705        } else if (proc != null && !keepIfLarge
2706                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2707                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2708            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2709            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2710                if (proc.baseProcessTracker != null) {
2711                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2712                }
2713                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2714            }
2715        }
2716        return proc;
2717    }
2718
2719    void ensurePackageDexOpt(String packageName) {
2720        IPackageManager pm = AppGlobals.getPackageManager();
2721        try {
2722            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2723                mDidDexOpt = true;
2724            }
2725        } catch (RemoteException e) {
2726        }
2727    }
2728
2729    boolean isNextTransitionForward() {
2730        int transit = mWindowManager.getPendingAppTransition();
2731        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2732                || transit == AppTransition.TRANSIT_TASK_OPEN
2733                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2734    }
2735
2736    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2737            String processName, String abiOverride, int uid, Runnable crashHandler) {
2738        synchronized(this) {
2739            ApplicationInfo info = new ApplicationInfo();
2740            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2741            // For isolated processes, the former contains the parent's uid and the latter the
2742            // actual uid of the isolated process.
2743            // In the special case introduced by this method (which is, starting an isolated
2744            // process directly from the SystemServer without an actual parent app process) the
2745            // closest thing to a parent's uid is SYSTEM_UID.
2746            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2747            // the |isolated| logic in the ProcessRecord constructor.
2748            info.uid = Process.SYSTEM_UID;
2749            info.processName = processName;
2750            info.className = entryPoint;
2751            info.packageName = "android";
2752            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2753                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2754                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2755                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2756                    crashHandler);
2757            return proc != null ? proc.pid : 0;
2758        }
2759    }
2760
2761    final ProcessRecord startProcessLocked(String processName,
2762            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2763            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2764            boolean isolated, boolean keepIfLarge) {
2765        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2766                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2767                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2768                null /* crashHandler */);
2769    }
2770
2771    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2772            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2773            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2774            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2775        long startTime = SystemClock.elapsedRealtime();
2776        ProcessRecord app;
2777        if (!isolated) {
2778            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2779            checkTime(startTime, "startProcess: after getProcessRecord");
2780        } else {
2781            // If this is an isolated process, it can't re-use an existing process.
2782            app = null;
2783        }
2784        // We don't have to do anything more if:
2785        // (1) There is an existing application record; and
2786        // (2) The caller doesn't think it is dead, OR there is no thread
2787        //     object attached to it so we know it couldn't have crashed; and
2788        // (3) There is a pid assigned to it, so it is either starting or
2789        //     already running.
2790        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2791                + " app=" + app + " knownToBeDead=" + knownToBeDead
2792                + " thread=" + (app != null ? app.thread : null)
2793                + " pid=" + (app != null ? app.pid : -1));
2794        if (app != null && app.pid > 0) {
2795            if (!knownToBeDead || app.thread == null) {
2796                // We already have the app running, or are waiting for it to
2797                // come up (we have a pid but not yet its thread), so keep it.
2798                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2799                // If this is a new package in the process, add the package to the list
2800                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2801                checkTime(startTime, "startProcess: done, added package to proc");
2802                return app;
2803            }
2804
2805            // An application record is attached to a previous process,
2806            // clean it up now.
2807            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2808            checkTime(startTime, "startProcess: bad proc running, killing");
2809            Process.killProcessGroup(app.info.uid, app.pid);
2810            handleAppDiedLocked(app, true, true);
2811            checkTime(startTime, "startProcess: done killing old proc");
2812        }
2813
2814        String hostingNameStr = hostingName != null
2815                ? hostingName.flattenToShortString() : null;
2816
2817        if (!isolated) {
2818            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2819                // If we are in the background, then check to see if this process
2820                // is bad.  If so, we will just silently fail.
2821                if (mBadProcesses.get(info.processName, info.uid) != null) {
2822                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2823                            + "/" + info.processName);
2824                    return null;
2825                }
2826            } else {
2827                // When the user is explicitly starting a process, then clear its
2828                // crash count so that we won't make it bad until they see at
2829                // least one crash dialog again, and make the process good again
2830                // if it had been bad.
2831                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2832                        + "/" + info.processName);
2833                mProcessCrashTimes.remove(info.processName, info.uid);
2834                if (mBadProcesses.get(info.processName, info.uid) != null) {
2835                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2836                            UserHandle.getUserId(info.uid), info.uid,
2837                            info.processName);
2838                    mBadProcesses.remove(info.processName, info.uid);
2839                    if (app != null) {
2840                        app.bad = false;
2841                    }
2842                }
2843            }
2844        }
2845
2846        if (app == null) {
2847            checkTime(startTime, "startProcess: creating new process record");
2848            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2849            app.crashHandler = crashHandler;
2850            if (app == null) {
2851                Slog.w(TAG, "Failed making new process record for "
2852                        + processName + "/" + info.uid + " isolated=" + isolated);
2853                return null;
2854            }
2855            mProcessNames.put(processName, app.uid, app);
2856            if (isolated) {
2857                mIsolatedProcesses.put(app.uid, app);
2858            }
2859            checkTime(startTime, "startProcess: done creating new process record");
2860        } else {
2861            // If this is a new package in the process, add the package to the list
2862            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2863            checkTime(startTime, "startProcess: added package to existing proc");
2864        }
2865
2866        // If the system is not ready yet, then hold off on starting this
2867        // process until it is.
2868        if (!mProcessesReady
2869                && !isAllowedWhileBooting(info)
2870                && !allowWhileBooting) {
2871            if (!mProcessesOnHold.contains(app)) {
2872                mProcessesOnHold.add(app);
2873            }
2874            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2875            checkTime(startTime, "startProcess: returning with proc on hold");
2876            return app;
2877        }
2878
2879        checkTime(startTime, "startProcess: stepping in to startProcess");
2880        startProcessLocked(
2881                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2882        checkTime(startTime, "startProcess: done starting proc!");
2883        return (app.pid != 0) ? app : null;
2884    }
2885
2886    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2887        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2888    }
2889
2890    private final void startProcessLocked(ProcessRecord app,
2891            String hostingType, String hostingNameStr) {
2892        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2893                null /* entryPoint */, null /* entryPointArgs */);
2894    }
2895
2896    private final void startProcessLocked(ProcessRecord app, String hostingType,
2897            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2898        long startTime = SystemClock.elapsedRealtime();
2899        if (app.pid > 0 && app.pid != MY_PID) {
2900            checkTime(startTime, "startProcess: removing from pids map");
2901            synchronized (mPidsSelfLocked) {
2902                mPidsSelfLocked.remove(app.pid);
2903                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2904            }
2905            checkTime(startTime, "startProcess: done removing from pids map");
2906            app.setPid(0);
2907        }
2908
2909        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2910                "startProcessLocked removing on hold: " + app);
2911        mProcessesOnHold.remove(app);
2912
2913        checkTime(startTime, "startProcess: starting to update cpu stats");
2914        updateCpuStats();
2915        checkTime(startTime, "startProcess: done updating cpu stats");
2916
2917        try {
2918            int uid = app.uid;
2919
2920            int[] gids = null;
2921            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2922            if (!app.isolated) {
2923                int[] permGids = null;
2924                try {
2925                    checkTime(startTime, "startProcess: getting gids from package manager");
2926                    final PackageManager pm = mContext.getPackageManager();
2927                    permGids = pm.getPackageGids(app.info.packageName);
2928
2929                    if (Environment.isExternalStorageEmulated()) {
2930                        checkTime(startTime, "startProcess: checking external storage perm");
2931                        if (pm.checkPermission(
2932                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2933                                app.info.packageName) == PERMISSION_GRANTED) {
2934                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2935                        } else {
2936                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2937                        }
2938                    }
2939                } catch (PackageManager.NameNotFoundException e) {
2940                    Slog.w(TAG, "Unable to retrieve gids", e);
2941                }
2942
2943                /*
2944                 * Add shared application and profile GIDs so applications can share some
2945                 * resources like shared libraries and access user-wide resources
2946                 */
2947                if (permGids == null) {
2948                    gids = new int[2];
2949                } else {
2950                    gids = new int[permGids.length + 2];
2951                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2952                }
2953                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2954                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2955            }
2956            checkTime(startTime, "startProcess: building args");
2957            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2958                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2959                        && mTopComponent != null
2960                        && app.processName.equals(mTopComponent.getPackageName())) {
2961                    uid = 0;
2962                }
2963                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2964                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2965                    uid = 0;
2966                }
2967            }
2968            int debugFlags = 0;
2969            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2970                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2971                // Also turn on CheckJNI for debuggable apps. It's quite
2972                // awkward to turn on otherwise.
2973                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2974            }
2975            // Run the app in safe mode if its manifest requests so or the
2976            // system is booted in safe mode.
2977            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2978                mSafeMode == true) {
2979                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2980            }
2981            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2986            }
2987            if ("1".equals(SystemProperties.get("debug.assert"))) {
2988                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2989            }
2990
2991            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2992            if (requiredAbi == null) {
2993                requiredAbi = Build.SUPPORTED_ABIS[0];
2994            }
2995
2996            String instructionSet = null;
2997            if (app.info.primaryCpuAbi != null) {
2998                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2999            }
3000
3001            // Start the process.  It will either succeed and return a result containing
3002            // the PID of the new process, or else throw a RuntimeException.
3003            boolean isActivityProcess = (entryPoint == null);
3004            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3005            checkTime(startTime, "startProcess: asking zygote to start proc");
3006            Process.ProcessStartResult startResult = Process.start(entryPoint,
3007                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3008                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3009                    app.info.dataDir, entryPointArgs);
3010            checkTime(startTime, "startProcess: returned from zygote!");
3011
3012            if (app.isolated) {
3013                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3014            }
3015            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3016            checkTime(startTime, "startProcess: done updating battery stats");
3017
3018            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3019                    UserHandle.getUserId(uid), startResult.pid, uid,
3020                    app.processName, hostingType,
3021                    hostingNameStr != null ? hostingNameStr : "");
3022
3023            if (app.persistent) {
3024                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3025            }
3026
3027            checkTime(startTime, "startProcess: building log message");
3028            StringBuilder buf = mStringBuilder;
3029            buf.setLength(0);
3030            buf.append("Start proc ");
3031            buf.append(app.processName);
3032            if (!isActivityProcess) {
3033                buf.append(" [");
3034                buf.append(entryPoint);
3035                buf.append("]");
3036            }
3037            buf.append(" for ");
3038            buf.append(hostingType);
3039            if (hostingNameStr != null) {
3040                buf.append(" ");
3041                buf.append(hostingNameStr);
3042            }
3043            buf.append(": pid=");
3044            buf.append(startResult.pid);
3045            buf.append(" uid=");
3046            buf.append(uid);
3047            buf.append(" gids={");
3048            if (gids != null) {
3049                for (int gi=0; gi<gids.length; gi++) {
3050                    if (gi != 0) buf.append(", ");
3051                    buf.append(gids[gi]);
3052
3053                }
3054            }
3055            buf.append("}");
3056            if (requiredAbi != null) {
3057                buf.append(" abi=");
3058                buf.append(requiredAbi);
3059            }
3060            Slog.i(TAG, buf.toString());
3061            app.setPid(startResult.pid);
3062            app.usingWrapper = startResult.usingWrapper;
3063            app.removed = false;
3064            app.killed = false;
3065            app.killedByAm = false;
3066            checkTime(startTime, "startProcess: starting to update pids map");
3067            synchronized (mPidsSelfLocked) {
3068                this.mPidsSelfLocked.put(startResult.pid, app);
3069                if (isActivityProcess) {
3070                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3071                    msg.obj = app;
3072                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3073                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3074                }
3075            }
3076            checkTime(startTime, "startProcess: done updating pids map");
3077        } catch (RuntimeException e) {
3078            // XXX do better error recovery.
3079            app.setPid(0);
3080            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3081            if (app.isolated) {
3082                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3083            }
3084            Slog.e(TAG, "Failure starting process " + app.processName, e);
3085        }
3086    }
3087
3088    void updateUsageStats(ActivityRecord component, boolean resumed) {
3089        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3090        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3091        if (resumed) {
3092            if (mUsageStatsService != null) {
3093                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3094                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3095            }
3096            synchronized (stats) {
3097                stats.noteActivityResumedLocked(component.app.uid);
3098            }
3099        } else {
3100            if (mUsageStatsService != null) {
3101                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3102                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3103            }
3104            synchronized (stats) {
3105                stats.noteActivityPausedLocked(component.app.uid);
3106            }
3107        }
3108    }
3109
3110    Intent getHomeIntent() {
3111        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3112        intent.setComponent(mTopComponent);
3113        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3114            intent.addCategory(Intent.CATEGORY_HOME);
3115        }
3116        return intent;
3117    }
3118
3119    boolean startHomeActivityLocked(int userId) {
3120        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3121                && mTopAction == null) {
3122            // We are running in factory test mode, but unable to find
3123            // the factory test app, so just sit around displaying the
3124            // error message and don't try to start anything.
3125            return false;
3126        }
3127        Intent intent = getHomeIntent();
3128        ActivityInfo aInfo =
3129            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3130        if (aInfo != null) {
3131            intent.setComponent(new ComponentName(
3132                    aInfo.applicationInfo.packageName, aInfo.name));
3133            // Don't do this if the home app is currently being
3134            // instrumented.
3135            aInfo = new ActivityInfo(aInfo);
3136            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3137            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3138                    aInfo.applicationInfo.uid, true);
3139            if (app == null || app.instrumentationClass == null) {
3140                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3141                mStackSupervisor.startHomeActivity(intent, aInfo);
3142            }
3143        }
3144
3145        return true;
3146    }
3147
3148    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3149        ActivityInfo ai = null;
3150        ComponentName comp = intent.getComponent();
3151        try {
3152            if (comp != null) {
3153                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3154            } else {
3155                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3156                        intent,
3157                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3158                            flags, userId);
3159
3160                if (info != null) {
3161                    ai = info.activityInfo;
3162                }
3163            }
3164        } catch (RemoteException e) {
3165            // ignore
3166        }
3167
3168        return ai;
3169    }
3170
3171    /**
3172     * Starts the "new version setup screen" if appropriate.
3173     */
3174    void startSetupActivityLocked() {
3175        // Only do this once per boot.
3176        if (mCheckedForSetup) {
3177            return;
3178        }
3179
3180        // We will show this screen if the current one is a different
3181        // version than the last one shown, and we are not running in
3182        // low-level factory test mode.
3183        final ContentResolver resolver = mContext.getContentResolver();
3184        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3185                Settings.Global.getInt(resolver,
3186                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3187            mCheckedForSetup = true;
3188
3189            // See if we should be showing the platform update setup UI.
3190            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3191            List<ResolveInfo> ris = mContext.getPackageManager()
3192                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3193
3194            // We don't allow third party apps to replace this.
3195            ResolveInfo ri = null;
3196            for (int i=0; ris != null && i<ris.size(); i++) {
3197                if ((ris.get(i).activityInfo.applicationInfo.flags
3198                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3199                    ri = ris.get(i);
3200                    break;
3201                }
3202            }
3203
3204            if (ri != null) {
3205                String vers = ri.activityInfo.metaData != null
3206                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3207                        : null;
3208                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3209                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3210                            Intent.METADATA_SETUP_VERSION);
3211                }
3212                String lastVers = Settings.Secure.getString(
3213                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3214                if (vers != null && !vers.equals(lastVers)) {
3215                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3216                    intent.setComponent(new ComponentName(
3217                            ri.activityInfo.packageName, ri.activityInfo.name));
3218                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3219                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3220                            null);
3221                }
3222            }
3223        }
3224    }
3225
3226    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3227        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3228    }
3229
3230    void enforceNotIsolatedCaller(String caller) {
3231        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3232            throw new SecurityException("Isolated process not allowed to call " + caller);
3233        }
3234    }
3235
3236    void enforceShellRestriction(String restriction, int userHandle) {
3237        if (Binder.getCallingUid() == Process.SHELL_UID) {
3238            if (userHandle < 0
3239                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3240                throw new SecurityException("Shell does not have permission to access user "
3241                        + userHandle);
3242            }
3243        }
3244    }
3245
3246    @Override
3247    public int getFrontActivityScreenCompatMode() {
3248        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3249        synchronized (this) {
3250            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3251        }
3252    }
3253
3254    @Override
3255    public void setFrontActivityScreenCompatMode(int mode) {
3256        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3257                "setFrontActivityScreenCompatMode");
3258        synchronized (this) {
3259            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3260        }
3261    }
3262
3263    @Override
3264    public int getPackageScreenCompatMode(String packageName) {
3265        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3266        synchronized (this) {
3267            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3268        }
3269    }
3270
3271    @Override
3272    public void setPackageScreenCompatMode(String packageName, int mode) {
3273        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3274                "setPackageScreenCompatMode");
3275        synchronized (this) {
3276            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3277        }
3278    }
3279
3280    @Override
3281    public boolean getPackageAskScreenCompat(String packageName) {
3282        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3283        synchronized (this) {
3284            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3285        }
3286    }
3287
3288    @Override
3289    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3290        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3291                "setPackageAskScreenCompat");
3292        synchronized (this) {
3293            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3294        }
3295    }
3296
3297    private void dispatchProcessesChanged() {
3298        int N;
3299        synchronized (this) {
3300            N = mPendingProcessChanges.size();
3301            if (mActiveProcessChanges.length < N) {
3302                mActiveProcessChanges = new ProcessChangeItem[N];
3303            }
3304            mPendingProcessChanges.toArray(mActiveProcessChanges);
3305            mAvailProcessChanges.addAll(mPendingProcessChanges);
3306            mPendingProcessChanges.clear();
3307            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3308        }
3309
3310        int i = mProcessObservers.beginBroadcast();
3311        while (i > 0) {
3312            i--;
3313            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3314            if (observer != null) {
3315                try {
3316                    for (int j=0; j<N; j++) {
3317                        ProcessChangeItem item = mActiveProcessChanges[j];
3318                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3319                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3320                                    + item.pid + " uid=" + item.uid + ": "
3321                                    + item.foregroundActivities);
3322                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3323                                    item.foregroundActivities);
3324                        }
3325                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3326                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3327                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3328                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3329                        }
3330                    }
3331                } catch (RemoteException e) {
3332                }
3333            }
3334        }
3335        mProcessObservers.finishBroadcast();
3336    }
3337
3338    private void dispatchProcessDied(int pid, int uid) {
3339        int i = mProcessObservers.beginBroadcast();
3340        while (i > 0) {
3341            i--;
3342            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3343            if (observer != null) {
3344                try {
3345                    observer.onProcessDied(pid, uid);
3346                } catch (RemoteException e) {
3347                }
3348            }
3349        }
3350        mProcessObservers.finishBroadcast();
3351    }
3352
3353    @Override
3354    public final int startActivity(IApplicationThread caller, String callingPackage,
3355            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3356            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3357        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3358            resultWho, requestCode, startFlags, profilerInfo, options,
3359            UserHandle.getCallingUserId());
3360    }
3361
3362    @Override
3363    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3364            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3365            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3366        enforceNotIsolatedCaller("startActivity");
3367        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3368                false, ALLOW_FULL_ONLY, "startActivity", null);
3369        // TODO: Switch to user app stacks here.
3370        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3371                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3372                profilerInfo, null, null, options, userId, null, null);
3373    }
3374
3375    @Override
3376    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3377            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3378            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3379
3380        // This is very dangerous -- it allows you to perform a start activity (including
3381        // permission grants) as any app that may launch one of your own activities.  So
3382        // we will only allow this to be done from activities that are part of the core framework,
3383        // and then only when they are running as the system.
3384        final ActivityRecord sourceRecord;
3385        final int targetUid;
3386        final String targetPackage;
3387        synchronized (this) {
3388            if (resultTo == null) {
3389                throw new SecurityException("Must be called from an activity");
3390            }
3391            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3392            if (sourceRecord == null) {
3393                throw new SecurityException("Called with bad activity token: " + resultTo);
3394            }
3395            if (!sourceRecord.info.packageName.equals("android")) {
3396                throw new SecurityException(
3397                        "Must be called from an activity that is declared in the android package");
3398            }
3399            if (sourceRecord.app == null) {
3400                throw new SecurityException("Called without a process attached to activity");
3401            }
3402            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3403                // This is still okay, as long as this activity is running under the
3404                // uid of the original calling activity.
3405                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3406                    throw new SecurityException(
3407                            "Calling activity in uid " + sourceRecord.app.uid
3408                                    + " must be system uid or original calling uid "
3409                                    + sourceRecord.launchedFromUid);
3410                }
3411            }
3412            targetUid = sourceRecord.launchedFromUid;
3413            targetPackage = sourceRecord.launchedFromPackage;
3414        }
3415
3416        if (userId == UserHandle.USER_NULL) {
3417            userId = UserHandle.getUserId(sourceRecord.app.uid);
3418        }
3419
3420        // TODO: Switch to user app stacks here.
3421        try {
3422            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3423                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3424                    null, null, options, userId, null, null);
3425            return ret;
3426        } catch (SecurityException e) {
3427            // XXX need to figure out how to propagate to original app.
3428            // A SecurityException here is generally actually a fault of the original
3429            // calling activity (such as a fairly granting permissions), so propagate it
3430            // back to them.
3431            /*
3432            StringBuilder msg = new StringBuilder();
3433            msg.append("While launching");
3434            msg.append(intent.toString());
3435            msg.append(": ");
3436            msg.append(e.getMessage());
3437            */
3438            throw e;
3439        }
3440    }
3441
3442    @Override
3443    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3444            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3445            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3446        enforceNotIsolatedCaller("startActivityAndWait");
3447        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3448                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3449        WaitResult res = new WaitResult();
3450        // TODO: Switch to user app stacks here.
3451        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3452                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3453                options, userId, null, null);
3454        return res;
3455    }
3456
3457    @Override
3458    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3459            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3460            int startFlags, Configuration config, Bundle options, int userId) {
3461        enforceNotIsolatedCaller("startActivityWithConfig");
3462        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3463                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3464        // TODO: Switch to user app stacks here.
3465        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3466                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3467                null, null, config, options, userId, null, null);
3468        return ret;
3469    }
3470
3471    @Override
3472    public int startActivityIntentSender(IApplicationThread caller,
3473            IntentSender intent, Intent fillInIntent, String resolvedType,
3474            IBinder resultTo, String resultWho, int requestCode,
3475            int flagsMask, int flagsValues, Bundle options) {
3476        enforceNotIsolatedCaller("startActivityIntentSender");
3477        // Refuse possible leaked file descriptors
3478        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3479            throw new IllegalArgumentException("File descriptors passed in Intent");
3480        }
3481
3482        IIntentSender sender = intent.getTarget();
3483        if (!(sender instanceof PendingIntentRecord)) {
3484            throw new IllegalArgumentException("Bad PendingIntent object");
3485        }
3486
3487        PendingIntentRecord pir = (PendingIntentRecord)sender;
3488
3489        synchronized (this) {
3490            // If this is coming from the currently resumed activity, it is
3491            // effectively saying that app switches are allowed at this point.
3492            final ActivityStack stack = getFocusedStack();
3493            if (stack.mResumedActivity != null &&
3494                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3495                mAppSwitchesAllowedTime = 0;
3496            }
3497        }
3498        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3499                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3500        return ret;
3501    }
3502
3503    @Override
3504    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3505            Intent intent, String resolvedType, IVoiceInteractionSession session,
3506            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3507            Bundle options, int userId) {
3508        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3509                != PackageManager.PERMISSION_GRANTED) {
3510            String msg = "Permission Denial: startVoiceActivity() from pid="
3511                    + Binder.getCallingPid()
3512                    + ", uid=" + Binder.getCallingUid()
3513                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3514            Slog.w(TAG, msg);
3515            throw new SecurityException(msg);
3516        }
3517        if (session == null || interactor == null) {
3518            throw new NullPointerException("null session or interactor");
3519        }
3520        userId = handleIncomingUser(callingPid, callingUid, userId,
3521                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3522        // TODO: Switch to user app stacks here.
3523        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3524                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3525                null, options, userId, null, null);
3526    }
3527
3528    @Override
3529    public boolean startNextMatchingActivity(IBinder callingActivity,
3530            Intent intent, Bundle options) {
3531        // Refuse possible leaked file descriptors
3532        if (intent != null && intent.hasFileDescriptors() == true) {
3533            throw new IllegalArgumentException("File descriptors passed in Intent");
3534        }
3535
3536        synchronized (this) {
3537            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3538            if (r == null) {
3539                ActivityOptions.abort(options);
3540                return false;
3541            }
3542            if (r.app == null || r.app.thread == null) {
3543                // The caller is not running...  d'oh!
3544                ActivityOptions.abort(options);
3545                return false;
3546            }
3547            intent = new Intent(intent);
3548            // The caller is not allowed to change the data.
3549            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3550            // And we are resetting to find the next component...
3551            intent.setComponent(null);
3552
3553            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3554
3555            ActivityInfo aInfo = null;
3556            try {
3557                List<ResolveInfo> resolves =
3558                    AppGlobals.getPackageManager().queryIntentActivities(
3559                            intent, r.resolvedType,
3560                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3561                            UserHandle.getCallingUserId());
3562
3563                // Look for the original activity in the list...
3564                final int N = resolves != null ? resolves.size() : 0;
3565                for (int i=0; i<N; i++) {
3566                    ResolveInfo rInfo = resolves.get(i);
3567                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3568                            && rInfo.activityInfo.name.equals(r.info.name)) {
3569                        // We found the current one...  the next matching is
3570                        // after it.
3571                        i++;
3572                        if (i<N) {
3573                            aInfo = resolves.get(i).activityInfo;
3574                        }
3575                        if (debug) {
3576                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3577                                    + "/" + r.info.name);
3578                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3579                                    + "/" + aInfo.name);
3580                        }
3581                        break;
3582                    }
3583                }
3584            } catch (RemoteException e) {
3585            }
3586
3587            if (aInfo == null) {
3588                // Nobody who is next!
3589                ActivityOptions.abort(options);
3590                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3591                return false;
3592            }
3593
3594            intent.setComponent(new ComponentName(
3595                    aInfo.applicationInfo.packageName, aInfo.name));
3596            intent.setFlags(intent.getFlags()&~(
3597                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3598                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3599                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3600                    Intent.FLAG_ACTIVITY_NEW_TASK));
3601
3602            // Okay now we need to start the new activity, replacing the
3603            // currently running activity.  This is a little tricky because
3604            // we want to start the new one as if the current one is finished,
3605            // but not finish the current one first so that there is no flicker.
3606            // And thus...
3607            final boolean wasFinishing = r.finishing;
3608            r.finishing = true;
3609
3610            // Propagate reply information over to the new activity.
3611            final ActivityRecord resultTo = r.resultTo;
3612            final String resultWho = r.resultWho;
3613            final int requestCode = r.requestCode;
3614            r.resultTo = null;
3615            if (resultTo != null) {
3616                resultTo.removeResultsLocked(r, resultWho, requestCode);
3617            }
3618
3619            final long origId = Binder.clearCallingIdentity();
3620            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3621                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3622                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3623                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3624            Binder.restoreCallingIdentity(origId);
3625
3626            r.finishing = wasFinishing;
3627            if (res != ActivityManager.START_SUCCESS) {
3628                return false;
3629            }
3630            return true;
3631        }
3632    }
3633
3634    @Override
3635    public final int startActivityFromRecents(int taskId, Bundle options) {
3636        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3637            String msg = "Permission Denial: startActivityFromRecents called without " +
3638                    START_TASKS_FROM_RECENTS;
3639            Slog.w(TAG, msg);
3640            throw new SecurityException(msg);
3641        }
3642        return startActivityFromRecentsInner(taskId, options);
3643    }
3644
3645    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3646        final TaskRecord task;
3647        final int callingUid;
3648        final String callingPackage;
3649        final Intent intent;
3650        final int userId;
3651        synchronized (this) {
3652            task = recentTaskForIdLocked(taskId);
3653            if (task == null) {
3654                throw new IllegalArgumentException("Task " + taskId + " not found.");
3655            }
3656            callingUid = task.mCallingUid;
3657            callingPackage = task.mCallingPackage;
3658            intent = task.intent;
3659            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3660            userId = task.userId;
3661        }
3662        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3663                options, userId, null, task);
3664    }
3665
3666    final int startActivityInPackage(int uid, String callingPackage,
3667            Intent intent, String resolvedType, IBinder resultTo,
3668            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3669            IActivityContainer container, TaskRecord inTask) {
3670
3671        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3672                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3673
3674        // TODO: Switch to user app stacks here.
3675        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3676                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3677                null, null, null, options, userId, container, inTask);
3678        return ret;
3679    }
3680
3681    @Override
3682    public final int startActivities(IApplicationThread caller, String callingPackage,
3683            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3684            int userId) {
3685        enforceNotIsolatedCaller("startActivities");
3686        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3687                false, ALLOW_FULL_ONLY, "startActivity", null);
3688        // TODO: Switch to user app stacks here.
3689        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3690                resolvedTypes, resultTo, options, userId);
3691        return ret;
3692    }
3693
3694    final int startActivitiesInPackage(int uid, String callingPackage,
3695            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3696            Bundle options, int userId) {
3697
3698        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3699                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3700        // TODO: Switch to user app stacks here.
3701        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3702                resultTo, options, userId);
3703        return ret;
3704    }
3705
3706    //explicitly remove thd old information in mRecentTasks when removing existing user.
3707    private void removeRecentTasksForUserLocked(int userId) {
3708        if(userId <= 0) {
3709            Slog.i(TAG, "Can't remove recent task on user " + userId);
3710            return;
3711        }
3712
3713        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3714            TaskRecord tr = mRecentTasks.get(i);
3715            if (tr.userId == userId) {
3716                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3717                        + " when finishing user" + userId);
3718                mRecentTasks.remove(i);
3719                tr.removedFromRecents(mTaskPersister);
3720            }
3721        }
3722
3723        // Remove tasks from persistent storage.
3724        mTaskPersister.wakeup(null, true);
3725    }
3726
3727    // Sort by taskId
3728    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3729        @Override
3730        public int compare(TaskRecord lhs, TaskRecord rhs) {
3731            return rhs.taskId - lhs.taskId;
3732        }
3733    };
3734
3735    // Extract the affiliates of the chain containing mRecentTasks[start].
3736    private int processNextAffiliateChain(int start) {
3737        final TaskRecord startTask = mRecentTasks.get(start);
3738        final int affiliateId = startTask.mAffiliatedTaskId;
3739
3740        // Quick identification of isolated tasks. I.e. those not launched behind.
3741        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3742                startTask.mNextAffiliate == null) {
3743            // There is still a slim chance that there are other tasks that point to this task
3744            // and that the chain is so messed up that this task no longer points to them but
3745            // the gain of this optimization outweighs the risk.
3746            startTask.inRecents = true;
3747            return start + 1;
3748        }
3749
3750        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3751        mTmpRecents.clear();
3752        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3753            final TaskRecord task = mRecentTasks.get(i);
3754            if (task.mAffiliatedTaskId == affiliateId) {
3755                mRecentTasks.remove(i);
3756                mTmpRecents.add(task);
3757            }
3758        }
3759
3760        // Sort them all by taskId. That is the order they were create in and that order will
3761        // always be correct.
3762        Collections.sort(mTmpRecents, mTaskRecordComparator);
3763
3764        // Go through and fix up the linked list.
3765        // The first one is the end of the chain and has no next.
3766        final TaskRecord first = mTmpRecents.get(0);
3767        first.inRecents = true;
3768        if (first.mNextAffiliate != null) {
3769            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3770            first.setNextAffiliate(null);
3771            mTaskPersister.wakeup(first, false);
3772        }
3773        // Everything in the middle is doubly linked from next to prev.
3774        final int tmpSize = mTmpRecents.size();
3775        for (int i = 0; i < tmpSize - 1; ++i) {
3776            final TaskRecord next = mTmpRecents.get(i);
3777            final TaskRecord prev = mTmpRecents.get(i + 1);
3778            if (next.mPrevAffiliate != prev) {
3779                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3780                        " setting prev=" + prev);
3781                next.setPrevAffiliate(prev);
3782                mTaskPersister.wakeup(next, false);
3783            }
3784            if (prev.mNextAffiliate != next) {
3785                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3786                        " setting next=" + next);
3787                prev.setNextAffiliate(next);
3788                mTaskPersister.wakeup(prev, false);
3789            }
3790            prev.inRecents = true;
3791        }
3792        // The last one is the beginning of the list and has no prev.
3793        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3794        if (last.mPrevAffiliate != null) {
3795            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3796            last.setPrevAffiliate(null);
3797            mTaskPersister.wakeup(last, false);
3798        }
3799
3800        // Insert the group back into mRecentTasks at start.
3801        mRecentTasks.addAll(start, mTmpRecents);
3802
3803        // Let the caller know where we left off.
3804        return start + tmpSize;
3805    }
3806
3807    /**
3808     * Update the recent tasks lists: make sure tasks should still be here (their
3809     * applications / activities still exist), update their availability, fixup ordering
3810     * of affiliations.
3811     */
3812    void cleanupRecentTasksLocked(int userId) {
3813        if (mRecentTasks == null) {
3814            // Happens when called from the packagemanager broadcast before boot.
3815            return;
3816        }
3817
3818        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3819        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3820        final IPackageManager pm = AppGlobals.getPackageManager();
3821        final ActivityInfo dummyAct = new ActivityInfo();
3822        final ApplicationInfo dummyApp = new ApplicationInfo();
3823
3824        int N = mRecentTasks.size();
3825
3826        int[] users = userId == UserHandle.USER_ALL
3827                ? getUsersLocked() : new int[] { userId };
3828        for (int user : users) {
3829            for (int i = 0; i < N; i++) {
3830                TaskRecord task = mRecentTasks.get(i);
3831                if (task.userId != user) {
3832                    // Only look at tasks for the user ID of interest.
3833                    continue;
3834                }
3835                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3836                    // This situation is broken, and we should just get rid of it now.
3837                    mRecentTasks.remove(i);
3838                    task.removedFromRecents(mTaskPersister);
3839                    i--;
3840                    N--;
3841                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3842                    continue;
3843                }
3844                // Check whether this activity is currently available.
3845                if (task.realActivity != null) {
3846                    ActivityInfo ai = availActCache.get(task.realActivity);
3847                    if (ai == null) {
3848                        try {
3849                            ai = pm.getActivityInfo(task.realActivity,
3850                                    PackageManager.GET_UNINSTALLED_PACKAGES
3851                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3852                        } catch (RemoteException e) {
3853                            // Will never happen.
3854                            continue;
3855                        }
3856                        if (ai == null) {
3857                            ai = dummyAct;
3858                        }
3859                        availActCache.put(task.realActivity, ai);
3860                    }
3861                    if (ai == dummyAct) {
3862                        // This could be either because the activity no longer exists, or the
3863                        // app is temporarily gone.  For the former we want to remove the recents
3864                        // entry; for the latter we want to mark it as unavailable.
3865                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3866                        if (app == null) {
3867                            try {
3868                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3869                                        PackageManager.GET_UNINSTALLED_PACKAGES
3870                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3871                            } catch (RemoteException e) {
3872                                // Will never happen.
3873                                continue;
3874                            }
3875                            if (app == null) {
3876                                app = dummyApp;
3877                            }
3878                            availAppCache.put(task.realActivity.getPackageName(), app);
3879                        }
3880                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3881                            // Doesn't exist any more!  Good-bye.
3882                            mRecentTasks.remove(i);
3883                            task.removedFromRecents(mTaskPersister);
3884                            i--;
3885                            N--;
3886                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3887                            continue;
3888                        } else {
3889                            // Otherwise just not available for now.
3890                            if (task.isAvailable) {
3891                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3892                                        + task);
3893                            }
3894                            task.isAvailable = false;
3895                        }
3896                    } else {
3897                        if (!ai.enabled || !ai.applicationInfo.enabled
3898                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3899                            if (task.isAvailable) {
3900                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3901                                        + task + " (enabled=" + ai.enabled + "/"
3902                                        + ai.applicationInfo.enabled +  " flags="
3903                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3904                            }
3905                            task.isAvailable = false;
3906                        } else {
3907                            if (!task.isAvailable) {
3908                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3909                                        + task);
3910                            }
3911                            task.isAvailable = true;
3912                        }
3913                    }
3914                }
3915            }
3916        }
3917
3918        // Verify the affiliate chain for each task.
3919        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3920        }
3921
3922        mTmpRecents.clear();
3923        // mRecentTasks is now in sorted, affiliated order.
3924    }
3925
3926    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3927        int N = mRecentTasks.size();
3928        TaskRecord top = task;
3929        int topIndex = taskIndex;
3930        while (top.mNextAffiliate != null && topIndex > 0) {
3931            top = top.mNextAffiliate;
3932            topIndex--;
3933        }
3934        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3935                + topIndex + " from intial " + taskIndex);
3936        // Find the end of the chain, doing a sanity check along the way.
3937        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3938        int endIndex = topIndex;
3939        TaskRecord prev = top;
3940        while (endIndex < N) {
3941            TaskRecord cur = mRecentTasks.get(endIndex);
3942            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3943                    + endIndex + " " + cur);
3944            if (cur == top) {
3945                // Verify start of the chain.
3946                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3947                    Slog.wtf(TAG, "Bad chain @" + endIndex
3948                            + ": first task has next affiliate: " + prev);
3949                    sane = false;
3950                    break;
3951                }
3952            } else {
3953                // Verify middle of the chain's next points back to the one before.
3954                if (cur.mNextAffiliate != prev
3955                        || cur.mNextAffiliateTaskId != prev.taskId) {
3956                    Slog.wtf(TAG, "Bad chain @" + endIndex
3957                            + ": middle task " + cur + " @" + endIndex
3958                            + " has bad next affiliate "
3959                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3960                            + ", expected " + prev);
3961                    sane = false;
3962                    break;
3963                }
3964            }
3965            if (cur.mPrevAffiliateTaskId == -1) {
3966                // Chain ends here.
3967                if (cur.mPrevAffiliate != null) {
3968                    Slog.wtf(TAG, "Bad chain @" + endIndex
3969                            + ": last task " + cur + " has previous affiliate "
3970                            + cur.mPrevAffiliate);
3971                    sane = false;
3972                }
3973                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3974                break;
3975            } else {
3976                // Verify middle of the chain's prev points to a valid item.
3977                if (cur.mPrevAffiliate == null) {
3978                    Slog.wtf(TAG, "Bad chain @" + endIndex
3979                            + ": task " + cur + " has previous affiliate "
3980                            + cur.mPrevAffiliate + " but should be id "
3981                            + cur.mPrevAffiliate);
3982                    sane = false;
3983                    break;
3984                }
3985            }
3986            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3987                Slog.wtf(TAG, "Bad chain @" + endIndex
3988                        + ": task " + cur + " has affiliated id "
3989                        + cur.mAffiliatedTaskId + " but should be "
3990                        + task.mAffiliatedTaskId);
3991                sane = false;
3992                break;
3993            }
3994            prev = cur;
3995            endIndex++;
3996            if (endIndex >= N) {
3997                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3998                        + ": last task " + prev);
3999                sane = false;
4000                break;
4001            }
4002        }
4003        if (sane) {
4004            if (endIndex < taskIndex) {
4005                Slog.wtf(TAG, "Bad chain @" + endIndex
4006                        + ": did not extend to task " + task + " @" + taskIndex);
4007                sane = false;
4008            }
4009        }
4010        if (sane) {
4011            // All looks good, we can just move all of the affiliated tasks
4012            // to the top.
4013            for (int i=topIndex; i<=endIndex; i++) {
4014                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4015                        + " from " + i + " to " + (i-topIndex));
4016                TaskRecord cur = mRecentTasks.remove(i);
4017                mRecentTasks.add(i-topIndex, cur);
4018            }
4019            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4020                    + " to " + endIndex);
4021            return true;
4022        }
4023
4024        // Whoops, couldn't do it.
4025        return false;
4026    }
4027
4028    final void addRecentTaskLocked(TaskRecord task) {
4029        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4030                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4031
4032        int N = mRecentTasks.size();
4033        // Quick case: check if the top-most recent task is the same.
4034        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4035            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4036            return;
4037        }
4038        // Another quick case: check if this is part of a set of affiliated
4039        // tasks that are at the top.
4040        if (isAffiliated && N > 0 && task.inRecents
4041                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4042            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4043                    + " at top when adding " + task);
4044            return;
4045        }
4046        // Another quick case: never add voice sessions.
4047        if (task.voiceSession != null) {
4048            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4049            return;
4050        }
4051
4052        boolean needAffiliationFix = false;
4053
4054        // Slightly less quick case: the task is already in recents, so all we need
4055        // to do is move it.
4056        if (task.inRecents) {
4057            int taskIndex = mRecentTasks.indexOf(task);
4058            if (taskIndex >= 0) {
4059                if (!isAffiliated) {
4060                    // Simple case: this is not an affiliated task, so we just move it to the front.
4061                    mRecentTasks.remove(taskIndex);
4062                    mRecentTasks.add(0, task);
4063                    notifyTaskPersisterLocked(task, false);
4064                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4065                            + " from " + taskIndex);
4066                    return;
4067                } else {
4068                    // More complicated: need to keep all affiliated tasks together.
4069                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4070                        // All went well.
4071                        return;
4072                    }
4073
4074                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4075                    // everything and then go through our general path of adding a new task.
4076                    needAffiliationFix = true;
4077                }
4078            } else {
4079                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4080                needAffiliationFix = true;
4081            }
4082        }
4083
4084        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4085        trimRecentsForTask(task, true);
4086
4087        N = mRecentTasks.size();
4088        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4089            final TaskRecord tr = mRecentTasks.remove(N - 1);
4090            tr.removedFromRecents(mTaskPersister);
4091            N--;
4092        }
4093        task.inRecents = true;
4094        if (!isAffiliated || needAffiliationFix) {
4095            // If this is a simple non-affiliated task, or we had some failure trying to
4096            // handle it as part of an affilated task, then just place it at the top.
4097            mRecentTasks.add(0, task);
4098        } else if (isAffiliated) {
4099            // If this is a new affiliated task, then move all of the affiliated tasks
4100            // to the front and insert this new one.
4101            TaskRecord other = task.mNextAffiliate;
4102            if (other == null) {
4103                other = task.mPrevAffiliate;
4104            }
4105            if (other != null) {
4106                int otherIndex = mRecentTasks.indexOf(other);
4107                if (otherIndex >= 0) {
4108                    // Insert new task at appropriate location.
4109                    int taskIndex;
4110                    if (other == task.mNextAffiliate) {
4111                        // We found the index of our next affiliation, which is who is
4112                        // before us in the list, so add after that point.
4113                        taskIndex = otherIndex+1;
4114                    } else {
4115                        // We found the index of our previous affiliation, which is who is
4116                        // after us in the list, so add at their position.
4117                        taskIndex = otherIndex;
4118                    }
4119                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4120                            + taskIndex + ": " + task);
4121                    mRecentTasks.add(taskIndex, task);
4122
4123                    // Now move everything to the front.
4124                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4125                        // All went well.
4126                        return;
4127                    }
4128
4129                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4130                    // everything and then go through our general path of adding a new task.
4131                    needAffiliationFix = true;
4132                } else {
4133                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4134                            + other);
4135                    needAffiliationFix = true;
4136                }
4137            } else {
4138                if (DEBUG_RECENTS) Slog.d(TAG,
4139                        "addRecent: adding affiliated task without next/prev:" + task);
4140                needAffiliationFix = true;
4141            }
4142        }
4143        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4144
4145        if (needAffiliationFix) {
4146            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4147            cleanupRecentTasksLocked(task.userId);
4148        }
4149    }
4150
4151    /**
4152     * If needed, remove oldest existing entries in recents that are for the same kind
4153     * of task as the given one.
4154     */
4155    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4156        int N = mRecentTasks.size();
4157        final Intent intent = task.intent;
4158        final boolean document = intent != null && intent.isDocument();
4159
4160        int maxRecents = task.maxRecents - 1;
4161        for (int i=0; i<N; i++) {
4162            final TaskRecord tr = mRecentTasks.get(i);
4163            if (task != tr) {
4164                if (task.userId != tr.userId) {
4165                    continue;
4166                }
4167                if (i > MAX_RECENT_BITMAPS) {
4168                    tr.freeLastThumbnail();
4169                }
4170                final Intent trIntent = tr.intent;
4171                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4172                    (intent == null || !intent.filterEquals(trIntent))) {
4173                    continue;
4174                }
4175                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4176                if (document && trIsDocument) {
4177                    // These are the same document activity (not necessarily the same doc).
4178                    if (maxRecents > 0) {
4179                        --maxRecents;
4180                        continue;
4181                    }
4182                    // Hit the maximum number of documents for this task. Fall through
4183                    // and remove this document from recents.
4184                } else if (document || trIsDocument) {
4185                    // Only one of these is a document. Not the droid we're looking for.
4186                    continue;
4187                }
4188            }
4189
4190            if (!doTrim) {
4191                // If the caller is not actually asking for a trim, just tell them we reached
4192                // a point where the trim would happen.
4193                return i;
4194            }
4195
4196            // Either task and tr are the same or, their affinities match or their intents match
4197            // and neither of them is a document, or they are documents using the same activity
4198            // and their maxRecents has been reached.
4199            tr.disposeThumbnail();
4200            mRecentTasks.remove(i);
4201            if (task != tr) {
4202                tr.removedFromRecents(mTaskPersister);
4203            }
4204            i--;
4205            N--;
4206            if (task.intent == null) {
4207                // If the new recent task we are adding is not fully
4208                // specified, then replace it with the existing recent task.
4209                task = tr;
4210            }
4211            notifyTaskPersisterLocked(tr, false);
4212        }
4213
4214        return -1;
4215    }
4216
4217    @Override
4218    public void reportActivityFullyDrawn(IBinder token) {
4219        synchronized (this) {
4220            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4221            if (r == null) {
4222                return;
4223            }
4224            r.reportFullyDrawnLocked();
4225        }
4226    }
4227
4228    @Override
4229    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4230        synchronized (this) {
4231            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4232            if (r == null) {
4233                return;
4234            }
4235            final long origId = Binder.clearCallingIdentity();
4236            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4237            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4238                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4239            if (config != null) {
4240                r.frozenBeforeDestroy = true;
4241                if (!updateConfigurationLocked(config, r, false, false)) {
4242                    mStackSupervisor.resumeTopActivitiesLocked();
4243                }
4244            }
4245            Binder.restoreCallingIdentity(origId);
4246        }
4247    }
4248
4249    @Override
4250    public int getRequestedOrientation(IBinder token) {
4251        synchronized (this) {
4252            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4253            if (r == null) {
4254                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4255            }
4256            return mWindowManager.getAppOrientation(r.appToken);
4257        }
4258    }
4259
4260    /**
4261     * This is the internal entry point for handling Activity.finish().
4262     *
4263     * @param token The Binder token referencing the Activity we want to finish.
4264     * @param resultCode Result code, if any, from this Activity.
4265     * @param resultData Result data (Intent), if any, from this Activity.
4266     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4267     *            the root Activity in the task.
4268     *
4269     * @return Returns true if the activity successfully finished, or false if it is still running.
4270     */
4271    @Override
4272    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4273            boolean finishTask) {
4274        // Refuse possible leaked file descriptors
4275        if (resultData != null && resultData.hasFileDescriptors() == true) {
4276            throw new IllegalArgumentException("File descriptors passed in Intent");
4277        }
4278
4279        synchronized(this) {
4280            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4281            if (r == null) {
4282                return true;
4283            }
4284            // Keep track of the root activity of the task before we finish it
4285            TaskRecord tr = r.task;
4286            ActivityRecord rootR = tr.getRootActivity();
4287            // Do not allow task to finish in Lock Task mode.
4288            if (tr == mStackSupervisor.mLockTaskModeTask) {
4289                if (rootR == r) {
4290                    mStackSupervisor.showLockTaskToast();
4291                    return false;
4292                }
4293            }
4294            if (mController != null) {
4295                // Find the first activity that is not finishing.
4296                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4297                if (next != null) {
4298                    // ask watcher if this is allowed
4299                    boolean resumeOK = true;
4300                    try {
4301                        resumeOK = mController.activityResuming(next.packageName);
4302                    } catch (RemoteException e) {
4303                        mController = null;
4304                        Watchdog.getInstance().setActivityController(null);
4305                    }
4306
4307                    if (!resumeOK) {
4308                        return false;
4309                    }
4310                }
4311            }
4312            final long origId = Binder.clearCallingIdentity();
4313            try {
4314                boolean res;
4315                if (finishTask && r == rootR) {
4316                    // If requested, remove the task that is associated to this activity only if it
4317                    // was the root activity in the task. The result code and data is ignored
4318                    // because we don't support returning them across task boundaries.
4319                    res = removeTaskByIdLocked(tr.taskId, false);
4320                } else {
4321                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4322                            resultData, "app-request", true);
4323                }
4324                return res;
4325            } finally {
4326                Binder.restoreCallingIdentity(origId);
4327            }
4328        }
4329    }
4330
4331    @Override
4332    public final void finishHeavyWeightApp() {
4333        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4334                != PackageManager.PERMISSION_GRANTED) {
4335            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4336                    + Binder.getCallingPid()
4337                    + ", uid=" + Binder.getCallingUid()
4338                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4339            Slog.w(TAG, msg);
4340            throw new SecurityException(msg);
4341        }
4342
4343        synchronized(this) {
4344            if (mHeavyWeightProcess == null) {
4345                return;
4346            }
4347
4348            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4349                    mHeavyWeightProcess.activities);
4350            for (int i=0; i<activities.size(); i++) {
4351                ActivityRecord r = activities.get(i);
4352                if (!r.finishing) {
4353                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4354                            null, "finish-heavy", true);
4355                }
4356            }
4357
4358            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4359                    mHeavyWeightProcess.userId, 0));
4360            mHeavyWeightProcess = null;
4361        }
4362    }
4363
4364    @Override
4365    public void crashApplication(int uid, int initialPid, String packageName,
4366            String message) {
4367        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4368                != PackageManager.PERMISSION_GRANTED) {
4369            String msg = "Permission Denial: crashApplication() from pid="
4370                    + Binder.getCallingPid()
4371                    + ", uid=" + Binder.getCallingUid()
4372                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4373            Slog.w(TAG, msg);
4374            throw new SecurityException(msg);
4375        }
4376
4377        synchronized(this) {
4378            ProcessRecord proc = null;
4379
4380            // Figure out which process to kill.  We don't trust that initialPid
4381            // still has any relation to current pids, so must scan through the
4382            // list.
4383            synchronized (mPidsSelfLocked) {
4384                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4385                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4386                    if (p.uid != uid) {
4387                        continue;
4388                    }
4389                    if (p.pid == initialPid) {
4390                        proc = p;
4391                        break;
4392                    }
4393                    if (p.pkgList.containsKey(packageName)) {
4394                        proc = p;
4395                    }
4396                }
4397            }
4398
4399            if (proc == null) {
4400                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4401                        + " initialPid=" + initialPid
4402                        + " packageName=" + packageName);
4403                return;
4404            }
4405
4406            if (proc.thread != null) {
4407                if (proc.pid == Process.myPid()) {
4408                    Log.w(TAG, "crashApplication: trying to crash self!");
4409                    return;
4410                }
4411                long ident = Binder.clearCallingIdentity();
4412                try {
4413                    proc.thread.scheduleCrash(message);
4414                } catch (RemoteException e) {
4415                }
4416                Binder.restoreCallingIdentity(ident);
4417            }
4418        }
4419    }
4420
4421    @Override
4422    public final void finishSubActivity(IBinder token, String resultWho,
4423            int requestCode) {
4424        synchronized(this) {
4425            final long origId = Binder.clearCallingIdentity();
4426            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4427            if (r != null) {
4428                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4429            }
4430            Binder.restoreCallingIdentity(origId);
4431        }
4432    }
4433
4434    @Override
4435    public boolean finishActivityAffinity(IBinder token) {
4436        synchronized(this) {
4437            final long origId = Binder.clearCallingIdentity();
4438            try {
4439                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4440
4441                ActivityRecord rootR = r.task.getRootActivity();
4442                // Do not allow task to finish in Lock Task mode.
4443                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4444                    if (rootR == r) {
4445                        mStackSupervisor.showLockTaskToast();
4446                        return false;
4447                    }
4448                }
4449                boolean res = false;
4450                if (r != null) {
4451                    res = r.task.stack.finishActivityAffinityLocked(r);
4452                }
4453                return res;
4454            } finally {
4455                Binder.restoreCallingIdentity(origId);
4456            }
4457        }
4458    }
4459
4460    @Override
4461    public void finishVoiceTask(IVoiceInteractionSession session) {
4462        synchronized(this) {
4463            final long origId = Binder.clearCallingIdentity();
4464            try {
4465                mStackSupervisor.finishVoiceTask(session);
4466            } finally {
4467                Binder.restoreCallingIdentity(origId);
4468            }
4469        }
4470
4471    }
4472
4473    @Override
4474    public boolean releaseActivityInstance(IBinder token) {
4475        synchronized(this) {
4476            final long origId = Binder.clearCallingIdentity();
4477            try {
4478                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4479                if (r.task == null || r.task.stack == null) {
4480                    return false;
4481                }
4482                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4483            } finally {
4484                Binder.restoreCallingIdentity(origId);
4485            }
4486        }
4487    }
4488
4489    @Override
4490    public void releaseSomeActivities(IApplicationThread appInt) {
4491        synchronized(this) {
4492            final long origId = Binder.clearCallingIdentity();
4493            try {
4494                ProcessRecord app = getRecordForAppLocked(appInt);
4495                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4496            } finally {
4497                Binder.restoreCallingIdentity(origId);
4498            }
4499        }
4500    }
4501
4502    @Override
4503    public boolean willActivityBeVisible(IBinder token) {
4504        synchronized(this) {
4505            ActivityStack stack = ActivityRecord.getStackLocked(token);
4506            if (stack != null) {
4507                return stack.willActivityBeVisibleLocked(token);
4508            }
4509            return false;
4510        }
4511    }
4512
4513    @Override
4514    public void overridePendingTransition(IBinder token, String packageName,
4515            int enterAnim, int exitAnim) {
4516        synchronized(this) {
4517            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4518            if (self == null) {
4519                return;
4520            }
4521
4522            final long origId = Binder.clearCallingIdentity();
4523
4524            if (self.state == ActivityState.RESUMED
4525                    || self.state == ActivityState.PAUSING) {
4526                mWindowManager.overridePendingAppTransition(packageName,
4527                        enterAnim, exitAnim, null);
4528            }
4529
4530            Binder.restoreCallingIdentity(origId);
4531        }
4532    }
4533
4534    /**
4535     * Main function for removing an existing process from the activity manager
4536     * as a result of that process going away.  Clears out all connections
4537     * to the process.
4538     */
4539    private final void handleAppDiedLocked(ProcessRecord app,
4540            boolean restarting, boolean allowRestart) {
4541        int pid = app.pid;
4542        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4543        if (!kept && !restarting) {
4544            removeLruProcessLocked(app);
4545            if (pid > 0) {
4546                ProcessList.remove(pid);
4547            }
4548        }
4549
4550        if (mProfileProc == app) {
4551            clearProfilerLocked();
4552        }
4553
4554        // Remove this application's activities from active lists.
4555        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4556
4557        app.activities.clear();
4558
4559        if (app.instrumentationClass != null) {
4560            Slog.w(TAG, "Crash of app " + app.processName
4561                  + " running instrumentation " + app.instrumentationClass);
4562            Bundle info = new Bundle();
4563            info.putString("shortMsg", "Process crashed.");
4564            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4565        }
4566
4567        if (!restarting) {
4568            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4569                // If there was nothing to resume, and we are not already
4570                // restarting this process, but there is a visible activity that
4571                // is hosted by the process...  then make sure all visible
4572                // activities are running, taking care of restarting this
4573                // process.
4574                if (hasVisibleActivities) {
4575                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4576                }
4577            }
4578        }
4579    }
4580
4581    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4582        IBinder threadBinder = thread.asBinder();
4583        // Find the application record.
4584        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4585            ProcessRecord rec = mLruProcesses.get(i);
4586            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4587                return i;
4588            }
4589        }
4590        return -1;
4591    }
4592
4593    final ProcessRecord getRecordForAppLocked(
4594            IApplicationThread thread) {
4595        if (thread == null) {
4596            return null;
4597        }
4598
4599        int appIndex = getLRURecordIndexForAppLocked(thread);
4600        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4601    }
4602
4603    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4604        // If there are no longer any background processes running,
4605        // and the app that died was not running instrumentation,
4606        // then tell everyone we are now low on memory.
4607        boolean haveBg = false;
4608        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4609            ProcessRecord rec = mLruProcesses.get(i);
4610            if (rec.thread != null
4611                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4612                haveBg = true;
4613                break;
4614            }
4615        }
4616
4617        if (!haveBg) {
4618            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4619            if (doReport) {
4620                long now = SystemClock.uptimeMillis();
4621                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4622                    doReport = false;
4623                } else {
4624                    mLastMemUsageReportTime = now;
4625                }
4626            }
4627            final ArrayList<ProcessMemInfo> memInfos
4628                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4629            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4630            long now = SystemClock.uptimeMillis();
4631            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4632                ProcessRecord rec = mLruProcesses.get(i);
4633                if (rec == dyingProc || rec.thread == null) {
4634                    continue;
4635                }
4636                if (doReport) {
4637                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4638                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4639                }
4640                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4641                    // The low memory report is overriding any current
4642                    // state for a GC request.  Make sure to do
4643                    // heavy/important/visible/foreground processes first.
4644                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4645                        rec.lastRequestedGc = 0;
4646                    } else {
4647                        rec.lastRequestedGc = rec.lastLowMemory;
4648                    }
4649                    rec.reportLowMemory = true;
4650                    rec.lastLowMemory = now;
4651                    mProcessesToGc.remove(rec);
4652                    addProcessToGcListLocked(rec);
4653                }
4654            }
4655            if (doReport) {
4656                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4657                mHandler.sendMessage(msg);
4658            }
4659            scheduleAppGcsLocked();
4660        }
4661    }
4662
4663    final void appDiedLocked(ProcessRecord app) {
4664       appDiedLocked(app, app.pid, app.thread);
4665    }
4666
4667    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4668        // First check if this ProcessRecord is actually active for the pid.
4669        synchronized (mPidsSelfLocked) {
4670            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4671            if (curProc != app) {
4672                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4673                return;
4674            }
4675        }
4676
4677        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4678        synchronized (stats) {
4679            stats.noteProcessDiedLocked(app.info.uid, pid);
4680        }
4681
4682        Process.killProcessQuiet(pid);
4683        Process.killProcessGroup(app.info.uid, pid);
4684        app.killed = true;
4685
4686        // Clean up already done if the process has been re-started.
4687        if (app.pid == pid && app.thread != null &&
4688                app.thread.asBinder() == thread.asBinder()) {
4689            boolean doLowMem = app.instrumentationClass == null;
4690            boolean doOomAdj = doLowMem;
4691            if (!app.killedByAm) {
4692                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4693                        + ") has died");
4694                mAllowLowerMemLevel = true;
4695            } else {
4696                // Note that we always want to do oom adj to update our state with the
4697                // new number of procs.
4698                mAllowLowerMemLevel = false;
4699                doLowMem = false;
4700            }
4701            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4702            if (DEBUG_CLEANUP) Slog.v(
4703                TAG, "Dying app: " + app + ", pid: " + pid
4704                + ", thread: " + thread.asBinder());
4705            handleAppDiedLocked(app, false, true);
4706
4707            if (doOomAdj) {
4708                updateOomAdjLocked();
4709            }
4710            if (doLowMem) {
4711                doLowMemReportIfNeededLocked(app);
4712            }
4713        } else if (app.pid != pid) {
4714            // A new process has already been started.
4715            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4716                    + ") has died and restarted (pid " + app.pid + ").");
4717            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4718        } else if (DEBUG_PROCESSES) {
4719            Slog.d(TAG, "Received spurious death notification for thread "
4720                    + thread.asBinder());
4721        }
4722    }
4723
4724    /**
4725     * If a stack trace dump file is configured, dump process stack traces.
4726     * @param clearTraces causes the dump file to be erased prior to the new
4727     *    traces being written, if true; when false, the new traces will be
4728     *    appended to any existing file content.
4729     * @param firstPids of dalvik VM processes to dump stack traces for first
4730     * @param lastPids of dalvik VM processes to dump stack traces for last
4731     * @param nativeProcs optional list of native process names to dump stack crawls
4732     * @return file containing stack traces, or null if no dump file is configured
4733     */
4734    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4735            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4736        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4737        if (tracesPath == null || tracesPath.length() == 0) {
4738            return null;
4739        }
4740
4741        File tracesFile = new File(tracesPath);
4742        try {
4743            File tracesDir = tracesFile.getParentFile();
4744            if (!tracesDir.exists()) {
4745                tracesDir.mkdirs();
4746                if (!SELinux.restorecon(tracesDir)) {
4747                    return null;
4748                }
4749            }
4750            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4751
4752            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4753            tracesFile.createNewFile();
4754            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4755        } catch (IOException e) {
4756            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4757            return null;
4758        }
4759
4760        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4761        return tracesFile;
4762    }
4763
4764    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4765            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4766        // Use a FileObserver to detect when traces finish writing.
4767        // The order of traces is considered important to maintain for legibility.
4768        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4769            @Override
4770            public synchronized void onEvent(int event, String path) { notify(); }
4771        };
4772
4773        try {
4774            observer.startWatching();
4775
4776            // First collect all of the stacks of the most important pids.
4777            if (firstPids != null) {
4778                try {
4779                    int num = firstPids.size();
4780                    for (int i = 0; i < num; i++) {
4781                        synchronized (observer) {
4782                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4783                            observer.wait(200);  // Wait for write-close, give up after 200msec
4784                        }
4785                    }
4786                } catch (InterruptedException e) {
4787                    Slog.wtf(TAG, e);
4788                }
4789            }
4790
4791            // Next collect the stacks of the native pids
4792            if (nativeProcs != null) {
4793                int[] pids = Process.getPidsForCommands(nativeProcs);
4794                if (pids != null) {
4795                    for (int pid : pids) {
4796                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4797                    }
4798                }
4799            }
4800
4801            // Lastly, measure CPU usage.
4802            if (processCpuTracker != null) {
4803                processCpuTracker.init();
4804                System.gc();
4805                processCpuTracker.update();
4806                try {
4807                    synchronized (processCpuTracker) {
4808                        processCpuTracker.wait(500); // measure over 1/2 second.
4809                    }
4810                } catch (InterruptedException e) {
4811                }
4812                processCpuTracker.update();
4813
4814                // We'll take the stack crawls of just the top apps using CPU.
4815                final int N = processCpuTracker.countWorkingStats();
4816                int numProcs = 0;
4817                for (int i=0; i<N && numProcs<5; i++) {
4818                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4819                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4820                        numProcs++;
4821                        try {
4822                            synchronized (observer) {
4823                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4824                                observer.wait(200);  // Wait for write-close, give up after 200msec
4825                            }
4826                        } catch (InterruptedException e) {
4827                            Slog.wtf(TAG, e);
4828                        }
4829
4830                    }
4831                }
4832            }
4833        } finally {
4834            observer.stopWatching();
4835        }
4836    }
4837
4838    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4839        if (true || IS_USER_BUILD) {
4840            return;
4841        }
4842        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4843        if (tracesPath == null || tracesPath.length() == 0) {
4844            return;
4845        }
4846
4847        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4848        StrictMode.allowThreadDiskWrites();
4849        try {
4850            final File tracesFile = new File(tracesPath);
4851            final File tracesDir = tracesFile.getParentFile();
4852            final File tracesTmp = new File(tracesDir, "__tmp__");
4853            try {
4854                if (!tracesDir.exists()) {
4855                    tracesDir.mkdirs();
4856                    if (!SELinux.restorecon(tracesDir.getPath())) {
4857                        return;
4858                    }
4859                }
4860                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4861
4862                if (tracesFile.exists()) {
4863                    tracesTmp.delete();
4864                    tracesFile.renameTo(tracesTmp);
4865                }
4866                StringBuilder sb = new StringBuilder();
4867                Time tobj = new Time();
4868                tobj.set(System.currentTimeMillis());
4869                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4870                sb.append(": ");
4871                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4872                sb.append(" since ");
4873                sb.append(msg);
4874                FileOutputStream fos = new FileOutputStream(tracesFile);
4875                fos.write(sb.toString().getBytes());
4876                if (app == null) {
4877                    fos.write("\n*** No application process!".getBytes());
4878                }
4879                fos.close();
4880                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4881            } catch (IOException e) {
4882                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4883                return;
4884            }
4885
4886            if (app != null) {
4887                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4888                firstPids.add(app.pid);
4889                dumpStackTraces(tracesPath, firstPids, null, null, null);
4890            }
4891
4892            File lastTracesFile = null;
4893            File curTracesFile = null;
4894            for (int i=9; i>=0; i--) {
4895                String name = String.format(Locale.US, "slow%02d.txt", i);
4896                curTracesFile = new File(tracesDir, name);
4897                if (curTracesFile.exists()) {
4898                    if (lastTracesFile != null) {
4899                        curTracesFile.renameTo(lastTracesFile);
4900                    } else {
4901                        curTracesFile.delete();
4902                    }
4903                }
4904                lastTracesFile = curTracesFile;
4905            }
4906            tracesFile.renameTo(curTracesFile);
4907            if (tracesTmp.exists()) {
4908                tracesTmp.renameTo(tracesFile);
4909            }
4910        } finally {
4911            StrictMode.setThreadPolicy(oldPolicy);
4912        }
4913    }
4914
4915    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4916            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4917        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4918        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4919
4920        if (mController != null) {
4921            try {
4922                // 0 == continue, -1 = kill process immediately
4923                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4924                if (res < 0 && app.pid != MY_PID) {
4925                    app.kill("anr", true);
4926                }
4927            } catch (RemoteException e) {
4928                mController = null;
4929                Watchdog.getInstance().setActivityController(null);
4930            }
4931        }
4932
4933        long anrTime = SystemClock.uptimeMillis();
4934        if (MONITOR_CPU_USAGE) {
4935            updateCpuStatsNow();
4936        }
4937
4938        synchronized (this) {
4939            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4940            if (mShuttingDown) {
4941                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4942                return;
4943            } else if (app.notResponding) {
4944                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4945                return;
4946            } else if (app.crashing) {
4947                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4948                return;
4949            }
4950
4951            // In case we come through here for the same app before completing
4952            // this one, mark as anring now so we will bail out.
4953            app.notResponding = true;
4954
4955            // Log the ANR to the event log.
4956            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4957                    app.processName, app.info.flags, annotation);
4958
4959            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4960            firstPids.add(app.pid);
4961
4962            int parentPid = app.pid;
4963            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4964            if (parentPid != app.pid) firstPids.add(parentPid);
4965
4966            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4967
4968            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4969                ProcessRecord r = mLruProcesses.get(i);
4970                if (r != null && r.thread != null) {
4971                    int pid = r.pid;
4972                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4973                        if (r.persistent) {
4974                            firstPids.add(pid);
4975                        } else {
4976                            lastPids.put(pid, Boolean.TRUE);
4977                        }
4978                    }
4979                }
4980            }
4981        }
4982
4983        // Log the ANR to the main log.
4984        StringBuilder info = new StringBuilder();
4985        info.setLength(0);
4986        info.append("ANR in ").append(app.processName);
4987        if (activity != null && activity.shortComponentName != null) {
4988            info.append(" (").append(activity.shortComponentName).append(")");
4989        }
4990        info.append("\n");
4991        info.append("PID: ").append(app.pid).append("\n");
4992        if (annotation != null) {
4993            info.append("Reason: ").append(annotation).append("\n");
4994        }
4995        if (parent != null && parent != activity) {
4996            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4997        }
4998
4999        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5000
5001        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5002                NATIVE_STACKS_OF_INTEREST);
5003
5004        String cpuInfo = null;
5005        if (MONITOR_CPU_USAGE) {
5006            updateCpuStatsNow();
5007            synchronized (mProcessCpuTracker) {
5008                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5009            }
5010            info.append(processCpuTracker.printCurrentLoad());
5011            info.append(cpuInfo);
5012        }
5013
5014        info.append(processCpuTracker.printCurrentState(anrTime));
5015
5016        Slog.e(TAG, info.toString());
5017        if (tracesFile == null) {
5018            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5019            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5020        }
5021
5022        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5023                cpuInfo, tracesFile, null);
5024
5025        if (mController != null) {
5026            try {
5027                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5028                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5029                if (res != 0) {
5030                    if (res < 0 && app.pid != MY_PID) {
5031                        app.kill("anr", true);
5032                    } else {
5033                        synchronized (this) {
5034                            mServices.scheduleServiceTimeoutLocked(app);
5035                        }
5036                    }
5037                    return;
5038                }
5039            } catch (RemoteException e) {
5040                mController = null;
5041                Watchdog.getInstance().setActivityController(null);
5042            }
5043        }
5044
5045        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5046        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5047                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5048
5049        synchronized (this) {
5050            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5051                app.kill("bg anr", true);
5052                return;
5053            }
5054
5055            // Set the app's notResponding state, and look up the errorReportReceiver
5056            makeAppNotRespondingLocked(app,
5057                    activity != null ? activity.shortComponentName : null,
5058                    annotation != null ? "ANR " + annotation : "ANR",
5059                    info.toString());
5060
5061            // Bring up the infamous App Not Responding dialog
5062            Message msg = Message.obtain();
5063            HashMap<String, Object> map = new HashMap<String, Object>();
5064            msg.what = SHOW_NOT_RESPONDING_MSG;
5065            msg.obj = map;
5066            msg.arg1 = aboveSystem ? 1 : 0;
5067            map.put("app", app);
5068            if (activity != null) {
5069                map.put("activity", activity);
5070            }
5071
5072            mHandler.sendMessage(msg);
5073        }
5074    }
5075
5076    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5077        if (!mLaunchWarningShown) {
5078            mLaunchWarningShown = true;
5079            mHandler.post(new Runnable() {
5080                @Override
5081                public void run() {
5082                    synchronized (ActivityManagerService.this) {
5083                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5084                        d.show();
5085                        mHandler.postDelayed(new Runnable() {
5086                            @Override
5087                            public void run() {
5088                                synchronized (ActivityManagerService.this) {
5089                                    d.dismiss();
5090                                    mLaunchWarningShown = false;
5091                                }
5092                            }
5093                        }, 4000);
5094                    }
5095                }
5096            });
5097        }
5098    }
5099
5100    @Override
5101    public boolean clearApplicationUserData(final String packageName,
5102            final IPackageDataObserver observer, int userId) {
5103        enforceNotIsolatedCaller("clearApplicationUserData");
5104        int uid = Binder.getCallingUid();
5105        int pid = Binder.getCallingPid();
5106        userId = handleIncomingUser(pid, uid,
5107                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5108        long callingId = Binder.clearCallingIdentity();
5109        try {
5110            IPackageManager pm = AppGlobals.getPackageManager();
5111            int pkgUid = -1;
5112            synchronized(this) {
5113                try {
5114                    pkgUid = pm.getPackageUid(packageName, userId);
5115                } catch (RemoteException e) {
5116                }
5117                if (pkgUid == -1) {
5118                    Slog.w(TAG, "Invalid packageName: " + packageName);
5119                    if (observer != null) {
5120                        try {
5121                            observer.onRemoveCompleted(packageName, false);
5122                        } catch (RemoteException e) {
5123                            Slog.i(TAG, "Observer no longer exists.");
5124                        }
5125                    }
5126                    return false;
5127                }
5128                if (uid == pkgUid || checkComponentPermission(
5129                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5130                        pid, uid, -1, true)
5131                        == PackageManager.PERMISSION_GRANTED) {
5132                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5133                } else {
5134                    throw new SecurityException("PID " + pid + " does not have permission "
5135                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5136                                    + " of package " + packageName);
5137                }
5138
5139                // Remove all tasks match the cleared application package and user
5140                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5141                    final TaskRecord tr = mRecentTasks.get(i);
5142                    final String taskPackageName =
5143                            tr.getBaseIntent().getComponent().getPackageName();
5144                    if (tr.userId != userId) continue;
5145                    if (!taskPackageName.equals(packageName)) continue;
5146                    removeTaskByIdLocked(tr.taskId, false);
5147                }
5148            }
5149
5150            try {
5151                // Clear application user data
5152                pm.clearApplicationUserData(packageName, observer, userId);
5153
5154                synchronized(this) {
5155                    // Remove all permissions granted from/to this package
5156                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5157                }
5158
5159                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5160                        Uri.fromParts("package", packageName, null));
5161                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5162                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5163                        null, null, 0, null, null, null, false, false, userId);
5164            } catch (RemoteException e) {
5165            }
5166        } finally {
5167            Binder.restoreCallingIdentity(callingId);
5168        }
5169        return true;
5170    }
5171
5172    @Override
5173    public void killBackgroundProcesses(final String packageName, int userId) {
5174        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5175                != PackageManager.PERMISSION_GRANTED &&
5176                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5177                        != PackageManager.PERMISSION_GRANTED) {
5178            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5179                    + Binder.getCallingPid()
5180                    + ", uid=" + Binder.getCallingUid()
5181                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5182            Slog.w(TAG, msg);
5183            throw new SecurityException(msg);
5184        }
5185
5186        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5187                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5188        long callingId = Binder.clearCallingIdentity();
5189        try {
5190            IPackageManager pm = AppGlobals.getPackageManager();
5191            synchronized(this) {
5192                int appId = -1;
5193                try {
5194                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5195                } catch (RemoteException e) {
5196                }
5197                if (appId == -1) {
5198                    Slog.w(TAG, "Invalid packageName: " + packageName);
5199                    return;
5200                }
5201                killPackageProcessesLocked(packageName, appId, userId,
5202                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5203            }
5204        } finally {
5205            Binder.restoreCallingIdentity(callingId);
5206        }
5207    }
5208
5209    @Override
5210    public void killAllBackgroundProcesses() {
5211        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5212                != PackageManager.PERMISSION_GRANTED) {
5213            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5214                    + Binder.getCallingPid()
5215                    + ", uid=" + Binder.getCallingUid()
5216                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5217            Slog.w(TAG, msg);
5218            throw new SecurityException(msg);
5219        }
5220
5221        long callingId = Binder.clearCallingIdentity();
5222        try {
5223            synchronized(this) {
5224                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5225                final int NP = mProcessNames.getMap().size();
5226                for (int ip=0; ip<NP; ip++) {
5227                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5228                    final int NA = apps.size();
5229                    for (int ia=0; ia<NA; ia++) {
5230                        ProcessRecord app = apps.valueAt(ia);
5231                        if (app.persistent) {
5232                            // we don't kill persistent processes
5233                            continue;
5234                        }
5235                        if (app.removed) {
5236                            procs.add(app);
5237                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5238                            app.removed = true;
5239                            procs.add(app);
5240                        }
5241                    }
5242                }
5243
5244                int N = procs.size();
5245                for (int i=0; i<N; i++) {
5246                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5247                }
5248                mAllowLowerMemLevel = true;
5249                updateOomAdjLocked();
5250                doLowMemReportIfNeededLocked(null);
5251            }
5252        } finally {
5253            Binder.restoreCallingIdentity(callingId);
5254        }
5255    }
5256
5257    @Override
5258    public void forceStopPackage(final String packageName, int userId) {
5259        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5260                != PackageManager.PERMISSION_GRANTED) {
5261            String msg = "Permission Denial: forceStopPackage() from pid="
5262                    + Binder.getCallingPid()
5263                    + ", uid=" + Binder.getCallingUid()
5264                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5265            Slog.w(TAG, msg);
5266            throw new SecurityException(msg);
5267        }
5268        final int callingPid = Binder.getCallingPid();
5269        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5270                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5271        long callingId = Binder.clearCallingIdentity();
5272        try {
5273            IPackageManager pm = AppGlobals.getPackageManager();
5274            synchronized(this) {
5275                int[] users = userId == UserHandle.USER_ALL
5276                        ? getUsersLocked() : new int[] { userId };
5277                for (int user : users) {
5278                    int pkgUid = -1;
5279                    try {
5280                        pkgUid = pm.getPackageUid(packageName, user);
5281                    } catch (RemoteException e) {
5282                    }
5283                    if (pkgUid == -1) {
5284                        Slog.w(TAG, "Invalid packageName: " + packageName);
5285                        continue;
5286                    }
5287                    try {
5288                        pm.setPackageStoppedState(packageName, true, user);
5289                    } catch (RemoteException e) {
5290                    } catch (IllegalArgumentException e) {
5291                        Slog.w(TAG, "Failed trying to unstop package "
5292                                + packageName + ": " + e);
5293                    }
5294                    if (isUserRunningLocked(user, false)) {
5295                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5296                    }
5297                }
5298            }
5299        } finally {
5300            Binder.restoreCallingIdentity(callingId);
5301        }
5302    }
5303
5304    @Override
5305    public void addPackageDependency(String packageName) {
5306        synchronized (this) {
5307            int callingPid = Binder.getCallingPid();
5308            if (callingPid == Process.myPid()) {
5309                //  Yeah, um, no.
5310                Slog.w(TAG, "Can't addPackageDependency on system process");
5311                return;
5312            }
5313            ProcessRecord proc;
5314            synchronized (mPidsSelfLocked) {
5315                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5316            }
5317            if (proc != null) {
5318                if (proc.pkgDeps == null) {
5319                    proc.pkgDeps = new ArraySet<String>(1);
5320                }
5321                proc.pkgDeps.add(packageName);
5322            }
5323        }
5324    }
5325
5326    /*
5327     * The pkg name and app id have to be specified.
5328     */
5329    @Override
5330    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5331        if (pkg == null) {
5332            return;
5333        }
5334        // Make sure the uid is valid.
5335        if (appid < 0) {
5336            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5337            return;
5338        }
5339        int callerUid = Binder.getCallingUid();
5340        // Only the system server can kill an application
5341        if (callerUid == Process.SYSTEM_UID) {
5342            // Post an aysnc message to kill the application
5343            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5344            msg.arg1 = appid;
5345            msg.arg2 = 0;
5346            Bundle bundle = new Bundle();
5347            bundle.putString("pkg", pkg);
5348            bundle.putString("reason", reason);
5349            msg.obj = bundle;
5350            mHandler.sendMessage(msg);
5351        } else {
5352            throw new SecurityException(callerUid + " cannot kill pkg: " +
5353                    pkg);
5354        }
5355    }
5356
5357    @Override
5358    public void closeSystemDialogs(String reason) {
5359        enforceNotIsolatedCaller("closeSystemDialogs");
5360
5361        final int pid = Binder.getCallingPid();
5362        final int uid = Binder.getCallingUid();
5363        final long origId = Binder.clearCallingIdentity();
5364        try {
5365            synchronized (this) {
5366                // Only allow this from foreground processes, so that background
5367                // applications can't abuse it to prevent system UI from being shown.
5368                if (uid >= Process.FIRST_APPLICATION_UID) {
5369                    ProcessRecord proc;
5370                    synchronized (mPidsSelfLocked) {
5371                        proc = mPidsSelfLocked.get(pid);
5372                    }
5373                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5374                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5375                                + " from background process " + proc);
5376                        return;
5377                    }
5378                }
5379                closeSystemDialogsLocked(reason);
5380            }
5381        } finally {
5382            Binder.restoreCallingIdentity(origId);
5383        }
5384    }
5385
5386    void closeSystemDialogsLocked(String reason) {
5387        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5388        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5389                | Intent.FLAG_RECEIVER_FOREGROUND);
5390        if (reason != null) {
5391            intent.putExtra("reason", reason);
5392        }
5393        mWindowManager.closeSystemDialogs(reason);
5394
5395        mStackSupervisor.closeSystemDialogsLocked();
5396
5397        broadcastIntentLocked(null, null, intent, null,
5398                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5399                Process.SYSTEM_UID, UserHandle.USER_ALL);
5400    }
5401
5402    @Override
5403    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5404        enforceNotIsolatedCaller("getProcessMemoryInfo");
5405        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5406        for (int i=pids.length-1; i>=0; i--) {
5407            ProcessRecord proc;
5408            int oomAdj;
5409            synchronized (this) {
5410                synchronized (mPidsSelfLocked) {
5411                    proc = mPidsSelfLocked.get(pids[i]);
5412                    oomAdj = proc != null ? proc.setAdj : 0;
5413                }
5414            }
5415            infos[i] = new Debug.MemoryInfo();
5416            Debug.getMemoryInfo(pids[i], infos[i]);
5417            if (proc != null) {
5418                synchronized (this) {
5419                    if (proc.thread != null && proc.setAdj == oomAdj) {
5420                        // Record this for posterity if the process has been stable.
5421                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5422                                infos[i].getTotalUss(), false, proc.pkgList);
5423                    }
5424                }
5425            }
5426        }
5427        return infos;
5428    }
5429
5430    @Override
5431    public long[] getProcessPss(int[] pids) {
5432        enforceNotIsolatedCaller("getProcessPss");
5433        long[] pss = new long[pids.length];
5434        for (int i=pids.length-1; i>=0; i--) {
5435            ProcessRecord proc;
5436            int oomAdj;
5437            synchronized (this) {
5438                synchronized (mPidsSelfLocked) {
5439                    proc = mPidsSelfLocked.get(pids[i]);
5440                    oomAdj = proc != null ? proc.setAdj : 0;
5441                }
5442            }
5443            long[] tmpUss = new long[1];
5444            pss[i] = Debug.getPss(pids[i], tmpUss);
5445            if (proc != null) {
5446                synchronized (this) {
5447                    if (proc.thread != null && proc.setAdj == oomAdj) {
5448                        // Record this for posterity if the process has been stable.
5449                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5450                    }
5451                }
5452            }
5453        }
5454        return pss;
5455    }
5456
5457    @Override
5458    public void killApplicationProcess(String processName, int uid) {
5459        if (processName == null) {
5460            return;
5461        }
5462
5463        int callerUid = Binder.getCallingUid();
5464        // Only the system server can kill an application
5465        if (callerUid == Process.SYSTEM_UID) {
5466            synchronized (this) {
5467                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5468                if (app != null && app.thread != null) {
5469                    try {
5470                        app.thread.scheduleSuicide();
5471                    } catch (RemoteException e) {
5472                        // If the other end already died, then our work here is done.
5473                    }
5474                } else {
5475                    Slog.w(TAG, "Process/uid not found attempting kill of "
5476                            + processName + " / " + uid);
5477                }
5478            }
5479        } else {
5480            throw new SecurityException(callerUid + " cannot kill app process: " +
5481                    processName);
5482        }
5483    }
5484
5485    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5486        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5487                false, true, false, false, UserHandle.getUserId(uid), reason);
5488        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5489                Uri.fromParts("package", packageName, null));
5490        if (!mProcessesReady) {
5491            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5492                    | Intent.FLAG_RECEIVER_FOREGROUND);
5493        }
5494        intent.putExtra(Intent.EXTRA_UID, uid);
5495        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5496        broadcastIntentLocked(null, null, intent,
5497                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5498                false, false,
5499                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5500    }
5501
5502    private void forceStopUserLocked(int userId, String reason) {
5503        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5504        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5505        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5506                | Intent.FLAG_RECEIVER_FOREGROUND);
5507        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5508        broadcastIntentLocked(null, null, intent,
5509                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5510                false, false,
5511                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5512    }
5513
5514    private final boolean killPackageProcessesLocked(String packageName, int appId,
5515            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5516            boolean doit, boolean evenPersistent, String reason) {
5517        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5518
5519        // Remove all processes this package may have touched: all with the
5520        // same UID (except for the system or root user), and all whose name
5521        // matches the package name.
5522        final int NP = mProcessNames.getMap().size();
5523        for (int ip=0; ip<NP; ip++) {
5524            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5525            final int NA = apps.size();
5526            for (int ia=0; ia<NA; ia++) {
5527                ProcessRecord app = apps.valueAt(ia);
5528                if (app.persistent && !evenPersistent) {
5529                    // we don't kill persistent processes
5530                    continue;
5531                }
5532                if (app.removed) {
5533                    if (doit) {
5534                        procs.add(app);
5535                    }
5536                    continue;
5537                }
5538
5539                // Skip process if it doesn't meet our oom adj requirement.
5540                if (app.setAdj < minOomAdj) {
5541                    continue;
5542                }
5543
5544                // If no package is specified, we call all processes under the
5545                // give user id.
5546                if (packageName == null) {
5547                    if (app.userId != userId) {
5548                        continue;
5549                    }
5550                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5551                        continue;
5552                    }
5553                // Package has been specified, we want to hit all processes
5554                // that match it.  We need to qualify this by the processes
5555                // that are running under the specified app and user ID.
5556                } else {
5557                    final boolean isDep = app.pkgDeps != null
5558                            && app.pkgDeps.contains(packageName);
5559                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5560                        continue;
5561                    }
5562                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5563                        continue;
5564                    }
5565                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5566                        continue;
5567                    }
5568                }
5569
5570                // Process has passed all conditions, kill it!
5571                if (!doit) {
5572                    return true;
5573                }
5574                app.removed = true;
5575                procs.add(app);
5576            }
5577        }
5578
5579        int N = procs.size();
5580        for (int i=0; i<N; i++) {
5581            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5582        }
5583        updateOomAdjLocked();
5584        return N > 0;
5585    }
5586
5587    private final boolean forceStopPackageLocked(String name, int appId,
5588            boolean callerWillRestart, boolean purgeCache, boolean doit,
5589            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5590        int i;
5591        int N;
5592
5593        if (userId == UserHandle.USER_ALL && name == null) {
5594            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5595        }
5596
5597        if (appId < 0 && name != null) {
5598            try {
5599                appId = UserHandle.getAppId(
5600                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5601            } catch (RemoteException e) {
5602            }
5603        }
5604
5605        if (doit) {
5606            if (name != null) {
5607                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5608                        + " user=" + userId + ": " + reason);
5609            } else {
5610                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5611            }
5612
5613            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5614            for (int ip=pmap.size()-1; ip>=0; ip--) {
5615                SparseArray<Long> ba = pmap.valueAt(ip);
5616                for (i=ba.size()-1; i>=0; i--) {
5617                    boolean remove = false;
5618                    final int entUid = ba.keyAt(i);
5619                    if (name != null) {
5620                        if (userId == UserHandle.USER_ALL) {
5621                            if (UserHandle.getAppId(entUid) == appId) {
5622                                remove = true;
5623                            }
5624                        } else {
5625                            if (entUid == UserHandle.getUid(userId, appId)) {
5626                                remove = true;
5627                            }
5628                        }
5629                    } else if (UserHandle.getUserId(entUid) == userId) {
5630                        remove = true;
5631                    }
5632                    if (remove) {
5633                        ba.removeAt(i);
5634                    }
5635                }
5636                if (ba.size() == 0) {
5637                    pmap.removeAt(ip);
5638                }
5639            }
5640        }
5641
5642        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5643                -100, callerWillRestart, true, doit, evenPersistent,
5644                name == null ? ("stop user " + userId) : ("stop " + name));
5645
5646        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5647            if (!doit) {
5648                return true;
5649            }
5650            didSomething = true;
5651        }
5652
5653        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5654            if (!doit) {
5655                return true;
5656            }
5657            didSomething = true;
5658        }
5659
5660        if (name == null) {
5661            // Remove all sticky broadcasts from this user.
5662            mStickyBroadcasts.remove(userId);
5663        }
5664
5665        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5666        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5667                userId, providers)) {
5668            if (!doit) {
5669                return true;
5670            }
5671            didSomething = true;
5672        }
5673        N = providers.size();
5674        for (i=0; i<N; i++) {
5675            removeDyingProviderLocked(null, providers.get(i), true);
5676        }
5677
5678        // Remove transient permissions granted from/to this package/user
5679        removeUriPermissionsForPackageLocked(name, userId, false);
5680
5681        if (name == null || uninstalling) {
5682            // Remove pending intents.  For now we only do this when force
5683            // stopping users, because we have some problems when doing this
5684            // for packages -- app widgets are not currently cleaned up for
5685            // such packages, so they can be left with bad pending intents.
5686            if (mIntentSenderRecords.size() > 0) {
5687                Iterator<WeakReference<PendingIntentRecord>> it
5688                        = mIntentSenderRecords.values().iterator();
5689                while (it.hasNext()) {
5690                    WeakReference<PendingIntentRecord> wpir = it.next();
5691                    if (wpir == null) {
5692                        it.remove();
5693                        continue;
5694                    }
5695                    PendingIntentRecord pir = wpir.get();
5696                    if (pir == null) {
5697                        it.remove();
5698                        continue;
5699                    }
5700                    if (name == null) {
5701                        // Stopping user, remove all objects for the user.
5702                        if (pir.key.userId != userId) {
5703                            // Not the same user, skip it.
5704                            continue;
5705                        }
5706                    } else {
5707                        if (UserHandle.getAppId(pir.uid) != appId) {
5708                            // Different app id, skip it.
5709                            continue;
5710                        }
5711                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5712                            // Different user, skip it.
5713                            continue;
5714                        }
5715                        if (!pir.key.packageName.equals(name)) {
5716                            // Different package, skip it.
5717                            continue;
5718                        }
5719                    }
5720                    if (!doit) {
5721                        return true;
5722                    }
5723                    didSomething = true;
5724                    it.remove();
5725                    pir.canceled = true;
5726                    if (pir.key.activity != null) {
5727                        pir.key.activity.pendingResults.remove(pir.ref);
5728                    }
5729                }
5730            }
5731        }
5732
5733        if (doit) {
5734            if (purgeCache && name != null) {
5735                AttributeCache ac = AttributeCache.instance();
5736                if (ac != null) {
5737                    ac.removePackage(name);
5738                }
5739            }
5740            if (mBooted) {
5741                mStackSupervisor.resumeTopActivitiesLocked();
5742                mStackSupervisor.scheduleIdleLocked();
5743            }
5744        }
5745
5746        return didSomething;
5747    }
5748
5749    private final boolean removeProcessLocked(ProcessRecord app,
5750            boolean callerWillRestart, boolean allowRestart, String reason) {
5751        final String name = app.processName;
5752        final int uid = app.uid;
5753        if (DEBUG_PROCESSES) Slog.d(
5754            TAG, "Force removing proc " + app.toShortString() + " (" + name
5755            + "/" + uid + ")");
5756
5757        mProcessNames.remove(name, uid);
5758        mIsolatedProcesses.remove(app.uid);
5759        if (mHeavyWeightProcess == app) {
5760            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5761                    mHeavyWeightProcess.userId, 0));
5762            mHeavyWeightProcess = null;
5763        }
5764        boolean needRestart = false;
5765        if (app.pid > 0 && app.pid != MY_PID) {
5766            int pid = app.pid;
5767            synchronized (mPidsSelfLocked) {
5768                mPidsSelfLocked.remove(pid);
5769                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5770            }
5771            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5772            if (app.isolated) {
5773                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5774            }
5775            app.kill(reason, true);
5776            handleAppDiedLocked(app, true, allowRestart);
5777            removeLruProcessLocked(app);
5778
5779            if (app.persistent && !app.isolated) {
5780                if (!callerWillRestart) {
5781                    addAppLocked(app.info, false, null /* ABI override */);
5782                } else {
5783                    needRestart = true;
5784                }
5785            }
5786        } else {
5787            mRemovedProcesses.add(app);
5788        }
5789
5790        return needRestart;
5791    }
5792
5793    private final void processStartTimedOutLocked(ProcessRecord app) {
5794        final int pid = app.pid;
5795        boolean gone = false;
5796        synchronized (mPidsSelfLocked) {
5797            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5798            if (knownApp != null && knownApp.thread == null) {
5799                mPidsSelfLocked.remove(pid);
5800                gone = true;
5801            }
5802        }
5803
5804        if (gone) {
5805            Slog.w(TAG, "Process " + app + " failed to attach");
5806            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5807                    pid, app.uid, app.processName);
5808            mProcessNames.remove(app.processName, app.uid);
5809            mIsolatedProcesses.remove(app.uid);
5810            if (mHeavyWeightProcess == app) {
5811                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5812                        mHeavyWeightProcess.userId, 0));
5813                mHeavyWeightProcess = null;
5814            }
5815            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5816            if (app.isolated) {
5817                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5818            }
5819            // Take care of any launching providers waiting for this process.
5820            checkAppInLaunchingProvidersLocked(app, true);
5821            // Take care of any services that are waiting for the process.
5822            mServices.processStartTimedOutLocked(app);
5823            app.kill("start timeout", true);
5824            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5825                Slog.w(TAG, "Unattached app died before backup, skipping");
5826                try {
5827                    IBackupManager bm = IBackupManager.Stub.asInterface(
5828                            ServiceManager.getService(Context.BACKUP_SERVICE));
5829                    bm.agentDisconnected(app.info.packageName);
5830                } catch (RemoteException e) {
5831                    // Can't happen; the backup manager is local
5832                }
5833            }
5834            if (isPendingBroadcastProcessLocked(pid)) {
5835                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5836                skipPendingBroadcastLocked(pid);
5837            }
5838        } else {
5839            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5840        }
5841    }
5842
5843    private final boolean attachApplicationLocked(IApplicationThread thread,
5844            int pid) {
5845
5846        // Find the application record that is being attached...  either via
5847        // the pid if we are running in multiple processes, or just pull the
5848        // next app record if we are emulating process with anonymous threads.
5849        ProcessRecord app;
5850        if (pid != MY_PID && pid >= 0) {
5851            synchronized (mPidsSelfLocked) {
5852                app = mPidsSelfLocked.get(pid);
5853            }
5854        } else {
5855            app = null;
5856        }
5857
5858        if (app == null) {
5859            Slog.w(TAG, "No pending application record for pid " + pid
5860                    + " (IApplicationThread " + thread + "); dropping process");
5861            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5862            if (pid > 0 && pid != MY_PID) {
5863                Process.killProcessQuiet(pid);
5864                //TODO: Process.killProcessGroup(app.info.uid, pid);
5865            } else {
5866                try {
5867                    thread.scheduleExit();
5868                } catch (Exception e) {
5869                    // Ignore exceptions.
5870                }
5871            }
5872            return false;
5873        }
5874
5875        // If this application record is still attached to a previous
5876        // process, clean it up now.
5877        if (app.thread != null) {
5878            handleAppDiedLocked(app, true, true);
5879        }
5880
5881        // Tell the process all about itself.
5882
5883        if (localLOGV) Slog.v(
5884                TAG, "Binding process pid " + pid + " to record " + app);
5885
5886        final String processName = app.processName;
5887        try {
5888            AppDeathRecipient adr = new AppDeathRecipient(
5889                    app, pid, thread);
5890            thread.asBinder().linkToDeath(adr, 0);
5891            app.deathRecipient = adr;
5892        } catch (RemoteException e) {
5893            app.resetPackageList(mProcessStats);
5894            startProcessLocked(app, "link fail", processName);
5895            return false;
5896        }
5897
5898        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5899
5900        app.makeActive(thread, mProcessStats);
5901        app.curAdj = app.setAdj = -100;
5902        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5903        app.forcingToForeground = null;
5904        updateProcessForegroundLocked(app, false, false);
5905        app.hasShownUi = false;
5906        app.debugging = false;
5907        app.cached = false;
5908
5909        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5910
5911        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5912        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5913
5914        if (!normalMode) {
5915            Slog.i(TAG, "Launching preboot mode app: " + app);
5916        }
5917
5918        if (localLOGV) Slog.v(
5919            TAG, "New app record " + app
5920            + " thread=" + thread.asBinder() + " pid=" + pid);
5921        try {
5922            int testMode = IApplicationThread.DEBUG_OFF;
5923            if (mDebugApp != null && mDebugApp.equals(processName)) {
5924                testMode = mWaitForDebugger
5925                    ? IApplicationThread.DEBUG_WAIT
5926                    : IApplicationThread.DEBUG_ON;
5927                app.debugging = true;
5928                if (mDebugTransient) {
5929                    mDebugApp = mOrigDebugApp;
5930                    mWaitForDebugger = mOrigWaitForDebugger;
5931                }
5932            }
5933            String profileFile = app.instrumentationProfileFile;
5934            ParcelFileDescriptor profileFd = null;
5935            int samplingInterval = 0;
5936            boolean profileAutoStop = false;
5937            if (mProfileApp != null && mProfileApp.equals(processName)) {
5938                mProfileProc = app;
5939                profileFile = mProfileFile;
5940                profileFd = mProfileFd;
5941                samplingInterval = mSamplingInterval;
5942                profileAutoStop = mAutoStopProfiler;
5943            }
5944            boolean enableOpenGlTrace = false;
5945            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5946                enableOpenGlTrace = true;
5947                mOpenGlTraceApp = null;
5948            }
5949
5950            // If the app is being launched for restore or full backup, set it up specially
5951            boolean isRestrictedBackupMode = false;
5952            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5953                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5954                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5955                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5956            }
5957
5958            ensurePackageDexOpt(app.instrumentationInfo != null
5959                    ? app.instrumentationInfo.packageName
5960                    : app.info.packageName);
5961            if (app.instrumentationClass != null) {
5962                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5963            }
5964            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5965                    + processName + " with config " + mConfiguration);
5966            ApplicationInfo appInfo = app.instrumentationInfo != null
5967                    ? app.instrumentationInfo : app.info;
5968            app.compat = compatibilityInfoForPackageLocked(appInfo);
5969            if (profileFd != null) {
5970                profileFd = profileFd.dup();
5971            }
5972            ProfilerInfo profilerInfo = profileFile == null ? null
5973                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5974            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5975                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5976                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5977                    isRestrictedBackupMode || !normalMode, app.persistent,
5978                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5979                    mCoreSettingsObserver.getCoreSettingsLocked());
5980            updateLruProcessLocked(app, false, null);
5981            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5982        } catch (Exception e) {
5983            // todo: Yikes!  What should we do?  For now we will try to
5984            // start another process, but that could easily get us in
5985            // an infinite loop of restarting processes...
5986            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5987
5988            app.resetPackageList(mProcessStats);
5989            app.unlinkDeathRecipient();
5990            startProcessLocked(app, "bind fail", processName);
5991            return false;
5992        }
5993
5994        // Remove this record from the list of starting applications.
5995        mPersistentStartingProcesses.remove(app);
5996        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5997                "Attach application locked removing on hold: " + app);
5998        mProcessesOnHold.remove(app);
5999
6000        boolean badApp = false;
6001        boolean didSomething = false;
6002
6003        // See if the top visible activity is waiting to run in this process...
6004        if (normalMode) {
6005            try {
6006                if (mStackSupervisor.attachApplicationLocked(app)) {
6007                    didSomething = true;
6008                }
6009            } catch (Exception e) {
6010                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6011                badApp = true;
6012            }
6013        }
6014
6015        // Find any services that should be running in this process...
6016        if (!badApp) {
6017            try {
6018                didSomething |= mServices.attachApplicationLocked(app, processName);
6019            } catch (Exception e) {
6020                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6021                badApp = true;
6022            }
6023        }
6024
6025        // Check if a next-broadcast receiver is in this process...
6026        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6027            try {
6028                didSomething |= sendPendingBroadcastsLocked(app);
6029            } catch (Exception e) {
6030                // If the app died trying to launch the receiver we declare it 'bad'
6031                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6032                badApp = true;
6033            }
6034        }
6035
6036        // Check whether the next backup agent is in this process...
6037        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6038            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6039            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6040            try {
6041                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6042                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6043                        mBackupTarget.backupMode);
6044            } catch (Exception e) {
6045                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6046                badApp = true;
6047            }
6048        }
6049
6050        if (badApp) {
6051            app.kill("error during init", true);
6052            handleAppDiedLocked(app, false, true);
6053            return false;
6054        }
6055
6056        if (!didSomething) {
6057            updateOomAdjLocked();
6058        }
6059
6060        return true;
6061    }
6062
6063    @Override
6064    public final void attachApplication(IApplicationThread thread) {
6065        synchronized (this) {
6066            int callingPid = Binder.getCallingPid();
6067            final long origId = Binder.clearCallingIdentity();
6068            attachApplicationLocked(thread, callingPid);
6069            Binder.restoreCallingIdentity(origId);
6070        }
6071    }
6072
6073    @Override
6074    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6075        final long origId = Binder.clearCallingIdentity();
6076        synchronized (this) {
6077            ActivityStack stack = ActivityRecord.getStackLocked(token);
6078            if (stack != null) {
6079                ActivityRecord r =
6080                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6081                if (stopProfiling) {
6082                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6083                        try {
6084                            mProfileFd.close();
6085                        } catch (IOException e) {
6086                        }
6087                        clearProfilerLocked();
6088                    }
6089                }
6090            }
6091        }
6092        Binder.restoreCallingIdentity(origId);
6093    }
6094
6095    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6096        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6097                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6098    }
6099
6100    void enableScreenAfterBoot() {
6101        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6102                SystemClock.uptimeMillis());
6103        mWindowManager.enableScreenAfterBoot();
6104
6105        synchronized (this) {
6106            updateEventDispatchingLocked();
6107        }
6108    }
6109
6110    @Override
6111    public void showBootMessage(final CharSequence msg, final boolean always) {
6112        enforceNotIsolatedCaller("showBootMessage");
6113        mWindowManager.showBootMessage(msg, always);
6114    }
6115
6116    @Override
6117    public void keyguardWaitingForActivityDrawn() {
6118        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6119        final long token = Binder.clearCallingIdentity();
6120        try {
6121            synchronized (this) {
6122                if (DEBUG_LOCKSCREEN) logLockScreen("");
6123                mWindowManager.keyguardWaitingForActivityDrawn();
6124                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6125                    mLockScreenShown = LOCK_SCREEN_LEAVING;
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, boolean killProcess) {
8291        mRecentTasks.remove(tr);
8292        tr.removedFromRecents(mTaskPersister);
8293        ComponentName component = tr.getBaseIntent().getComponent();
8294        if (component == null) {
8295            Slog.w(TAG, "No component for base intent of task: " + tr);
8296            return;
8297        }
8298
8299        if (!killProcess) {
8300            return;
8301        }
8302
8303        // Determine if the process(es) for this task should be killed.
8304        final String pkg = component.getPackageName();
8305        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8306        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8307        for (int i = 0; i < pmap.size(); i++) {
8308
8309            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8310            for (int j = 0; j < uids.size(); j++) {
8311                ProcessRecord proc = uids.valueAt(j);
8312                if (proc.userId != tr.userId) {
8313                    // Don't kill process for a different user.
8314                    continue;
8315                }
8316                if (proc == mHomeProcess) {
8317                    // Don't kill the home process along with tasks from the same package.
8318                    continue;
8319                }
8320                if (!proc.pkgList.containsKey(pkg)) {
8321                    // Don't kill process that is not associated with this task.
8322                    continue;
8323                }
8324
8325                for (int k = 0; k < proc.activities.size(); k++) {
8326                    TaskRecord otherTask = proc.activities.get(k).task;
8327                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8328                        // Don't kill process(es) that has an activity in a different task that is
8329                        // also in recents.
8330                        return;
8331                    }
8332                }
8333
8334                // Add process to kill list.
8335                procsToKill.add(proc);
8336            }
8337        }
8338
8339        // Find any running services associated with this app and stop if needed.
8340        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8341
8342        // Kill the running processes.
8343        for (int i = 0; i < procsToKill.size(); i++) {
8344            ProcessRecord pr = procsToKill.get(i);
8345            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8346                pr.kill("remove task", true);
8347            } else {
8348                pr.waitingToKill = "remove task";
8349            }
8350        }
8351    }
8352
8353    /**
8354     * Removes the task with the specified task id.
8355     *
8356     * @param taskId Identifier of the task to be removed.
8357     * @param killProcess Kill any process associated with the task if possible.
8358     * @return Returns true if the given task was found and removed.
8359     */
8360    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8361        TaskRecord tr = recentTaskForIdLocked(taskId);
8362        if (tr != null) {
8363            tr.removeTaskActivitiesLocked();
8364            cleanUpRemovedTaskLocked(tr, killProcess);
8365            if (tr.isPersistable) {
8366                notifyTaskPersisterLocked(null, true);
8367            }
8368            return true;
8369        }
8370        return false;
8371    }
8372
8373    @Override
8374    public boolean removeTask(int taskId) {
8375        synchronized (this) {
8376            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8377                    "removeTask()");
8378            long ident = Binder.clearCallingIdentity();
8379            try {
8380                return removeTaskByIdLocked(taskId, true);
8381            } finally {
8382                Binder.restoreCallingIdentity(ident);
8383            }
8384        }
8385    }
8386
8387    /**
8388     * TODO: Add mController hook
8389     */
8390    @Override
8391    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8392        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8393                "moveTaskToFront()");
8394
8395        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8396        synchronized(this) {
8397            moveTaskToFrontLocked(taskId, flags, options);
8398        }
8399    }
8400
8401    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8402        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8403                Binder.getCallingUid(), -1, -1, "Task to front")) {
8404            ActivityOptions.abort(options);
8405            return;
8406        }
8407        final long origId = Binder.clearCallingIdentity();
8408        try {
8409            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8410            if (task == null) {
8411                return;
8412            }
8413            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8414                mStackSupervisor.showLockTaskToast();
8415                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8416                return;
8417            }
8418            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8419            if (prev != null && prev.isRecentsActivity()) {
8420                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8421            }
8422            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8423        } finally {
8424            Binder.restoreCallingIdentity(origId);
8425        }
8426        ActivityOptions.abort(options);
8427    }
8428
8429    @Override
8430    public void moveTaskToBack(int taskId) {
8431        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8432                "moveTaskToBack()");
8433
8434        synchronized(this) {
8435            TaskRecord tr = recentTaskForIdLocked(taskId);
8436            if (tr != null) {
8437                if (tr == mStackSupervisor.mLockTaskModeTask) {
8438                    mStackSupervisor.showLockTaskToast();
8439                    return;
8440                }
8441                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8442                ActivityStack stack = tr.stack;
8443                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8444                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8445                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8446                        return;
8447                    }
8448                }
8449                final long origId = Binder.clearCallingIdentity();
8450                try {
8451                    stack.moveTaskToBackLocked(taskId, null);
8452                } finally {
8453                    Binder.restoreCallingIdentity(origId);
8454                }
8455            }
8456        }
8457    }
8458
8459    /**
8460     * Moves an activity, and all of the other activities within the same task, to the bottom
8461     * of the history stack.  The activity's order within the task is unchanged.
8462     *
8463     * @param token A reference to the activity we wish to move
8464     * @param nonRoot If false then this only works if the activity is the root
8465     *                of a task; if true it will work for any activity in a task.
8466     * @return Returns true if the move completed, false if not.
8467     */
8468    @Override
8469    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8470        enforceNotIsolatedCaller("moveActivityTaskToBack");
8471        synchronized(this) {
8472            final long origId = Binder.clearCallingIdentity();
8473            try {
8474                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8475                if (taskId >= 0) {
8476                    if ((mStackSupervisor.mLockTaskModeTask != null)
8477                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8478                        mStackSupervisor.showLockTaskToast();
8479                        return false;
8480                    }
8481                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8482                }
8483            } finally {
8484                Binder.restoreCallingIdentity(origId);
8485            }
8486        }
8487        return false;
8488    }
8489
8490    @Override
8491    public void moveTaskBackwards(int task) {
8492        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8493                "moveTaskBackwards()");
8494
8495        synchronized(this) {
8496            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8497                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8498                return;
8499            }
8500            final long origId = Binder.clearCallingIdentity();
8501            moveTaskBackwardsLocked(task);
8502            Binder.restoreCallingIdentity(origId);
8503        }
8504    }
8505
8506    private final void moveTaskBackwardsLocked(int task) {
8507        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8508    }
8509
8510    @Override
8511    public IBinder getHomeActivityToken() throws RemoteException {
8512        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8513                "getHomeActivityToken()");
8514        synchronized (this) {
8515            return mStackSupervisor.getHomeActivityToken();
8516        }
8517    }
8518
8519    @Override
8520    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8521            IActivityContainerCallback callback) throws RemoteException {
8522        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8523                "createActivityContainer()");
8524        synchronized (this) {
8525            if (parentActivityToken == null) {
8526                throw new IllegalArgumentException("parent token must not be null");
8527            }
8528            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8529            if (r == null) {
8530                return null;
8531            }
8532            if (callback == null) {
8533                throw new IllegalArgumentException("callback must not be null");
8534            }
8535            return mStackSupervisor.createActivityContainer(r, callback);
8536        }
8537    }
8538
8539    @Override
8540    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8541        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8542                "deleteActivityContainer()");
8543        synchronized (this) {
8544            mStackSupervisor.deleteActivityContainer(container);
8545        }
8546    }
8547
8548    @Override
8549    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8550            throws RemoteException {
8551        synchronized (this) {
8552            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8553            if (stack != null) {
8554                return stack.mActivityContainer;
8555            }
8556            return null;
8557        }
8558    }
8559
8560    @Override
8561    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8562        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8563                "moveTaskToStack()");
8564        if (stackId == HOME_STACK_ID) {
8565            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8566                    new RuntimeException("here").fillInStackTrace());
8567        }
8568        synchronized (this) {
8569            long ident = Binder.clearCallingIdentity();
8570            try {
8571                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8572                        + stackId + " toTop=" + toTop);
8573                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8574            } finally {
8575                Binder.restoreCallingIdentity(ident);
8576            }
8577        }
8578    }
8579
8580    @Override
8581    public void resizeStack(int stackBoxId, Rect bounds) {
8582        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8583                "resizeStackBox()");
8584        long ident = Binder.clearCallingIdentity();
8585        try {
8586            mWindowManager.resizeStack(stackBoxId, bounds);
8587        } finally {
8588            Binder.restoreCallingIdentity(ident);
8589        }
8590    }
8591
8592    @Override
8593    public List<StackInfo> getAllStackInfos() {
8594        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8595                "getAllStackInfos()");
8596        long ident = Binder.clearCallingIdentity();
8597        try {
8598            synchronized (this) {
8599                return mStackSupervisor.getAllStackInfosLocked();
8600            }
8601        } finally {
8602            Binder.restoreCallingIdentity(ident);
8603        }
8604    }
8605
8606    @Override
8607    public StackInfo getStackInfo(int stackId) {
8608        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8609                "getStackInfo()");
8610        long ident = Binder.clearCallingIdentity();
8611        try {
8612            synchronized (this) {
8613                return mStackSupervisor.getStackInfoLocked(stackId);
8614            }
8615        } finally {
8616            Binder.restoreCallingIdentity(ident);
8617        }
8618    }
8619
8620    @Override
8621    public boolean isInHomeStack(int taskId) {
8622        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8623                "getStackInfo()");
8624        long ident = Binder.clearCallingIdentity();
8625        try {
8626            synchronized (this) {
8627                TaskRecord tr = recentTaskForIdLocked(taskId);
8628                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8629            }
8630        } finally {
8631            Binder.restoreCallingIdentity(ident);
8632        }
8633    }
8634
8635    @Override
8636    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8637        synchronized(this) {
8638            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8639        }
8640    }
8641
8642    private boolean isLockTaskAuthorized(String pkg) {
8643        final DevicePolicyManager dpm = (DevicePolicyManager)
8644                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8645        try {
8646            int uid = mContext.getPackageManager().getPackageUid(pkg,
8647                    Binder.getCallingUserHandle().getIdentifier());
8648            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8649        } catch (NameNotFoundException e) {
8650            return false;
8651        }
8652    }
8653
8654    void startLockTaskMode(TaskRecord task) {
8655        final String pkg;
8656        synchronized (this) {
8657            pkg = task.intent.getComponent().getPackageName();
8658        }
8659        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8660        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8661            final TaskRecord taskRecord = task;
8662            mHandler.post(new Runnable() {
8663                @Override
8664                public void run() {
8665                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8666                }
8667            });
8668            return;
8669        }
8670        long ident = Binder.clearCallingIdentity();
8671        try {
8672            synchronized (this) {
8673                // Since we lost lock on task, make sure it is still there.
8674                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8675                if (task != null) {
8676                    if (!isSystemInitiated
8677                            && ((mStackSupervisor.getFocusedStack() == null)
8678                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8679                        throw new IllegalArgumentException("Invalid task, not in foreground");
8680                    }
8681                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8682                }
8683            }
8684        } finally {
8685            Binder.restoreCallingIdentity(ident);
8686        }
8687    }
8688
8689    @Override
8690    public void startLockTaskMode(int taskId) {
8691        final TaskRecord task;
8692        long ident = Binder.clearCallingIdentity();
8693        try {
8694            synchronized (this) {
8695                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8696            }
8697        } finally {
8698            Binder.restoreCallingIdentity(ident);
8699        }
8700        if (task != null) {
8701            startLockTaskMode(task);
8702        }
8703    }
8704
8705    @Override
8706    public void startLockTaskMode(IBinder token) {
8707        final TaskRecord task;
8708        long ident = Binder.clearCallingIdentity();
8709        try {
8710            synchronized (this) {
8711                final ActivityRecord r = ActivityRecord.forToken(token);
8712                if (r == null) {
8713                    return;
8714                }
8715                task = r.task;
8716            }
8717        } finally {
8718            Binder.restoreCallingIdentity(ident);
8719        }
8720        if (task != null) {
8721            startLockTaskMode(task);
8722        }
8723    }
8724
8725    @Override
8726    public void startLockTaskModeOnCurrent() throws RemoteException {
8727        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8728                "startLockTaskModeOnCurrent");
8729        ActivityRecord r = null;
8730        synchronized (this) {
8731            r = mStackSupervisor.topRunningActivityLocked();
8732        }
8733        startLockTaskMode(r.task);
8734    }
8735
8736    @Override
8737    public void stopLockTaskMode() {
8738        // Verify that the user matches the package of the intent for the TaskRecord
8739        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8740        // and stopLockTaskMode.
8741        final int callingUid = Binder.getCallingUid();
8742        if (callingUid != Process.SYSTEM_UID) {
8743            try {
8744                String pkg =
8745                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8746                int uid = mContext.getPackageManager().getPackageUid(pkg,
8747                        Binder.getCallingUserHandle().getIdentifier());
8748                if (uid != callingUid) {
8749                    throw new SecurityException("Invalid uid, expected " + uid);
8750                }
8751            } catch (NameNotFoundException e) {
8752                Log.d(TAG, "stopLockTaskMode " + e);
8753                return;
8754            }
8755        }
8756        long ident = Binder.clearCallingIdentity();
8757        try {
8758            Log.d(TAG, "stopLockTaskMode");
8759            // Stop lock task
8760            synchronized (this) {
8761                mStackSupervisor.setLockTaskModeLocked(null, false);
8762            }
8763        } finally {
8764            Binder.restoreCallingIdentity(ident);
8765        }
8766    }
8767
8768    @Override
8769    public void stopLockTaskModeOnCurrent() throws RemoteException {
8770        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8771                "stopLockTaskModeOnCurrent");
8772        long ident = Binder.clearCallingIdentity();
8773        try {
8774            stopLockTaskMode();
8775        } finally {
8776            Binder.restoreCallingIdentity(ident);
8777        }
8778    }
8779
8780    @Override
8781    public boolean isInLockTaskMode() {
8782        synchronized (this) {
8783            return mStackSupervisor.isInLockTaskMode();
8784        }
8785    }
8786
8787    // =========================================================
8788    // CONTENT PROVIDERS
8789    // =========================================================
8790
8791    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8792        List<ProviderInfo> providers = null;
8793        try {
8794            providers = AppGlobals.getPackageManager().
8795                queryContentProviders(app.processName, app.uid,
8796                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8797        } catch (RemoteException ex) {
8798        }
8799        if (DEBUG_MU)
8800            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8801        int userId = app.userId;
8802        if (providers != null) {
8803            int N = providers.size();
8804            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8805            for (int i=0; i<N; i++) {
8806                ProviderInfo cpi =
8807                    (ProviderInfo)providers.get(i);
8808                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8809                        cpi.name, cpi.flags);
8810                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8811                    // This is a singleton provider, but a user besides the
8812                    // default user is asking to initialize a process it runs
8813                    // in...  well, no, it doesn't actually run in this process,
8814                    // it runs in the process of the default user.  Get rid of it.
8815                    providers.remove(i);
8816                    N--;
8817                    i--;
8818                    continue;
8819                }
8820
8821                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8822                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8823                if (cpr == null) {
8824                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8825                    mProviderMap.putProviderByClass(comp, cpr);
8826                }
8827                if (DEBUG_MU)
8828                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8829                app.pubProviders.put(cpi.name, cpr);
8830                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8831                    // Don't add this if it is a platform component that is marked
8832                    // to run in multiple processes, because this is actually
8833                    // part of the framework so doesn't make sense to track as a
8834                    // separate apk in the process.
8835                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8836                            mProcessStats);
8837                }
8838                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8839            }
8840        }
8841        return providers;
8842    }
8843
8844    /**
8845     * Check if {@link ProcessRecord} has a possible chance at accessing the
8846     * given {@link ProviderInfo}. Final permission checking is always done
8847     * in {@link ContentProvider}.
8848     */
8849    private final String checkContentProviderPermissionLocked(
8850            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8851        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8852        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8853        boolean checkedGrants = false;
8854        if (checkUser) {
8855            // Looking for cross-user grants before enforcing the typical cross-users permissions
8856            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8857            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8858                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8859                    return null;
8860                }
8861                checkedGrants = true;
8862            }
8863            userId = handleIncomingUser(callingPid, callingUid, userId,
8864                    false, ALLOW_NON_FULL,
8865                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8866            if (userId != tmpTargetUserId) {
8867                // When we actually went to determine the final targer user ID, this ended
8868                // up different than our initial check for the authority.  This is because
8869                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8870                // SELF.  So we need to re-check the grants again.
8871                checkedGrants = false;
8872            }
8873        }
8874        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8875                cpi.applicationInfo.uid, cpi.exported)
8876                == PackageManager.PERMISSION_GRANTED) {
8877            return null;
8878        }
8879        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8880                cpi.applicationInfo.uid, cpi.exported)
8881                == PackageManager.PERMISSION_GRANTED) {
8882            return null;
8883        }
8884
8885        PathPermission[] pps = cpi.pathPermissions;
8886        if (pps != null) {
8887            int i = pps.length;
8888            while (i > 0) {
8889                i--;
8890                PathPermission pp = pps[i];
8891                String pprperm = pp.getReadPermission();
8892                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8893                        cpi.applicationInfo.uid, cpi.exported)
8894                        == PackageManager.PERMISSION_GRANTED) {
8895                    return null;
8896                }
8897                String ppwperm = pp.getWritePermission();
8898                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8899                        cpi.applicationInfo.uid, cpi.exported)
8900                        == PackageManager.PERMISSION_GRANTED) {
8901                    return null;
8902                }
8903            }
8904        }
8905        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8906            return null;
8907        }
8908
8909        String msg;
8910        if (!cpi.exported) {
8911            msg = "Permission Denial: opening provider " + cpi.name
8912                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8913                    + ", uid=" + callingUid + ") that is not exported from uid "
8914                    + cpi.applicationInfo.uid;
8915        } else {
8916            msg = "Permission Denial: opening provider " + cpi.name
8917                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8918                    + ", uid=" + callingUid + ") requires "
8919                    + cpi.readPermission + " or " + cpi.writePermission;
8920        }
8921        Slog.w(TAG, msg);
8922        return msg;
8923    }
8924
8925    /**
8926     * Returns if the ContentProvider has granted a uri to callingUid
8927     */
8928    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8929        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8930        if (perms != null) {
8931            for (int i=perms.size()-1; i>=0; i--) {
8932                GrantUri grantUri = perms.keyAt(i);
8933                if (grantUri.sourceUserId == userId || !checkUser) {
8934                    if (matchesProvider(grantUri.uri, cpi)) {
8935                        return true;
8936                    }
8937                }
8938            }
8939        }
8940        return false;
8941    }
8942
8943    /**
8944     * Returns true if the uri authority is one of the authorities specified in the provider.
8945     */
8946    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8947        String uriAuth = uri.getAuthority();
8948        String cpiAuth = cpi.authority;
8949        if (cpiAuth.indexOf(';') == -1) {
8950            return cpiAuth.equals(uriAuth);
8951        }
8952        String[] cpiAuths = cpiAuth.split(";");
8953        int length = cpiAuths.length;
8954        for (int i = 0; i < length; i++) {
8955            if (cpiAuths[i].equals(uriAuth)) return true;
8956        }
8957        return false;
8958    }
8959
8960    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8961            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8962        if (r != null) {
8963            for (int i=0; i<r.conProviders.size(); i++) {
8964                ContentProviderConnection conn = r.conProviders.get(i);
8965                if (conn.provider == cpr) {
8966                    if (DEBUG_PROVIDER) Slog.v(TAG,
8967                            "Adding provider requested by "
8968                            + r.processName + " from process "
8969                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8970                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8971                    if (stable) {
8972                        conn.stableCount++;
8973                        conn.numStableIncs++;
8974                    } else {
8975                        conn.unstableCount++;
8976                        conn.numUnstableIncs++;
8977                    }
8978                    return conn;
8979                }
8980            }
8981            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8982            if (stable) {
8983                conn.stableCount = 1;
8984                conn.numStableIncs = 1;
8985            } else {
8986                conn.unstableCount = 1;
8987                conn.numUnstableIncs = 1;
8988            }
8989            cpr.connections.add(conn);
8990            r.conProviders.add(conn);
8991            return conn;
8992        }
8993        cpr.addExternalProcessHandleLocked(externalProcessToken);
8994        return null;
8995    }
8996
8997    boolean decProviderCountLocked(ContentProviderConnection conn,
8998            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8999        if (conn != null) {
9000            cpr = conn.provider;
9001            if (DEBUG_PROVIDER) Slog.v(TAG,
9002                    "Removing provider requested by "
9003                    + conn.client.processName + " from process "
9004                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9005                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9006            if (stable) {
9007                conn.stableCount--;
9008            } else {
9009                conn.unstableCount--;
9010            }
9011            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9012                cpr.connections.remove(conn);
9013                conn.client.conProviders.remove(conn);
9014                return true;
9015            }
9016            return false;
9017        }
9018        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9019        return false;
9020    }
9021
9022    private void checkTime(long startTime, String where) {
9023        long now = SystemClock.elapsedRealtime();
9024        if ((now-startTime) > 1000) {
9025            // If we are taking more than a second, log about it.
9026            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9027        }
9028    }
9029
9030    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9031            String name, IBinder token, boolean stable, int userId) {
9032        ContentProviderRecord cpr;
9033        ContentProviderConnection conn = null;
9034        ProviderInfo cpi = null;
9035
9036        synchronized(this) {
9037            long startTime = SystemClock.elapsedRealtime();
9038
9039            ProcessRecord r = null;
9040            if (caller != null) {
9041                r = getRecordForAppLocked(caller);
9042                if (r == null) {
9043                    throw new SecurityException(
9044                            "Unable to find app for caller " + caller
9045                          + " (pid=" + Binder.getCallingPid()
9046                          + ") when getting content provider " + name);
9047                }
9048            }
9049
9050            boolean checkCrossUser = true;
9051
9052            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9053
9054            // First check if this content provider has been published...
9055            cpr = mProviderMap.getProviderByName(name, userId);
9056            // If that didn't work, check if it exists for user 0 and then
9057            // verify that it's a singleton provider before using it.
9058            if (cpr == null && userId != UserHandle.USER_OWNER) {
9059                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9060                if (cpr != null) {
9061                    cpi = cpr.info;
9062                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9063                            cpi.name, cpi.flags)
9064                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9065                        userId = UserHandle.USER_OWNER;
9066                        checkCrossUser = false;
9067                    } else {
9068                        cpr = null;
9069                        cpi = null;
9070                    }
9071                }
9072            }
9073
9074            boolean providerRunning = cpr != null;
9075            if (providerRunning) {
9076                cpi = cpr.info;
9077                String msg;
9078                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9079                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9080                        != null) {
9081                    throw new SecurityException(msg);
9082                }
9083                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9084
9085                if (r != null && cpr.canRunHere(r)) {
9086                    // This provider has been published or is in the process
9087                    // of being published...  but it is also allowed to run
9088                    // in the caller's process, so don't make a connection
9089                    // and just let the caller instantiate its own instance.
9090                    ContentProviderHolder holder = cpr.newHolder(null);
9091                    // don't give caller the provider object, it needs
9092                    // to make its own.
9093                    holder.provider = null;
9094                    return holder;
9095                }
9096
9097                final long origId = Binder.clearCallingIdentity();
9098
9099                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9100
9101                // In this case the provider instance already exists, so we can
9102                // return it right away.
9103                conn = incProviderCountLocked(r, cpr, token, stable);
9104                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9105                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9106                        // If this is a perceptible app accessing the provider,
9107                        // make sure to count it as being accessed and thus
9108                        // back up on the LRU list.  This is good because
9109                        // content providers are often expensive to start.
9110                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9111                        updateLruProcessLocked(cpr.proc, false, null);
9112                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9113                    }
9114                }
9115
9116                if (cpr.proc != null) {
9117                    if (false) {
9118                        if (cpr.name.flattenToShortString().equals(
9119                                "com.android.providers.calendar/.CalendarProvider2")) {
9120                            Slog.v(TAG, "****************** KILLING "
9121                                + cpr.name.flattenToShortString());
9122                            Process.killProcess(cpr.proc.pid);
9123                        }
9124                    }
9125                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9126                    boolean success = updateOomAdjLocked(cpr.proc);
9127                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9128                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9129                    // NOTE: there is still a race here where a signal could be
9130                    // pending on the process even though we managed to update its
9131                    // adj level.  Not sure what to do about this, but at least
9132                    // the race is now smaller.
9133                    if (!success) {
9134                        // Uh oh...  it looks like the provider's process
9135                        // has been killed on us.  We need to wait for a new
9136                        // process to be started, and make sure its death
9137                        // doesn't kill our process.
9138                        Slog.i(TAG,
9139                                "Existing provider " + cpr.name.flattenToShortString()
9140                                + " is crashing; detaching " + r);
9141                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9142                        checkTime(startTime, "getContentProviderImpl: before appDied");
9143                        appDiedLocked(cpr.proc);
9144                        checkTime(startTime, "getContentProviderImpl: after appDied");
9145                        if (!lastRef) {
9146                            // This wasn't the last ref our process had on
9147                            // the provider...  we have now been killed, bail.
9148                            return null;
9149                        }
9150                        providerRunning = false;
9151                        conn = null;
9152                    }
9153                }
9154
9155                Binder.restoreCallingIdentity(origId);
9156            }
9157
9158            boolean singleton;
9159            if (!providerRunning) {
9160                try {
9161                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9162                    cpi = AppGlobals.getPackageManager().
9163                        resolveContentProvider(name,
9164                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9165                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9166                } catch (RemoteException ex) {
9167                }
9168                if (cpi == null) {
9169                    return null;
9170                }
9171                // If the provider is a singleton AND
9172                // (it's a call within the same user || the provider is a
9173                // privileged app)
9174                // Then allow connecting to the singleton provider
9175                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9176                        cpi.name, cpi.flags)
9177                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9178                if (singleton) {
9179                    userId = UserHandle.USER_OWNER;
9180                }
9181                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9182                checkTime(startTime, "getContentProviderImpl: got app info for user");
9183
9184                String msg;
9185                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9186                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9187                        != null) {
9188                    throw new SecurityException(msg);
9189                }
9190                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9191
9192                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9193                        && !cpi.processName.equals("system")) {
9194                    // If this content provider does not run in the system
9195                    // process, and the system is not yet ready to run other
9196                    // processes, then fail fast instead of hanging.
9197                    throw new IllegalArgumentException(
9198                            "Attempt to launch content provider before system ready");
9199                }
9200
9201                // Make sure that the user who owns this provider is started.  If not,
9202                // we don't want to allow it to run.
9203                if (mStartedUsers.get(userId) == null) {
9204                    Slog.w(TAG, "Unable to launch app "
9205                            + cpi.applicationInfo.packageName + "/"
9206                            + cpi.applicationInfo.uid + " for provider "
9207                            + name + ": user " + userId + " is stopped");
9208                    return null;
9209                }
9210
9211                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9212                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9213                cpr = mProviderMap.getProviderByClass(comp, userId);
9214                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9215                final boolean firstClass = cpr == null;
9216                if (firstClass) {
9217                    final long ident = Binder.clearCallingIdentity();
9218                    try {
9219                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9220                        ApplicationInfo ai =
9221                            AppGlobals.getPackageManager().
9222                                getApplicationInfo(
9223                                        cpi.applicationInfo.packageName,
9224                                        STOCK_PM_FLAGS, userId);
9225                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9226                        if (ai == null) {
9227                            Slog.w(TAG, "No package info for content provider "
9228                                    + cpi.name);
9229                            return null;
9230                        }
9231                        ai = getAppInfoForUser(ai, userId);
9232                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9233                    } catch (RemoteException ex) {
9234                        // pm is in same process, this will never happen.
9235                    } finally {
9236                        Binder.restoreCallingIdentity(ident);
9237                    }
9238                }
9239
9240                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9241
9242                if (r != null && cpr.canRunHere(r)) {
9243                    // If this is a multiprocess provider, then just return its
9244                    // info and allow the caller to instantiate it.  Only do
9245                    // this if the provider is the same user as the caller's
9246                    // process, or can run as root (so can be in any process).
9247                    return cpr.newHolder(null);
9248                }
9249
9250                if (DEBUG_PROVIDER) {
9251                    RuntimeException e = new RuntimeException("here");
9252                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9253                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9254                }
9255
9256                // This is single process, and our app is now connecting to it.
9257                // See if we are already in the process of launching this
9258                // provider.
9259                final int N = mLaunchingProviders.size();
9260                int i;
9261                for (i=0; i<N; i++) {
9262                    if (mLaunchingProviders.get(i) == cpr) {
9263                        break;
9264                    }
9265                }
9266
9267                // If the provider is not already being launched, then get it
9268                // started.
9269                if (i >= N) {
9270                    final long origId = Binder.clearCallingIdentity();
9271
9272                    try {
9273                        // Content provider is now in use, its package can't be stopped.
9274                        try {
9275                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9276                            AppGlobals.getPackageManager().setPackageStoppedState(
9277                                    cpr.appInfo.packageName, false, userId);
9278                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9279                        } catch (RemoteException e) {
9280                        } catch (IllegalArgumentException e) {
9281                            Slog.w(TAG, "Failed trying to unstop package "
9282                                    + cpr.appInfo.packageName + ": " + e);
9283                        }
9284
9285                        // Use existing process if already started
9286                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9287                        ProcessRecord proc = getProcessRecordLocked(
9288                                cpi.processName, cpr.appInfo.uid, false);
9289                        if (proc != null && proc.thread != null) {
9290                            if (DEBUG_PROVIDER) {
9291                                Slog.d(TAG, "Installing in existing process " + proc);
9292                            }
9293                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9294                            proc.pubProviders.put(cpi.name, cpr);
9295                            try {
9296                                proc.thread.scheduleInstallProvider(cpi);
9297                            } catch (RemoteException e) {
9298                            }
9299                        } else {
9300                            checkTime(startTime, "getContentProviderImpl: before start process");
9301                            proc = startProcessLocked(cpi.processName,
9302                                    cpr.appInfo, false, 0, "content provider",
9303                                    new ComponentName(cpi.applicationInfo.packageName,
9304                                            cpi.name), false, false, false);
9305                            checkTime(startTime, "getContentProviderImpl: after start process");
9306                            if (proc == null) {
9307                                Slog.w(TAG, "Unable to launch app "
9308                                        + cpi.applicationInfo.packageName + "/"
9309                                        + cpi.applicationInfo.uid + " for provider "
9310                                        + name + ": process is bad");
9311                                return null;
9312                            }
9313                        }
9314                        cpr.launchingApp = proc;
9315                        mLaunchingProviders.add(cpr);
9316                    } finally {
9317                        Binder.restoreCallingIdentity(origId);
9318                    }
9319                }
9320
9321                checkTime(startTime, "getContentProviderImpl: updating data structures");
9322
9323                // Make sure the provider is published (the same provider class
9324                // may be published under multiple names).
9325                if (firstClass) {
9326                    mProviderMap.putProviderByClass(comp, cpr);
9327                }
9328
9329                mProviderMap.putProviderByName(name, cpr);
9330                conn = incProviderCountLocked(r, cpr, token, stable);
9331                if (conn != null) {
9332                    conn.waiting = true;
9333                }
9334            }
9335            checkTime(startTime, "getContentProviderImpl: done!");
9336        }
9337
9338        // Wait for the provider to be published...
9339        synchronized (cpr) {
9340            while (cpr.provider == null) {
9341                if (cpr.launchingApp == null) {
9342                    Slog.w(TAG, "Unable to launch app "
9343                            + cpi.applicationInfo.packageName + "/"
9344                            + cpi.applicationInfo.uid + " for provider "
9345                            + name + ": launching app became null");
9346                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9347                            UserHandle.getUserId(cpi.applicationInfo.uid),
9348                            cpi.applicationInfo.packageName,
9349                            cpi.applicationInfo.uid, name);
9350                    return null;
9351                }
9352                try {
9353                    if (DEBUG_MU) {
9354                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9355                                + cpr.launchingApp);
9356                    }
9357                    if (conn != null) {
9358                        conn.waiting = true;
9359                    }
9360                    cpr.wait();
9361                } catch (InterruptedException ex) {
9362                } finally {
9363                    if (conn != null) {
9364                        conn.waiting = false;
9365                    }
9366                }
9367            }
9368        }
9369        return cpr != null ? cpr.newHolder(conn) : null;
9370    }
9371
9372    @Override
9373    public final ContentProviderHolder getContentProvider(
9374            IApplicationThread caller, String name, int userId, boolean stable) {
9375        enforceNotIsolatedCaller("getContentProvider");
9376        if (caller == null) {
9377            String msg = "null IApplicationThread when getting content provider "
9378                    + name;
9379            Slog.w(TAG, msg);
9380            throw new SecurityException(msg);
9381        }
9382        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9383        // with cross-user grant.
9384        return getContentProviderImpl(caller, name, null, stable, userId);
9385    }
9386
9387    public ContentProviderHolder getContentProviderExternal(
9388            String name, int userId, IBinder token) {
9389        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9390            "Do not have permission in call getContentProviderExternal()");
9391        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9392                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9393        return getContentProviderExternalUnchecked(name, token, userId);
9394    }
9395
9396    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9397            IBinder token, int userId) {
9398        return getContentProviderImpl(null, name, token, true, userId);
9399    }
9400
9401    /**
9402     * Drop a content provider from a ProcessRecord's bookkeeping
9403     */
9404    public void removeContentProvider(IBinder connection, boolean stable) {
9405        enforceNotIsolatedCaller("removeContentProvider");
9406        long ident = Binder.clearCallingIdentity();
9407        try {
9408            synchronized (this) {
9409                ContentProviderConnection conn;
9410                try {
9411                    conn = (ContentProviderConnection)connection;
9412                } catch (ClassCastException e) {
9413                    String msg ="removeContentProvider: " + connection
9414                            + " not a ContentProviderConnection";
9415                    Slog.w(TAG, msg);
9416                    throw new IllegalArgumentException(msg);
9417                }
9418                if (conn == null) {
9419                    throw new NullPointerException("connection is null");
9420                }
9421                if (decProviderCountLocked(conn, null, null, stable)) {
9422                    updateOomAdjLocked();
9423                }
9424            }
9425        } finally {
9426            Binder.restoreCallingIdentity(ident);
9427        }
9428    }
9429
9430    public void removeContentProviderExternal(String name, IBinder token) {
9431        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9432            "Do not have permission in call removeContentProviderExternal()");
9433        int userId = UserHandle.getCallingUserId();
9434        long ident = Binder.clearCallingIdentity();
9435        try {
9436            removeContentProviderExternalUnchecked(name, token, userId);
9437        } finally {
9438            Binder.restoreCallingIdentity(ident);
9439        }
9440    }
9441
9442    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9443        synchronized (this) {
9444            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9445            if(cpr == null) {
9446                //remove from mProvidersByClass
9447                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9448                return;
9449            }
9450
9451            //update content provider record entry info
9452            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9453            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9454            if (localCpr.hasExternalProcessHandles()) {
9455                if (localCpr.removeExternalProcessHandleLocked(token)) {
9456                    updateOomAdjLocked();
9457                } else {
9458                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9459                            + " with no external reference for token: "
9460                            + token + ".");
9461                }
9462            } else {
9463                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9464                        + " with no external references.");
9465            }
9466        }
9467    }
9468
9469    public final void publishContentProviders(IApplicationThread caller,
9470            List<ContentProviderHolder> providers) {
9471        if (providers == null) {
9472            return;
9473        }
9474
9475        enforceNotIsolatedCaller("publishContentProviders");
9476        synchronized (this) {
9477            final ProcessRecord r = getRecordForAppLocked(caller);
9478            if (DEBUG_MU)
9479                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9480            if (r == null) {
9481                throw new SecurityException(
9482                        "Unable to find app for caller " + caller
9483                      + " (pid=" + Binder.getCallingPid()
9484                      + ") when publishing content providers");
9485            }
9486
9487            final long origId = Binder.clearCallingIdentity();
9488
9489            final int N = providers.size();
9490            for (int i=0; i<N; i++) {
9491                ContentProviderHolder src = providers.get(i);
9492                if (src == null || src.info == null || src.provider == null) {
9493                    continue;
9494                }
9495                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9496                if (DEBUG_MU)
9497                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9498                if (dst != null) {
9499                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9500                    mProviderMap.putProviderByClass(comp, dst);
9501                    String names[] = dst.info.authority.split(";");
9502                    for (int j = 0; j < names.length; j++) {
9503                        mProviderMap.putProviderByName(names[j], dst);
9504                    }
9505
9506                    int NL = mLaunchingProviders.size();
9507                    int j;
9508                    for (j=0; j<NL; j++) {
9509                        if (mLaunchingProviders.get(j) == dst) {
9510                            mLaunchingProviders.remove(j);
9511                            j--;
9512                            NL--;
9513                        }
9514                    }
9515                    synchronized (dst) {
9516                        dst.provider = src.provider;
9517                        dst.proc = r;
9518                        dst.notifyAll();
9519                    }
9520                    updateOomAdjLocked(r);
9521                }
9522            }
9523
9524            Binder.restoreCallingIdentity(origId);
9525        }
9526    }
9527
9528    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9529        ContentProviderConnection conn;
9530        try {
9531            conn = (ContentProviderConnection)connection;
9532        } catch (ClassCastException e) {
9533            String msg ="refContentProvider: " + connection
9534                    + " not a ContentProviderConnection";
9535            Slog.w(TAG, msg);
9536            throw new IllegalArgumentException(msg);
9537        }
9538        if (conn == null) {
9539            throw new NullPointerException("connection is null");
9540        }
9541
9542        synchronized (this) {
9543            if (stable > 0) {
9544                conn.numStableIncs += stable;
9545            }
9546            stable = conn.stableCount + stable;
9547            if (stable < 0) {
9548                throw new IllegalStateException("stableCount < 0: " + stable);
9549            }
9550
9551            if (unstable > 0) {
9552                conn.numUnstableIncs += unstable;
9553            }
9554            unstable = conn.unstableCount + unstable;
9555            if (unstable < 0) {
9556                throw new IllegalStateException("unstableCount < 0: " + unstable);
9557            }
9558
9559            if ((stable+unstable) <= 0) {
9560                throw new IllegalStateException("ref counts can't go to zero here: stable="
9561                        + stable + " unstable=" + unstable);
9562            }
9563            conn.stableCount = stable;
9564            conn.unstableCount = unstable;
9565            return !conn.dead;
9566        }
9567    }
9568
9569    public void unstableProviderDied(IBinder connection) {
9570        ContentProviderConnection conn;
9571        try {
9572            conn = (ContentProviderConnection)connection;
9573        } catch (ClassCastException e) {
9574            String msg ="refContentProvider: " + connection
9575                    + " not a ContentProviderConnection";
9576            Slog.w(TAG, msg);
9577            throw new IllegalArgumentException(msg);
9578        }
9579        if (conn == null) {
9580            throw new NullPointerException("connection is null");
9581        }
9582
9583        // Safely retrieve the content provider associated with the connection.
9584        IContentProvider provider;
9585        synchronized (this) {
9586            provider = conn.provider.provider;
9587        }
9588
9589        if (provider == null) {
9590            // Um, yeah, we're way ahead of you.
9591            return;
9592        }
9593
9594        // Make sure the caller is being honest with us.
9595        if (provider.asBinder().pingBinder()) {
9596            // Er, no, still looks good to us.
9597            synchronized (this) {
9598                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9599                        + " says " + conn + " died, but we don't agree");
9600                return;
9601            }
9602        }
9603
9604        // Well look at that!  It's dead!
9605        synchronized (this) {
9606            if (conn.provider.provider != provider) {
9607                // But something changed...  good enough.
9608                return;
9609            }
9610
9611            ProcessRecord proc = conn.provider.proc;
9612            if (proc == null || proc.thread == null) {
9613                // Seems like the process is already cleaned up.
9614                return;
9615            }
9616
9617            // As far as we're concerned, this is just like receiving a
9618            // death notification...  just a bit prematurely.
9619            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9620                    + ") early provider death");
9621            final long ident = Binder.clearCallingIdentity();
9622            try {
9623                appDiedLocked(proc);
9624            } finally {
9625                Binder.restoreCallingIdentity(ident);
9626            }
9627        }
9628    }
9629
9630    @Override
9631    public void appNotRespondingViaProvider(IBinder connection) {
9632        enforceCallingPermission(
9633                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9634
9635        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9636        if (conn == null) {
9637            Slog.w(TAG, "ContentProviderConnection is null");
9638            return;
9639        }
9640
9641        final ProcessRecord host = conn.provider.proc;
9642        if (host == null) {
9643            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9644            return;
9645        }
9646
9647        final long token = Binder.clearCallingIdentity();
9648        try {
9649            appNotResponding(host, null, null, false, "ContentProvider not responding");
9650        } finally {
9651            Binder.restoreCallingIdentity(token);
9652        }
9653    }
9654
9655    public final void installSystemProviders() {
9656        List<ProviderInfo> providers;
9657        synchronized (this) {
9658            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9659            providers = generateApplicationProvidersLocked(app);
9660            if (providers != null) {
9661                for (int i=providers.size()-1; i>=0; i--) {
9662                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9663                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9664                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9665                                + ": not system .apk");
9666                        providers.remove(i);
9667                    }
9668                }
9669            }
9670        }
9671        if (providers != null) {
9672            mSystemThread.installSystemProviders(providers);
9673        }
9674
9675        mCoreSettingsObserver = new CoreSettingsObserver(this);
9676
9677        //mUsageStatsService.monitorPackages();
9678    }
9679
9680    /**
9681     * Allows apps to retrieve the MIME type of a URI.
9682     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9683     * users, then it does not need permission to access the ContentProvider.
9684     * Either, it needs cross-user uri grants.
9685     *
9686     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9687     *
9688     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9689     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9690     */
9691    public String getProviderMimeType(Uri uri, int userId) {
9692        enforceNotIsolatedCaller("getProviderMimeType");
9693        final String name = uri.getAuthority();
9694        int callingUid = Binder.getCallingUid();
9695        int callingPid = Binder.getCallingPid();
9696        long ident = 0;
9697        boolean clearedIdentity = false;
9698        userId = unsafeConvertIncomingUser(userId);
9699        if (canClearIdentity(callingPid, callingUid, userId)) {
9700            clearedIdentity = true;
9701            ident = Binder.clearCallingIdentity();
9702        }
9703        ContentProviderHolder holder = null;
9704        try {
9705            holder = getContentProviderExternalUnchecked(name, null, userId);
9706            if (holder != null) {
9707                return holder.provider.getType(uri);
9708            }
9709        } catch (RemoteException e) {
9710            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9711            return null;
9712        } finally {
9713            // We need to clear the identity to call removeContentProviderExternalUnchecked
9714            if (!clearedIdentity) {
9715                ident = Binder.clearCallingIdentity();
9716            }
9717            try {
9718                if (holder != null) {
9719                    removeContentProviderExternalUnchecked(name, null, userId);
9720                }
9721            } finally {
9722                Binder.restoreCallingIdentity(ident);
9723            }
9724        }
9725
9726        return null;
9727    }
9728
9729    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9730        if (UserHandle.getUserId(callingUid) == userId) {
9731            return true;
9732        }
9733        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9734                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9735                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9736                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9737                return true;
9738        }
9739        return false;
9740    }
9741
9742    // =========================================================
9743    // GLOBAL MANAGEMENT
9744    // =========================================================
9745
9746    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9747            boolean isolated, int isolatedUid) {
9748        String proc = customProcess != null ? customProcess : info.processName;
9749        BatteryStatsImpl.Uid.Proc ps = null;
9750        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9751        int uid = info.uid;
9752        if (isolated) {
9753            if (isolatedUid == 0) {
9754                int userId = UserHandle.getUserId(uid);
9755                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9756                while (true) {
9757                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9758                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9759                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9760                    }
9761                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9762                    mNextIsolatedProcessUid++;
9763                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9764                        // No process for this uid, use it.
9765                        break;
9766                    }
9767                    stepsLeft--;
9768                    if (stepsLeft <= 0) {
9769                        return null;
9770                    }
9771                }
9772            } else {
9773                // Special case for startIsolatedProcess (internal only), where
9774                // the uid of the isolated process is specified by the caller.
9775                uid = isolatedUid;
9776            }
9777        }
9778        return new ProcessRecord(stats, info, proc, uid);
9779    }
9780
9781    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9782            String abiOverride) {
9783        ProcessRecord app;
9784        if (!isolated) {
9785            app = getProcessRecordLocked(info.processName, info.uid, true);
9786        } else {
9787            app = null;
9788        }
9789
9790        if (app == null) {
9791            app = newProcessRecordLocked(info, null, isolated, 0);
9792            mProcessNames.put(info.processName, app.uid, app);
9793            if (isolated) {
9794                mIsolatedProcesses.put(app.uid, app);
9795            }
9796            updateLruProcessLocked(app, false, null);
9797            updateOomAdjLocked();
9798        }
9799
9800        // This package really, really can not be stopped.
9801        try {
9802            AppGlobals.getPackageManager().setPackageStoppedState(
9803                    info.packageName, false, UserHandle.getUserId(app.uid));
9804        } catch (RemoteException e) {
9805        } catch (IllegalArgumentException e) {
9806            Slog.w(TAG, "Failed trying to unstop package "
9807                    + info.packageName + ": " + e);
9808        }
9809
9810        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9811                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9812            app.persistent = true;
9813            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9814        }
9815        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9816            mPersistentStartingProcesses.add(app);
9817            startProcessLocked(app, "added application", app.processName, abiOverride,
9818                    null /* entryPoint */, null /* entryPointArgs */);
9819        }
9820
9821        return app;
9822    }
9823
9824    public void unhandledBack() {
9825        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9826                "unhandledBack()");
9827
9828        synchronized(this) {
9829            final long origId = Binder.clearCallingIdentity();
9830            try {
9831                getFocusedStack().unhandledBackLocked();
9832            } finally {
9833                Binder.restoreCallingIdentity(origId);
9834            }
9835        }
9836    }
9837
9838    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9839        enforceNotIsolatedCaller("openContentUri");
9840        final int userId = UserHandle.getCallingUserId();
9841        String name = uri.getAuthority();
9842        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9843        ParcelFileDescriptor pfd = null;
9844        if (cph != null) {
9845            // We record the binder invoker's uid in thread-local storage before
9846            // going to the content provider to open the file.  Later, in the code
9847            // that handles all permissions checks, we look for this uid and use
9848            // that rather than the Activity Manager's own uid.  The effect is that
9849            // we do the check against the caller's permissions even though it looks
9850            // to the content provider like the Activity Manager itself is making
9851            // the request.
9852            sCallerIdentity.set(new Identity(
9853                    Binder.getCallingPid(), Binder.getCallingUid()));
9854            try {
9855                pfd = cph.provider.openFile(null, uri, "r", null);
9856            } catch (FileNotFoundException e) {
9857                // do nothing; pfd will be returned null
9858            } finally {
9859                // Ensure that whatever happens, we clean up the identity state
9860                sCallerIdentity.remove();
9861            }
9862
9863            // We've got the fd now, so we're done with the provider.
9864            removeContentProviderExternalUnchecked(name, null, userId);
9865        } else {
9866            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9867        }
9868        return pfd;
9869    }
9870
9871    // Actually is sleeping or shutting down or whatever else in the future
9872    // is an inactive state.
9873    public boolean isSleepingOrShuttingDown() {
9874        return isSleeping() || mShuttingDown;
9875    }
9876
9877    public boolean isSleeping() {
9878        return mSleeping;
9879    }
9880
9881    void goingToSleep() {
9882        synchronized(this) {
9883            mWentToSleep = true;
9884            goToSleepIfNeededLocked();
9885        }
9886    }
9887
9888    void finishRunningVoiceLocked() {
9889        if (mRunningVoice) {
9890            mRunningVoice = false;
9891            goToSleepIfNeededLocked();
9892        }
9893    }
9894
9895    void goToSleepIfNeededLocked() {
9896        if (mWentToSleep && !mRunningVoice) {
9897            if (!mSleeping) {
9898                mSleeping = true;
9899                mStackSupervisor.goingToSleepLocked();
9900
9901                // Initialize the wake times of all processes.
9902                checkExcessivePowerUsageLocked(false);
9903                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9904                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9905                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9906            }
9907        }
9908    }
9909
9910    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9911        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9912            // Never persist the home stack.
9913            return;
9914        }
9915        mTaskPersister.wakeup(task, flush);
9916    }
9917
9918    @Override
9919    public boolean shutdown(int timeout) {
9920        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9921                != PackageManager.PERMISSION_GRANTED) {
9922            throw new SecurityException("Requires permission "
9923                    + android.Manifest.permission.SHUTDOWN);
9924        }
9925
9926        boolean timedout = false;
9927
9928        synchronized(this) {
9929            mShuttingDown = true;
9930            updateEventDispatchingLocked();
9931            timedout = mStackSupervisor.shutdownLocked(timeout);
9932        }
9933
9934        mAppOpsService.shutdown();
9935        if (mUsageStatsService != null) {
9936            mUsageStatsService.prepareShutdown();
9937        }
9938        mBatteryStatsService.shutdown();
9939        synchronized (this) {
9940            mProcessStats.shutdownLocked();
9941        }
9942        notifyTaskPersisterLocked(null, true);
9943
9944        return timedout;
9945    }
9946
9947    public final void activitySlept(IBinder token) {
9948        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9949
9950        final long origId = Binder.clearCallingIdentity();
9951
9952        synchronized (this) {
9953            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9954            if (r != null) {
9955                mStackSupervisor.activitySleptLocked(r);
9956            }
9957        }
9958
9959        Binder.restoreCallingIdentity(origId);
9960    }
9961
9962    private String lockScreenShownToString() {
9963        switch (mLockScreenShown) {
9964            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9965            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9966            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9967            default: return "Unknown=" + mLockScreenShown;
9968        }
9969    }
9970
9971    void logLockScreen(String msg) {
9972        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9973                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
9974                mWentToSleep + " mSleeping=" + mSleeping);
9975    }
9976
9977    void comeOutOfSleepIfNeededLocked() {
9978        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
9979            if (mSleeping) {
9980                mSleeping = false;
9981                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9982            }
9983        }
9984    }
9985
9986    void wakingUp() {
9987        synchronized(this) {
9988            mWentToSleep = false;
9989            comeOutOfSleepIfNeededLocked();
9990        }
9991    }
9992
9993    void startRunningVoiceLocked() {
9994        if (!mRunningVoice) {
9995            mRunningVoice = true;
9996            comeOutOfSleepIfNeededLocked();
9997        }
9998    }
9999
10000    private void updateEventDispatchingLocked() {
10001        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10002    }
10003
10004    public void setLockScreenShown(boolean shown) {
10005        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10006                != PackageManager.PERMISSION_GRANTED) {
10007            throw new SecurityException("Requires permission "
10008                    + android.Manifest.permission.DEVICE_POWER);
10009        }
10010
10011        synchronized(this) {
10012            long ident = Binder.clearCallingIdentity();
10013            try {
10014                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10015                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10016                comeOutOfSleepIfNeededLocked();
10017            } finally {
10018                Binder.restoreCallingIdentity(ident);
10019            }
10020        }
10021    }
10022
10023    @Override
10024    public void stopAppSwitches() {
10025        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10026                != PackageManager.PERMISSION_GRANTED) {
10027            throw new SecurityException("Requires permission "
10028                    + android.Manifest.permission.STOP_APP_SWITCHES);
10029        }
10030
10031        synchronized(this) {
10032            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10033                    + APP_SWITCH_DELAY_TIME;
10034            mDidAppSwitch = false;
10035            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10036            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10037            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10038        }
10039    }
10040
10041    public void resumeAppSwitches() {
10042        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10043                != PackageManager.PERMISSION_GRANTED) {
10044            throw new SecurityException("Requires permission "
10045                    + android.Manifest.permission.STOP_APP_SWITCHES);
10046        }
10047
10048        synchronized(this) {
10049            // Note that we don't execute any pending app switches... we will
10050            // let those wait until either the timeout, or the next start
10051            // activity request.
10052            mAppSwitchesAllowedTime = 0;
10053        }
10054    }
10055
10056    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10057            int callingPid, int callingUid, String name) {
10058        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10059            return true;
10060        }
10061
10062        int perm = checkComponentPermission(
10063                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10064                sourceUid, -1, true);
10065        if (perm == PackageManager.PERMISSION_GRANTED) {
10066            return true;
10067        }
10068
10069        // If the actual IPC caller is different from the logical source, then
10070        // also see if they are allowed to control app switches.
10071        if (callingUid != -1 && callingUid != sourceUid) {
10072            perm = checkComponentPermission(
10073                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10074                    callingUid, -1, true);
10075            if (perm == PackageManager.PERMISSION_GRANTED) {
10076                return true;
10077            }
10078        }
10079
10080        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10081        return false;
10082    }
10083
10084    public void setDebugApp(String packageName, boolean waitForDebugger,
10085            boolean persistent) {
10086        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10087                "setDebugApp()");
10088
10089        long ident = Binder.clearCallingIdentity();
10090        try {
10091            // Note that this is not really thread safe if there are multiple
10092            // callers into it at the same time, but that's not a situation we
10093            // care about.
10094            if (persistent) {
10095                final ContentResolver resolver = mContext.getContentResolver();
10096                Settings.Global.putString(
10097                    resolver, Settings.Global.DEBUG_APP,
10098                    packageName);
10099                Settings.Global.putInt(
10100                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10101                    waitForDebugger ? 1 : 0);
10102            }
10103
10104            synchronized (this) {
10105                if (!persistent) {
10106                    mOrigDebugApp = mDebugApp;
10107                    mOrigWaitForDebugger = mWaitForDebugger;
10108                }
10109                mDebugApp = packageName;
10110                mWaitForDebugger = waitForDebugger;
10111                mDebugTransient = !persistent;
10112                if (packageName != null) {
10113                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10114                            false, UserHandle.USER_ALL, "set debug app");
10115                }
10116            }
10117        } finally {
10118            Binder.restoreCallingIdentity(ident);
10119        }
10120    }
10121
10122    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10123        synchronized (this) {
10124            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10125            if (!isDebuggable) {
10126                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10127                    throw new SecurityException("Process not debuggable: " + app.packageName);
10128                }
10129            }
10130
10131            mOpenGlTraceApp = processName;
10132        }
10133    }
10134
10135    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10136        synchronized (this) {
10137            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10138            if (!isDebuggable) {
10139                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10140                    throw new SecurityException("Process not debuggable: " + app.packageName);
10141                }
10142            }
10143            mProfileApp = processName;
10144            mProfileFile = profilerInfo.profileFile;
10145            if (mProfileFd != null) {
10146                try {
10147                    mProfileFd.close();
10148                } catch (IOException e) {
10149                }
10150                mProfileFd = null;
10151            }
10152            mProfileFd = profilerInfo.profileFd;
10153            mSamplingInterval = profilerInfo.samplingInterval;
10154            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10155            mProfileType = 0;
10156        }
10157    }
10158
10159    @Override
10160    public void setAlwaysFinish(boolean enabled) {
10161        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10162                "setAlwaysFinish()");
10163
10164        Settings.Global.putInt(
10165                mContext.getContentResolver(),
10166                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10167
10168        synchronized (this) {
10169            mAlwaysFinishActivities = enabled;
10170        }
10171    }
10172
10173    @Override
10174    public void setActivityController(IActivityController controller) {
10175        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10176                "setActivityController()");
10177        synchronized (this) {
10178            mController = controller;
10179            Watchdog.getInstance().setActivityController(controller);
10180        }
10181    }
10182
10183    @Override
10184    public void setUserIsMonkey(boolean userIsMonkey) {
10185        synchronized (this) {
10186            synchronized (mPidsSelfLocked) {
10187                final int callingPid = Binder.getCallingPid();
10188                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10189                if (precessRecord == null) {
10190                    throw new SecurityException("Unknown process: " + callingPid);
10191                }
10192                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10193                    throw new SecurityException("Only an instrumentation process "
10194                            + "with a UiAutomation can call setUserIsMonkey");
10195                }
10196            }
10197            mUserIsMonkey = userIsMonkey;
10198        }
10199    }
10200
10201    @Override
10202    public boolean isUserAMonkey() {
10203        synchronized (this) {
10204            // If there is a controller also implies the user is a monkey.
10205            return (mUserIsMonkey || mController != null);
10206        }
10207    }
10208
10209    public void requestBugReport() {
10210        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10211        SystemProperties.set("ctl.start", "bugreport");
10212    }
10213
10214    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10215        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10216    }
10217
10218    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10219        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10220            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10221        }
10222        return KEY_DISPATCHING_TIMEOUT;
10223    }
10224
10225    @Override
10226    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10227        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10228                != PackageManager.PERMISSION_GRANTED) {
10229            throw new SecurityException("Requires permission "
10230                    + android.Manifest.permission.FILTER_EVENTS);
10231        }
10232        ProcessRecord proc;
10233        long timeout;
10234        synchronized (this) {
10235            synchronized (mPidsSelfLocked) {
10236                proc = mPidsSelfLocked.get(pid);
10237            }
10238            timeout = getInputDispatchingTimeoutLocked(proc);
10239        }
10240
10241        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10242            return -1;
10243        }
10244
10245        return timeout;
10246    }
10247
10248    /**
10249     * Handle input dispatching timeouts.
10250     * Returns whether input dispatching should be aborted or not.
10251     */
10252    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10253            final ActivityRecord activity, final ActivityRecord parent,
10254            final boolean aboveSystem, String reason) {
10255        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10256                != PackageManager.PERMISSION_GRANTED) {
10257            throw new SecurityException("Requires permission "
10258                    + android.Manifest.permission.FILTER_EVENTS);
10259        }
10260
10261        final String annotation;
10262        if (reason == null) {
10263            annotation = "Input dispatching timed out";
10264        } else {
10265            annotation = "Input dispatching timed out (" + reason + ")";
10266        }
10267
10268        if (proc != null) {
10269            synchronized (this) {
10270                if (proc.debugging) {
10271                    return false;
10272                }
10273
10274                if (mDidDexOpt) {
10275                    // Give more time since we were dexopting.
10276                    mDidDexOpt = false;
10277                    return false;
10278                }
10279
10280                if (proc.instrumentationClass != null) {
10281                    Bundle info = new Bundle();
10282                    info.putString("shortMsg", "keyDispatchingTimedOut");
10283                    info.putString("longMsg", annotation);
10284                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10285                    return true;
10286                }
10287            }
10288            mHandler.post(new Runnable() {
10289                @Override
10290                public void run() {
10291                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10292                }
10293            });
10294        }
10295
10296        return true;
10297    }
10298
10299    public Bundle getAssistContextExtras(int requestType) {
10300        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10301                UserHandle.getCallingUserId());
10302        if (pae == null) {
10303            return null;
10304        }
10305        synchronized (pae) {
10306            while (!pae.haveResult) {
10307                try {
10308                    pae.wait();
10309                } catch (InterruptedException e) {
10310                }
10311            }
10312            if (pae.result != null) {
10313                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10314            }
10315        }
10316        synchronized (this) {
10317            mPendingAssistExtras.remove(pae);
10318            mHandler.removeCallbacks(pae);
10319        }
10320        return pae.extras;
10321    }
10322
10323    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10324            int userHandle) {
10325        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10326                "getAssistContextExtras()");
10327        PendingAssistExtras pae;
10328        Bundle extras = new Bundle();
10329        synchronized (this) {
10330            ActivityRecord activity = getFocusedStack().mResumedActivity;
10331            if (activity == null) {
10332                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10333                return null;
10334            }
10335            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10336            if (activity.app == null || activity.app.thread == null) {
10337                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10338                return null;
10339            }
10340            if (activity.app.pid == Binder.getCallingPid()) {
10341                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10342                return null;
10343            }
10344            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10345            try {
10346                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10347                        requestType);
10348                mPendingAssistExtras.add(pae);
10349                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10350            } catch (RemoteException e) {
10351                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10352                return null;
10353            }
10354            return pae;
10355        }
10356    }
10357
10358    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10359        PendingAssistExtras pae = (PendingAssistExtras)token;
10360        synchronized (pae) {
10361            pae.result = extras;
10362            pae.haveResult = true;
10363            pae.notifyAll();
10364            if (pae.intent == null) {
10365                // Caller is just waiting for the result.
10366                return;
10367            }
10368        }
10369
10370        // We are now ready to launch the assist activity.
10371        synchronized (this) {
10372            boolean exists = mPendingAssistExtras.remove(pae);
10373            mHandler.removeCallbacks(pae);
10374            if (!exists) {
10375                // Timed out.
10376                return;
10377            }
10378        }
10379        pae.intent.replaceExtras(extras);
10380        if (pae.hint != null) {
10381            pae.intent.putExtra(pae.hint, true);
10382        }
10383        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10384                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10385                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10386        closeSystemDialogs("assist");
10387        try {
10388            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10389        } catch (ActivityNotFoundException e) {
10390            Slog.w(TAG, "No activity to handle assist action.", e);
10391        }
10392    }
10393
10394    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10395        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10396    }
10397
10398    public void registerProcessObserver(IProcessObserver observer) {
10399        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10400                "registerProcessObserver()");
10401        synchronized (this) {
10402            mProcessObservers.register(observer);
10403        }
10404    }
10405
10406    @Override
10407    public void unregisterProcessObserver(IProcessObserver observer) {
10408        synchronized (this) {
10409            mProcessObservers.unregister(observer);
10410        }
10411    }
10412
10413    @Override
10414    public boolean convertFromTranslucent(IBinder token) {
10415        final long origId = Binder.clearCallingIdentity();
10416        try {
10417            synchronized (this) {
10418                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10419                if (r == null) {
10420                    return false;
10421                }
10422                final boolean translucentChanged = r.changeWindowTranslucency(true);
10423                if (translucentChanged) {
10424                    r.task.stack.releaseBackgroundResources();
10425                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10426                }
10427                mWindowManager.setAppFullscreen(token, true);
10428                return translucentChanged;
10429            }
10430        } finally {
10431            Binder.restoreCallingIdentity(origId);
10432        }
10433    }
10434
10435    @Override
10436    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10437        final long origId = Binder.clearCallingIdentity();
10438        try {
10439            synchronized (this) {
10440                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10441                if (r == null) {
10442                    return false;
10443                }
10444                int index = r.task.mActivities.lastIndexOf(r);
10445                if (index > 0) {
10446                    ActivityRecord under = r.task.mActivities.get(index - 1);
10447                    under.returningOptions = options;
10448                }
10449                final boolean translucentChanged = r.changeWindowTranslucency(false);
10450                if (translucentChanged) {
10451                    r.task.stack.convertToTranslucent(r);
10452                }
10453                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10454                mWindowManager.setAppFullscreen(token, false);
10455                return translucentChanged;
10456            }
10457        } finally {
10458            Binder.restoreCallingIdentity(origId);
10459        }
10460    }
10461
10462    @Override
10463    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10464        final long origId = Binder.clearCallingIdentity();
10465        try {
10466            synchronized (this) {
10467                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10468                if (r != null) {
10469                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10470                }
10471            }
10472            return false;
10473        } finally {
10474            Binder.restoreCallingIdentity(origId);
10475        }
10476    }
10477
10478    @Override
10479    public boolean isBackgroundVisibleBehind(IBinder token) {
10480        final long origId = Binder.clearCallingIdentity();
10481        try {
10482            synchronized (this) {
10483                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10484                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10485                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10486                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10487                return visible;
10488            }
10489        } finally {
10490            Binder.restoreCallingIdentity(origId);
10491        }
10492    }
10493
10494    @Override
10495    public ActivityOptions getActivityOptions(IBinder token) {
10496        final long origId = Binder.clearCallingIdentity();
10497        try {
10498            synchronized (this) {
10499                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10500                if (r != null) {
10501                    final ActivityOptions activityOptions = r.pendingOptions;
10502                    r.pendingOptions = null;
10503                    return activityOptions;
10504                }
10505                return null;
10506            }
10507        } finally {
10508            Binder.restoreCallingIdentity(origId);
10509        }
10510    }
10511
10512    @Override
10513    public void setImmersive(IBinder token, boolean immersive) {
10514        synchronized(this) {
10515            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10516            if (r == null) {
10517                throw new IllegalArgumentException();
10518            }
10519            r.immersive = immersive;
10520
10521            // update associated state if we're frontmost
10522            if (r == mFocusedActivity) {
10523                if (DEBUG_IMMERSIVE) {
10524                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10525                }
10526                applyUpdateLockStateLocked(r);
10527            }
10528        }
10529    }
10530
10531    @Override
10532    public boolean isImmersive(IBinder token) {
10533        synchronized (this) {
10534            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10535            if (r == null) {
10536                throw new IllegalArgumentException();
10537            }
10538            return r.immersive;
10539        }
10540    }
10541
10542    public boolean isTopActivityImmersive() {
10543        enforceNotIsolatedCaller("startActivity");
10544        synchronized (this) {
10545            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10546            return (r != null) ? r.immersive : false;
10547        }
10548    }
10549
10550    @Override
10551    public boolean isTopOfTask(IBinder token) {
10552        synchronized (this) {
10553            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10554            if (r == null) {
10555                throw new IllegalArgumentException();
10556            }
10557            return r.task.getTopActivity() == r;
10558        }
10559    }
10560
10561    public final void enterSafeMode() {
10562        synchronized(this) {
10563            // It only makes sense to do this before the system is ready
10564            // and started launching other packages.
10565            if (!mSystemReady) {
10566                try {
10567                    AppGlobals.getPackageManager().enterSafeMode();
10568                } catch (RemoteException e) {
10569                }
10570            }
10571
10572            mSafeMode = true;
10573        }
10574    }
10575
10576    public final void showSafeModeOverlay() {
10577        View v = LayoutInflater.from(mContext).inflate(
10578                com.android.internal.R.layout.safe_mode, null);
10579        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10580        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10581        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10582        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10583        lp.gravity = Gravity.BOTTOM | Gravity.START;
10584        lp.format = v.getBackground().getOpacity();
10585        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10586                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10587        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10588        ((WindowManager)mContext.getSystemService(
10589                Context.WINDOW_SERVICE)).addView(v, lp);
10590    }
10591
10592    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10593        if (!(sender instanceof PendingIntentRecord)) {
10594            return;
10595        }
10596        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10597        synchronized (stats) {
10598            if (mBatteryStatsService.isOnBattery()) {
10599                mBatteryStatsService.enforceCallingPermission();
10600                PendingIntentRecord rec = (PendingIntentRecord)sender;
10601                int MY_UID = Binder.getCallingUid();
10602                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10603                BatteryStatsImpl.Uid.Pkg pkg =
10604                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10605                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10606                pkg.incWakeupsLocked();
10607            }
10608        }
10609    }
10610
10611    public boolean killPids(int[] pids, String pReason, boolean secure) {
10612        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10613            throw new SecurityException("killPids only available to the system");
10614        }
10615        String reason = (pReason == null) ? "Unknown" : pReason;
10616        // XXX Note: don't acquire main activity lock here, because the window
10617        // manager calls in with its locks held.
10618
10619        boolean killed = false;
10620        synchronized (mPidsSelfLocked) {
10621            int[] types = new int[pids.length];
10622            int worstType = 0;
10623            for (int i=0; i<pids.length; i++) {
10624                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10625                if (proc != null) {
10626                    int type = proc.setAdj;
10627                    types[i] = type;
10628                    if (type > worstType) {
10629                        worstType = type;
10630                    }
10631                }
10632            }
10633
10634            // If the worst oom_adj is somewhere in the cached proc LRU range,
10635            // then constrain it so we will kill all cached procs.
10636            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10637                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10638                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10639            }
10640
10641            // If this is not a secure call, don't let it kill processes that
10642            // are important.
10643            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10644                worstType = ProcessList.SERVICE_ADJ;
10645            }
10646
10647            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10648            for (int i=0; i<pids.length; i++) {
10649                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10650                if (proc == null) {
10651                    continue;
10652                }
10653                int adj = proc.setAdj;
10654                if (adj >= worstType && !proc.killedByAm) {
10655                    proc.kill(reason, true);
10656                    killed = true;
10657                }
10658            }
10659        }
10660        return killed;
10661    }
10662
10663    @Override
10664    public void killUid(int uid, String reason) {
10665        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10666            throw new SecurityException("killUid only available to the system");
10667        }
10668        synchronized (this) {
10669            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10670                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10671                    reason != null ? reason : "kill uid");
10672        }
10673    }
10674
10675    @Override
10676    public boolean killProcessesBelowForeground(String reason) {
10677        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10678            throw new SecurityException("killProcessesBelowForeground() only available to system");
10679        }
10680
10681        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10682    }
10683
10684    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10685        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10686            throw new SecurityException("killProcessesBelowAdj() only available to system");
10687        }
10688
10689        boolean killed = false;
10690        synchronized (mPidsSelfLocked) {
10691            final int size = mPidsSelfLocked.size();
10692            for (int i = 0; i < size; i++) {
10693                final int pid = mPidsSelfLocked.keyAt(i);
10694                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10695                if (proc == null) continue;
10696
10697                final int adj = proc.setAdj;
10698                if (adj > belowAdj && !proc.killedByAm) {
10699                    proc.kill(reason, true);
10700                    killed = true;
10701                }
10702            }
10703        }
10704        return killed;
10705    }
10706
10707    @Override
10708    public void hang(final IBinder who, boolean allowRestart) {
10709        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10710                != PackageManager.PERMISSION_GRANTED) {
10711            throw new SecurityException("Requires permission "
10712                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10713        }
10714
10715        final IBinder.DeathRecipient death = new DeathRecipient() {
10716            @Override
10717            public void binderDied() {
10718                synchronized (this) {
10719                    notifyAll();
10720                }
10721            }
10722        };
10723
10724        try {
10725            who.linkToDeath(death, 0);
10726        } catch (RemoteException e) {
10727            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10728            return;
10729        }
10730
10731        synchronized (this) {
10732            Watchdog.getInstance().setAllowRestart(allowRestart);
10733            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10734            synchronized (death) {
10735                while (who.isBinderAlive()) {
10736                    try {
10737                        death.wait();
10738                    } catch (InterruptedException e) {
10739                    }
10740                }
10741            }
10742            Watchdog.getInstance().setAllowRestart(true);
10743        }
10744    }
10745
10746    @Override
10747    public void restart() {
10748        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10749                != PackageManager.PERMISSION_GRANTED) {
10750            throw new SecurityException("Requires permission "
10751                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10752        }
10753
10754        Log.i(TAG, "Sending shutdown broadcast...");
10755
10756        BroadcastReceiver br = new BroadcastReceiver() {
10757            @Override public void onReceive(Context context, Intent intent) {
10758                // Now the broadcast is done, finish up the low-level shutdown.
10759                Log.i(TAG, "Shutting down activity manager...");
10760                shutdown(10000);
10761                Log.i(TAG, "Shutdown complete, restarting!");
10762                Process.killProcess(Process.myPid());
10763                System.exit(10);
10764            }
10765        };
10766
10767        // First send the high-level shut down broadcast.
10768        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10769        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10770        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10771        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10772        mContext.sendOrderedBroadcastAsUser(intent,
10773                UserHandle.ALL, null, br, mHandler, 0, null, null);
10774        */
10775        br.onReceive(mContext, intent);
10776    }
10777
10778    private long getLowRamTimeSinceIdle(long now) {
10779        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10780    }
10781
10782    @Override
10783    public void performIdleMaintenance() {
10784        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10785                != PackageManager.PERMISSION_GRANTED) {
10786            throw new SecurityException("Requires permission "
10787                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10788        }
10789
10790        synchronized (this) {
10791            final long now = SystemClock.uptimeMillis();
10792            final long timeSinceLastIdle = now - mLastIdleTime;
10793            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10794            mLastIdleTime = now;
10795            mLowRamTimeSinceLastIdle = 0;
10796            if (mLowRamStartTime != 0) {
10797                mLowRamStartTime = now;
10798            }
10799
10800            StringBuilder sb = new StringBuilder(128);
10801            sb.append("Idle maintenance over ");
10802            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10803            sb.append(" low RAM for ");
10804            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10805            Slog.i(TAG, sb.toString());
10806
10807            // If at least 1/3 of our time since the last idle period has been spent
10808            // with RAM low, then we want to kill processes.
10809            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10810
10811            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10812                ProcessRecord proc = mLruProcesses.get(i);
10813                if (proc.notCachedSinceIdle) {
10814                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10815                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10816                        if (doKilling && proc.initialIdlePss != 0
10817                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10818                            proc.kill("idle maint (pss " + proc.lastPss
10819                                    + " from " + proc.initialIdlePss + ")", true);
10820                        }
10821                    }
10822                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10823                    proc.notCachedSinceIdle = true;
10824                    proc.initialIdlePss = 0;
10825                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10826                            isSleeping(), now);
10827                }
10828            }
10829
10830            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10831            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10832        }
10833    }
10834
10835    private void retrieveSettings() {
10836        final ContentResolver resolver = mContext.getContentResolver();
10837        String debugApp = Settings.Global.getString(
10838            resolver, Settings.Global.DEBUG_APP);
10839        boolean waitForDebugger = Settings.Global.getInt(
10840            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10841        boolean alwaysFinishActivities = Settings.Global.getInt(
10842            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10843        boolean forceRtl = Settings.Global.getInt(
10844                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10845        // Transfer any global setting for forcing RTL layout, into a System Property
10846        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10847
10848        Configuration configuration = new Configuration();
10849        Settings.System.getConfiguration(resolver, configuration);
10850        if (forceRtl) {
10851            // This will take care of setting the correct layout direction flags
10852            configuration.setLayoutDirection(configuration.locale);
10853        }
10854
10855        synchronized (this) {
10856            mDebugApp = mOrigDebugApp = debugApp;
10857            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10858            mAlwaysFinishActivities = alwaysFinishActivities;
10859            // This happens before any activities are started, so we can
10860            // change mConfiguration in-place.
10861            updateConfigurationLocked(configuration, null, false, true);
10862            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10863        }
10864    }
10865
10866    /** Loads resources after the current configuration has been set. */
10867    private void loadResourcesOnSystemReady() {
10868        final Resources res = mContext.getResources();
10869        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10870        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10871        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10872    }
10873
10874    public boolean testIsSystemReady() {
10875        // no need to synchronize(this) just to read & return the value
10876        return mSystemReady;
10877    }
10878
10879    private static File getCalledPreBootReceiversFile() {
10880        File dataDir = Environment.getDataDirectory();
10881        File systemDir = new File(dataDir, "system");
10882        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10883        return fname;
10884    }
10885
10886    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10887        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10888        File file = getCalledPreBootReceiversFile();
10889        FileInputStream fis = null;
10890        try {
10891            fis = new FileInputStream(file);
10892            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10893            int fvers = dis.readInt();
10894            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10895                String vers = dis.readUTF();
10896                String codename = dis.readUTF();
10897                String build = dis.readUTF();
10898                if (android.os.Build.VERSION.RELEASE.equals(vers)
10899                        && android.os.Build.VERSION.CODENAME.equals(codename)
10900                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10901                    int num = dis.readInt();
10902                    while (num > 0) {
10903                        num--;
10904                        String pkg = dis.readUTF();
10905                        String cls = dis.readUTF();
10906                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10907                    }
10908                }
10909            }
10910        } catch (FileNotFoundException e) {
10911        } catch (IOException e) {
10912            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10913        } finally {
10914            if (fis != null) {
10915                try {
10916                    fis.close();
10917                } catch (IOException e) {
10918                }
10919            }
10920        }
10921        return lastDoneReceivers;
10922    }
10923
10924    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10925        File file = getCalledPreBootReceiversFile();
10926        FileOutputStream fos = null;
10927        DataOutputStream dos = null;
10928        try {
10929            fos = new FileOutputStream(file);
10930            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10931            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10932            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10933            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10934            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10935            dos.writeInt(list.size());
10936            for (int i=0; i<list.size(); i++) {
10937                dos.writeUTF(list.get(i).getPackageName());
10938                dos.writeUTF(list.get(i).getClassName());
10939            }
10940        } catch (IOException e) {
10941            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10942            file.delete();
10943        } finally {
10944            FileUtils.sync(fos);
10945            if (dos != null) {
10946                try {
10947                    dos.close();
10948                } catch (IOException e) {
10949                    // TODO Auto-generated catch block
10950                    e.printStackTrace();
10951                }
10952            }
10953        }
10954    }
10955
10956    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10957            ArrayList<ComponentName> doneReceivers, int userId) {
10958        boolean waitingUpdate = false;
10959        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10960        List<ResolveInfo> ris = null;
10961        try {
10962            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10963                    intent, null, 0, userId);
10964        } catch (RemoteException e) {
10965        }
10966        if (ris != null) {
10967            for (int i=ris.size()-1; i>=0; i--) {
10968                if ((ris.get(i).activityInfo.applicationInfo.flags
10969                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10970                    ris.remove(i);
10971                }
10972            }
10973            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10974
10975            // For User 0, load the version number. When delivering to a new user, deliver
10976            // to all receivers.
10977            if (userId == UserHandle.USER_OWNER) {
10978                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10979                for (int i=0; i<ris.size(); i++) {
10980                    ActivityInfo ai = ris.get(i).activityInfo;
10981                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10982                    if (lastDoneReceivers.contains(comp)) {
10983                        // We already did the pre boot receiver for this app with the current
10984                        // platform version, so don't do it again...
10985                        ris.remove(i);
10986                        i--;
10987                        // ...however, do keep it as one that has been done, so we don't
10988                        // forget about it when rewriting the file of last done receivers.
10989                        doneReceivers.add(comp);
10990                    }
10991                }
10992            }
10993
10994            // If primary user, send broadcast to all available users, else just to userId
10995            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10996                    : new int[] { userId };
10997            for (int i = 0; i < ris.size(); i++) {
10998                ActivityInfo ai = ris.get(i).activityInfo;
10999                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11000                doneReceivers.add(comp);
11001                intent.setComponent(comp);
11002                for (int j=0; j<users.length; j++) {
11003                    IIntentReceiver finisher = null;
11004                    // On last receiver and user, set up a completion callback
11005                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11006                        finisher = new IIntentReceiver.Stub() {
11007                            public void performReceive(Intent intent, int resultCode,
11008                                    String data, Bundle extras, boolean ordered,
11009                                    boolean sticky, int sendingUser) {
11010                                // The raw IIntentReceiver interface is called
11011                                // with the AM lock held, so redispatch to
11012                                // execute our code without the lock.
11013                                mHandler.post(onFinishCallback);
11014                            }
11015                        };
11016                    }
11017                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11018                            + " for user " + users[j]);
11019                    broadcastIntentLocked(null, null, intent, null, finisher,
11020                            0, null, null, null, AppOpsManager.OP_NONE,
11021                            true, false, MY_PID, Process.SYSTEM_UID,
11022                            users[j]);
11023                    if (finisher != null) {
11024                        waitingUpdate = true;
11025                    }
11026                }
11027            }
11028        }
11029
11030        return waitingUpdate;
11031    }
11032
11033    public void systemReady(final Runnable goingCallback) {
11034        synchronized(this) {
11035            if (mSystemReady) {
11036                // If we're done calling all the receivers, run the next "boot phase" passed in
11037                // by the SystemServer
11038                if (goingCallback != null) {
11039                    goingCallback.run();
11040                }
11041                return;
11042            }
11043
11044            // Make sure we have the current profile info, since it is needed for
11045            // security checks.
11046            updateCurrentProfileIdsLocked();
11047
11048            if (mRecentTasks == null) {
11049                mRecentTasks = mTaskPersister.restoreTasksLocked();
11050                if (!mRecentTasks.isEmpty()) {
11051                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11052                }
11053                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11054                mTaskPersister.startPersisting();
11055            }
11056
11057            // Check to see if there are any update receivers to run.
11058            if (!mDidUpdate) {
11059                if (mWaitingUpdate) {
11060                    return;
11061                }
11062                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11063                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11064                    public void run() {
11065                        synchronized (ActivityManagerService.this) {
11066                            mDidUpdate = true;
11067                        }
11068                        writeLastDonePreBootReceivers(doneReceivers);
11069                        showBootMessage(mContext.getText(
11070                                R.string.android_upgrading_complete),
11071                                false);
11072                        systemReady(goingCallback);
11073                    }
11074                }, doneReceivers, UserHandle.USER_OWNER);
11075
11076                if (mWaitingUpdate) {
11077                    return;
11078                }
11079                mDidUpdate = true;
11080            }
11081
11082            mAppOpsService.systemReady();
11083            mSystemReady = true;
11084        }
11085
11086        ArrayList<ProcessRecord> procsToKill = null;
11087        synchronized(mPidsSelfLocked) {
11088            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11089                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11090                if (!isAllowedWhileBooting(proc.info)){
11091                    if (procsToKill == null) {
11092                        procsToKill = new ArrayList<ProcessRecord>();
11093                    }
11094                    procsToKill.add(proc);
11095                }
11096            }
11097        }
11098
11099        synchronized(this) {
11100            if (procsToKill != null) {
11101                for (int i=procsToKill.size()-1; i>=0; i--) {
11102                    ProcessRecord proc = procsToKill.get(i);
11103                    Slog.i(TAG, "Removing system update proc: " + proc);
11104                    removeProcessLocked(proc, true, false, "system update done");
11105                }
11106            }
11107
11108            // Now that we have cleaned up any update processes, we
11109            // are ready to start launching real processes and know that
11110            // we won't trample on them any more.
11111            mProcessesReady = true;
11112        }
11113
11114        Slog.i(TAG, "System now ready");
11115        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11116            SystemClock.uptimeMillis());
11117
11118        synchronized(this) {
11119            // Make sure we have no pre-ready processes sitting around.
11120
11121            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11122                ResolveInfo ri = mContext.getPackageManager()
11123                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11124                                STOCK_PM_FLAGS);
11125                CharSequence errorMsg = null;
11126                if (ri != null) {
11127                    ActivityInfo ai = ri.activityInfo;
11128                    ApplicationInfo app = ai.applicationInfo;
11129                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11130                        mTopAction = Intent.ACTION_FACTORY_TEST;
11131                        mTopData = null;
11132                        mTopComponent = new ComponentName(app.packageName,
11133                                ai.name);
11134                    } else {
11135                        errorMsg = mContext.getResources().getText(
11136                                com.android.internal.R.string.factorytest_not_system);
11137                    }
11138                } else {
11139                    errorMsg = mContext.getResources().getText(
11140                            com.android.internal.R.string.factorytest_no_action);
11141                }
11142                if (errorMsg != null) {
11143                    mTopAction = null;
11144                    mTopData = null;
11145                    mTopComponent = null;
11146                    Message msg = Message.obtain();
11147                    msg.what = SHOW_FACTORY_ERROR_MSG;
11148                    msg.getData().putCharSequence("msg", errorMsg);
11149                    mHandler.sendMessage(msg);
11150                }
11151            }
11152        }
11153
11154        retrieveSettings();
11155        loadResourcesOnSystemReady();
11156
11157        synchronized (this) {
11158            readGrantedUriPermissionsLocked();
11159        }
11160
11161        if (goingCallback != null) goingCallback.run();
11162
11163        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11164                Integer.toString(mCurrentUserId), mCurrentUserId);
11165        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11166                Integer.toString(mCurrentUserId), mCurrentUserId);
11167        mSystemServiceManager.startUser(mCurrentUserId);
11168
11169        synchronized (this) {
11170            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11171                try {
11172                    List apps = AppGlobals.getPackageManager().
11173                        getPersistentApplications(STOCK_PM_FLAGS);
11174                    if (apps != null) {
11175                        int N = apps.size();
11176                        int i;
11177                        for (i=0; i<N; i++) {
11178                            ApplicationInfo info
11179                                = (ApplicationInfo)apps.get(i);
11180                            if (info != null &&
11181                                    !info.packageName.equals("android")) {
11182                                addAppLocked(info, false, null /* ABI override */);
11183                            }
11184                        }
11185                    }
11186                } catch (RemoteException ex) {
11187                    // pm is in same process, this will never happen.
11188                }
11189            }
11190
11191            // Start up initial activity.
11192            mBooting = true;
11193            startHomeActivityLocked(mCurrentUserId);
11194
11195            try {
11196                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11197                    Message msg = Message.obtain();
11198                    msg.what = SHOW_UID_ERROR_MSG;
11199                    mHandler.sendMessage(msg);
11200                }
11201            } catch (RemoteException e) {
11202            }
11203
11204            long ident = Binder.clearCallingIdentity();
11205            try {
11206                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11207                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11208                        | Intent.FLAG_RECEIVER_FOREGROUND);
11209                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11210                broadcastIntentLocked(null, null, intent,
11211                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11212                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11213                intent = new Intent(Intent.ACTION_USER_STARTING);
11214                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11215                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11216                broadcastIntentLocked(null, null, intent,
11217                        null, new IIntentReceiver.Stub() {
11218                            @Override
11219                            public void performReceive(Intent intent, int resultCode, String data,
11220                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11221                                    throws RemoteException {
11222                            }
11223                        }, 0, null, null,
11224                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11225                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11226            } catch (Throwable t) {
11227                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11228            } finally {
11229                Binder.restoreCallingIdentity(ident);
11230            }
11231            mStackSupervisor.resumeTopActivitiesLocked();
11232            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11233        }
11234    }
11235
11236    private boolean makeAppCrashingLocked(ProcessRecord app,
11237            String shortMsg, String longMsg, String stackTrace) {
11238        app.crashing = true;
11239        app.crashingReport = generateProcessError(app,
11240                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11241        startAppProblemLocked(app);
11242        app.stopFreezingAllLocked();
11243        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11244    }
11245
11246    private void makeAppNotRespondingLocked(ProcessRecord app,
11247            String activity, String shortMsg, String longMsg) {
11248        app.notResponding = true;
11249        app.notRespondingReport = generateProcessError(app,
11250                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11251                activity, shortMsg, longMsg, null);
11252        startAppProblemLocked(app);
11253        app.stopFreezingAllLocked();
11254    }
11255
11256    /**
11257     * Generate a process error record, suitable for attachment to a ProcessRecord.
11258     *
11259     * @param app The ProcessRecord in which the error occurred.
11260     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11261     *                      ActivityManager.AppErrorStateInfo
11262     * @param activity The activity associated with the crash, if known.
11263     * @param shortMsg Short message describing the crash.
11264     * @param longMsg Long message describing the crash.
11265     * @param stackTrace Full crash stack trace, may be null.
11266     *
11267     * @return Returns a fully-formed AppErrorStateInfo record.
11268     */
11269    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11270            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11271        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11272
11273        report.condition = condition;
11274        report.processName = app.processName;
11275        report.pid = app.pid;
11276        report.uid = app.info.uid;
11277        report.tag = activity;
11278        report.shortMsg = shortMsg;
11279        report.longMsg = longMsg;
11280        report.stackTrace = stackTrace;
11281
11282        return report;
11283    }
11284
11285    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11286        synchronized (this) {
11287            app.crashing = false;
11288            app.crashingReport = null;
11289            app.notResponding = false;
11290            app.notRespondingReport = null;
11291            if (app.anrDialog == fromDialog) {
11292                app.anrDialog = null;
11293            }
11294            if (app.waitDialog == fromDialog) {
11295                app.waitDialog = null;
11296            }
11297            if (app.pid > 0 && app.pid != MY_PID) {
11298                handleAppCrashLocked(app, null, null, null);
11299                app.kill("user request after error", true);
11300            }
11301        }
11302    }
11303
11304    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11305            String stackTrace) {
11306        long now = SystemClock.uptimeMillis();
11307
11308        Long crashTime;
11309        if (!app.isolated) {
11310            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11311        } else {
11312            crashTime = null;
11313        }
11314        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11315            // This process loses!
11316            Slog.w(TAG, "Process " + app.info.processName
11317                    + " has crashed too many times: killing!");
11318            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11319                    app.userId, app.info.processName, app.uid);
11320            mStackSupervisor.handleAppCrashLocked(app);
11321            if (!app.persistent) {
11322                // We don't want to start this process again until the user
11323                // explicitly does so...  but for persistent process, we really
11324                // need to keep it running.  If a persistent process is actually
11325                // repeatedly crashing, then badness for everyone.
11326                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11327                        app.info.processName);
11328                if (!app.isolated) {
11329                    // XXX We don't have a way to mark isolated processes
11330                    // as bad, since they don't have a peristent identity.
11331                    mBadProcesses.put(app.info.processName, app.uid,
11332                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11333                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11334                }
11335                app.bad = true;
11336                app.removed = true;
11337                // Don't let services in this process be restarted and potentially
11338                // annoy the user repeatedly.  Unless it is persistent, since those
11339                // processes run critical code.
11340                removeProcessLocked(app, false, false, "crash");
11341                mStackSupervisor.resumeTopActivitiesLocked();
11342                return false;
11343            }
11344            mStackSupervisor.resumeTopActivitiesLocked();
11345        } else {
11346            mStackSupervisor.finishTopRunningActivityLocked(app);
11347        }
11348
11349        // Bump up the crash count of any services currently running in the proc.
11350        for (int i=app.services.size()-1; i>=0; i--) {
11351            // Any services running in the application need to be placed
11352            // back in the pending list.
11353            ServiceRecord sr = app.services.valueAt(i);
11354            sr.crashCount++;
11355        }
11356
11357        // If the crashing process is what we consider to be the "home process" and it has been
11358        // replaced by a third-party app, clear the package preferred activities from packages
11359        // with a home activity running in the process to prevent a repeatedly crashing app
11360        // from blocking the user to manually clear the list.
11361        final ArrayList<ActivityRecord> activities = app.activities;
11362        if (app == mHomeProcess && activities.size() > 0
11363                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11364            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11365                final ActivityRecord r = activities.get(activityNdx);
11366                if (r.isHomeActivity()) {
11367                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11368                    try {
11369                        ActivityThread.getPackageManager()
11370                                .clearPackagePreferredActivities(r.packageName);
11371                    } catch (RemoteException c) {
11372                        // pm is in same process, this will never happen.
11373                    }
11374                }
11375            }
11376        }
11377
11378        if (!app.isolated) {
11379            // XXX Can't keep track of crash times for isolated processes,
11380            // because they don't have a perisistent identity.
11381            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11382        }
11383
11384        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11385        return true;
11386    }
11387
11388    void startAppProblemLocked(ProcessRecord app) {
11389        // If this app is not running under the current user, then we
11390        // can't give it a report button because that would require
11391        // launching the report UI under a different user.
11392        app.errorReportReceiver = null;
11393
11394        for (int userId : mCurrentProfileIds) {
11395            if (app.userId == userId) {
11396                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11397                        mContext, app.info.packageName, app.info.flags);
11398            }
11399        }
11400        skipCurrentReceiverLocked(app);
11401    }
11402
11403    void skipCurrentReceiverLocked(ProcessRecord app) {
11404        for (BroadcastQueue queue : mBroadcastQueues) {
11405            queue.skipCurrentReceiverLocked(app);
11406        }
11407    }
11408
11409    /**
11410     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11411     * The application process will exit immediately after this call returns.
11412     * @param app object of the crashing app, null for the system server
11413     * @param crashInfo describing the exception
11414     */
11415    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11416        ProcessRecord r = findAppProcess(app, "Crash");
11417        final String processName = app == null ? "system_server"
11418                : (r == null ? "unknown" : r.processName);
11419
11420        handleApplicationCrashInner("crash", r, processName, crashInfo);
11421    }
11422
11423    /* Native crash reporting uses this inner version because it needs to be somewhat
11424     * decoupled from the AM-managed cleanup lifecycle
11425     */
11426    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11427            ApplicationErrorReport.CrashInfo crashInfo) {
11428        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11429                UserHandle.getUserId(Binder.getCallingUid()), processName,
11430                r == null ? -1 : r.info.flags,
11431                crashInfo.exceptionClassName,
11432                crashInfo.exceptionMessage,
11433                crashInfo.throwFileName,
11434                crashInfo.throwLineNumber);
11435
11436        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11437
11438        crashApplication(r, crashInfo);
11439    }
11440
11441    public void handleApplicationStrictModeViolation(
11442            IBinder app,
11443            int violationMask,
11444            StrictMode.ViolationInfo info) {
11445        ProcessRecord r = findAppProcess(app, "StrictMode");
11446        if (r == null) {
11447            return;
11448        }
11449
11450        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11451            Integer stackFingerprint = info.hashCode();
11452            boolean logIt = true;
11453            synchronized (mAlreadyLoggedViolatedStacks) {
11454                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11455                    logIt = false;
11456                    // TODO: sub-sample into EventLog for these, with
11457                    // the info.durationMillis?  Then we'd get
11458                    // the relative pain numbers, without logging all
11459                    // the stack traces repeatedly.  We'd want to do
11460                    // likewise in the client code, which also does
11461                    // dup suppression, before the Binder call.
11462                } else {
11463                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11464                        mAlreadyLoggedViolatedStacks.clear();
11465                    }
11466                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11467                }
11468            }
11469            if (logIt) {
11470                logStrictModeViolationToDropBox(r, info);
11471            }
11472        }
11473
11474        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11475            AppErrorResult result = new AppErrorResult();
11476            synchronized (this) {
11477                final long origId = Binder.clearCallingIdentity();
11478
11479                Message msg = Message.obtain();
11480                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11481                HashMap<String, Object> data = new HashMap<String, Object>();
11482                data.put("result", result);
11483                data.put("app", r);
11484                data.put("violationMask", violationMask);
11485                data.put("info", info);
11486                msg.obj = data;
11487                mHandler.sendMessage(msg);
11488
11489                Binder.restoreCallingIdentity(origId);
11490            }
11491            int res = result.get();
11492            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11493        }
11494    }
11495
11496    // Depending on the policy in effect, there could be a bunch of
11497    // these in quick succession so we try to batch these together to
11498    // minimize disk writes, number of dropbox entries, and maximize
11499    // compression, by having more fewer, larger records.
11500    private void logStrictModeViolationToDropBox(
11501            ProcessRecord process,
11502            StrictMode.ViolationInfo info) {
11503        if (info == null) {
11504            return;
11505        }
11506        final boolean isSystemApp = process == null ||
11507                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11508                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11509        final String processName = process == null ? "unknown" : process.processName;
11510        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11511        final DropBoxManager dbox = (DropBoxManager)
11512                mContext.getSystemService(Context.DROPBOX_SERVICE);
11513
11514        // Exit early if the dropbox isn't configured to accept this report type.
11515        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11516
11517        boolean bufferWasEmpty;
11518        boolean needsFlush;
11519        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11520        synchronized (sb) {
11521            bufferWasEmpty = sb.length() == 0;
11522            appendDropBoxProcessHeaders(process, processName, sb);
11523            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11524            sb.append("System-App: ").append(isSystemApp).append("\n");
11525            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11526            if (info.violationNumThisLoop != 0) {
11527                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11528            }
11529            if (info.numAnimationsRunning != 0) {
11530                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11531            }
11532            if (info.broadcastIntentAction != null) {
11533                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11534            }
11535            if (info.durationMillis != -1) {
11536                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11537            }
11538            if (info.numInstances != -1) {
11539                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11540            }
11541            if (info.tags != null) {
11542                for (String tag : info.tags) {
11543                    sb.append("Span-Tag: ").append(tag).append("\n");
11544                }
11545            }
11546            sb.append("\n");
11547            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11548                sb.append(info.crashInfo.stackTrace);
11549            }
11550            sb.append("\n");
11551
11552            // Only buffer up to ~64k.  Various logging bits truncate
11553            // things at 128k.
11554            needsFlush = (sb.length() > 64 * 1024);
11555        }
11556
11557        // Flush immediately if the buffer's grown too large, or this
11558        // is a non-system app.  Non-system apps are isolated with a
11559        // different tag & policy and not batched.
11560        //
11561        // Batching is useful during internal testing with
11562        // StrictMode settings turned up high.  Without batching,
11563        // thousands of separate files could be created on boot.
11564        if (!isSystemApp || needsFlush) {
11565            new Thread("Error dump: " + dropboxTag) {
11566                @Override
11567                public void run() {
11568                    String report;
11569                    synchronized (sb) {
11570                        report = sb.toString();
11571                        sb.delete(0, sb.length());
11572                        sb.trimToSize();
11573                    }
11574                    if (report.length() != 0) {
11575                        dbox.addText(dropboxTag, report);
11576                    }
11577                }
11578            }.start();
11579            return;
11580        }
11581
11582        // System app batching:
11583        if (!bufferWasEmpty) {
11584            // An existing dropbox-writing thread is outstanding, so
11585            // we don't need to start it up.  The existing thread will
11586            // catch the buffer appends we just did.
11587            return;
11588        }
11589
11590        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11591        // (After this point, we shouldn't access AMS internal data structures.)
11592        new Thread("Error dump: " + dropboxTag) {
11593            @Override
11594            public void run() {
11595                // 5 second sleep to let stacks arrive and be batched together
11596                try {
11597                    Thread.sleep(5000);  // 5 seconds
11598                } catch (InterruptedException e) {}
11599
11600                String errorReport;
11601                synchronized (mStrictModeBuffer) {
11602                    errorReport = mStrictModeBuffer.toString();
11603                    if (errorReport.length() == 0) {
11604                        return;
11605                    }
11606                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11607                    mStrictModeBuffer.trimToSize();
11608                }
11609                dbox.addText(dropboxTag, errorReport);
11610            }
11611        }.start();
11612    }
11613
11614    /**
11615     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11616     * @param app object of the crashing app, null for the system server
11617     * @param tag reported by the caller
11618     * @param system whether this wtf is coming from the system
11619     * @param crashInfo describing the context of the error
11620     * @return true if the process should exit immediately (WTF is fatal)
11621     */
11622    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11623            final ApplicationErrorReport.CrashInfo crashInfo) {
11624        final int callingUid = Binder.getCallingUid();
11625        final int callingPid = Binder.getCallingPid();
11626
11627        if (system) {
11628            // If this is coming from the system, we could very well have low-level
11629            // system locks held, so we want to do this all asynchronously.  And we
11630            // never want this to become fatal, so there is that too.
11631            mHandler.post(new Runnable() {
11632                @Override public void run() {
11633                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11634                }
11635            });
11636            return false;
11637        }
11638
11639        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11640                crashInfo);
11641
11642        if (r != null && r.pid != Process.myPid() &&
11643                Settings.Global.getInt(mContext.getContentResolver(),
11644                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11645            crashApplication(r, crashInfo);
11646            return true;
11647        } else {
11648            return false;
11649        }
11650    }
11651
11652    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11653            final ApplicationErrorReport.CrashInfo crashInfo) {
11654        final ProcessRecord r = findAppProcess(app, "WTF");
11655        final String processName = app == null ? "system_server"
11656                : (r == null ? "unknown" : r.processName);
11657
11658        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11659                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11660
11661        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11662
11663        return r;
11664    }
11665
11666    /**
11667     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11668     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11669     */
11670    private ProcessRecord findAppProcess(IBinder app, String reason) {
11671        if (app == null) {
11672            return null;
11673        }
11674
11675        synchronized (this) {
11676            final int NP = mProcessNames.getMap().size();
11677            for (int ip=0; ip<NP; ip++) {
11678                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11679                final int NA = apps.size();
11680                for (int ia=0; ia<NA; ia++) {
11681                    ProcessRecord p = apps.valueAt(ia);
11682                    if (p.thread != null && p.thread.asBinder() == app) {
11683                        return p;
11684                    }
11685                }
11686            }
11687
11688            Slog.w(TAG, "Can't find mystery application for " + reason
11689                    + " from pid=" + Binder.getCallingPid()
11690                    + " uid=" + Binder.getCallingUid() + ": " + app);
11691            return null;
11692        }
11693    }
11694
11695    /**
11696     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11697     * to append various headers to the dropbox log text.
11698     */
11699    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11700            StringBuilder sb) {
11701        // Watchdog thread ends up invoking this function (with
11702        // a null ProcessRecord) to add the stack file to dropbox.
11703        // Do not acquire a lock on this (am) in such cases, as it
11704        // could cause a potential deadlock, if and when watchdog
11705        // is invoked due to unavailability of lock on am and it
11706        // would prevent watchdog from killing system_server.
11707        if (process == null) {
11708            sb.append("Process: ").append(processName).append("\n");
11709            return;
11710        }
11711        // Note: ProcessRecord 'process' is guarded by the service
11712        // instance.  (notably process.pkgList, which could otherwise change
11713        // concurrently during execution of this method)
11714        synchronized (this) {
11715            sb.append("Process: ").append(processName).append("\n");
11716            int flags = process.info.flags;
11717            IPackageManager pm = AppGlobals.getPackageManager();
11718            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11719            for (int ip=0; ip<process.pkgList.size(); ip++) {
11720                String pkg = process.pkgList.keyAt(ip);
11721                sb.append("Package: ").append(pkg);
11722                try {
11723                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11724                    if (pi != null) {
11725                        sb.append(" v").append(pi.versionCode);
11726                        if (pi.versionName != null) {
11727                            sb.append(" (").append(pi.versionName).append(")");
11728                        }
11729                    }
11730                } catch (RemoteException e) {
11731                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11732                }
11733                sb.append("\n");
11734            }
11735        }
11736    }
11737
11738    private static String processClass(ProcessRecord process) {
11739        if (process == null || process.pid == MY_PID) {
11740            return "system_server";
11741        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11742            return "system_app";
11743        } else {
11744            return "data_app";
11745        }
11746    }
11747
11748    /**
11749     * Write a description of an error (crash, WTF, ANR) to the drop box.
11750     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11751     * @param process which caused the error, null means the system server
11752     * @param activity which triggered the error, null if unknown
11753     * @param parent activity related to the error, null if unknown
11754     * @param subject line related to the error, null if absent
11755     * @param report in long form describing the error, null if absent
11756     * @param logFile to include in the report, null if none
11757     * @param crashInfo giving an application stack trace, null if absent
11758     */
11759    public void addErrorToDropBox(String eventType,
11760            ProcessRecord process, String processName, ActivityRecord activity,
11761            ActivityRecord parent, String subject,
11762            final String report, final File logFile,
11763            final ApplicationErrorReport.CrashInfo crashInfo) {
11764        // NOTE -- this must never acquire the ActivityManagerService lock,
11765        // otherwise the watchdog may be prevented from resetting the system.
11766
11767        final String dropboxTag = processClass(process) + "_" + eventType;
11768        final DropBoxManager dbox = (DropBoxManager)
11769                mContext.getSystemService(Context.DROPBOX_SERVICE);
11770
11771        // Exit early if the dropbox isn't configured to accept this report type.
11772        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11773
11774        final StringBuilder sb = new StringBuilder(1024);
11775        appendDropBoxProcessHeaders(process, processName, sb);
11776        if (activity != null) {
11777            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11778        }
11779        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11780            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11781        }
11782        if (parent != null && parent != activity) {
11783            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11784        }
11785        if (subject != null) {
11786            sb.append("Subject: ").append(subject).append("\n");
11787        }
11788        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11789        if (Debug.isDebuggerConnected()) {
11790            sb.append("Debugger: Connected\n");
11791        }
11792        sb.append("\n");
11793
11794        // Do the rest in a worker thread to avoid blocking the caller on I/O
11795        // (After this point, we shouldn't access AMS internal data structures.)
11796        Thread worker = new Thread("Error dump: " + dropboxTag) {
11797            @Override
11798            public void run() {
11799                if (report != null) {
11800                    sb.append(report);
11801                }
11802                if (logFile != null) {
11803                    try {
11804                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11805                                    "\n\n[[TRUNCATED]]"));
11806                    } catch (IOException e) {
11807                        Slog.e(TAG, "Error reading " + logFile, e);
11808                    }
11809                }
11810                if (crashInfo != null && crashInfo.stackTrace != null) {
11811                    sb.append(crashInfo.stackTrace);
11812                }
11813
11814                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11815                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11816                if (lines > 0) {
11817                    sb.append("\n");
11818
11819                    // Merge several logcat streams, and take the last N lines
11820                    InputStreamReader input = null;
11821                    try {
11822                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11823                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11824                                "-b", "crash",
11825                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11826
11827                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11828                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11829                        input = new InputStreamReader(logcat.getInputStream());
11830
11831                        int num;
11832                        char[] buf = new char[8192];
11833                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11834                    } catch (IOException e) {
11835                        Slog.e(TAG, "Error running logcat", e);
11836                    } finally {
11837                        if (input != null) try { input.close(); } catch (IOException e) {}
11838                    }
11839                }
11840
11841                dbox.addText(dropboxTag, sb.toString());
11842            }
11843        };
11844
11845        if (process == null) {
11846            // If process is null, we are being called from some internal code
11847            // and may be about to die -- run this synchronously.
11848            worker.run();
11849        } else {
11850            worker.start();
11851        }
11852    }
11853
11854    /**
11855     * Bring up the "unexpected error" dialog box for a crashing app.
11856     * Deal with edge cases (intercepts from instrumented applications,
11857     * ActivityController, error intent receivers, that sort of thing).
11858     * @param r the application crashing
11859     * @param crashInfo describing the failure
11860     */
11861    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11862        long timeMillis = System.currentTimeMillis();
11863        String shortMsg = crashInfo.exceptionClassName;
11864        String longMsg = crashInfo.exceptionMessage;
11865        String stackTrace = crashInfo.stackTrace;
11866        if (shortMsg != null && longMsg != null) {
11867            longMsg = shortMsg + ": " + longMsg;
11868        } else if (shortMsg != null) {
11869            longMsg = shortMsg;
11870        }
11871
11872        AppErrorResult result = new AppErrorResult();
11873        synchronized (this) {
11874            if (mController != null) {
11875                try {
11876                    String name = r != null ? r.processName : null;
11877                    int pid = r != null ? r.pid : Binder.getCallingPid();
11878                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11879                    if (!mController.appCrashed(name, pid,
11880                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11881                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11882                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11883                            Slog.w(TAG, "Skip killing native crashed app " + name
11884                                    + "(" + pid + ") during testing");
11885                        } else {
11886                            Slog.w(TAG, "Force-killing crashed app " + name
11887                                    + " at watcher's request");
11888                            if (r != null) {
11889                                r.kill("crash", true);
11890                            } else {
11891                                // Huh.
11892                                Process.killProcess(pid);
11893                                Process.killProcessGroup(uid, pid);
11894                            }
11895                        }
11896                        return;
11897                    }
11898                } catch (RemoteException e) {
11899                    mController = null;
11900                    Watchdog.getInstance().setActivityController(null);
11901                }
11902            }
11903
11904            final long origId = Binder.clearCallingIdentity();
11905
11906            // If this process is running instrumentation, finish it.
11907            if (r != null && r.instrumentationClass != null) {
11908                Slog.w(TAG, "Error in app " + r.processName
11909                      + " running instrumentation " + r.instrumentationClass + ":");
11910                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11911                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11912                Bundle info = new Bundle();
11913                info.putString("shortMsg", shortMsg);
11914                info.putString("longMsg", longMsg);
11915                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11916                Binder.restoreCallingIdentity(origId);
11917                return;
11918            }
11919
11920            // If we can't identify the process or it's already exceeded its crash quota,
11921            // quit right away without showing a crash dialog.
11922            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11923                Binder.restoreCallingIdentity(origId);
11924                return;
11925            }
11926
11927            Message msg = Message.obtain();
11928            msg.what = SHOW_ERROR_MSG;
11929            HashMap data = new HashMap();
11930            data.put("result", result);
11931            data.put("app", r);
11932            msg.obj = data;
11933            mHandler.sendMessage(msg);
11934
11935            Binder.restoreCallingIdentity(origId);
11936        }
11937
11938        int res = result.get();
11939
11940        Intent appErrorIntent = null;
11941        synchronized (this) {
11942            if (r != null && !r.isolated) {
11943                // XXX Can't keep track of crash time for isolated processes,
11944                // since they don't have a persistent identity.
11945                mProcessCrashTimes.put(r.info.processName, r.uid,
11946                        SystemClock.uptimeMillis());
11947            }
11948            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11949                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11950            }
11951        }
11952
11953        if (appErrorIntent != null) {
11954            try {
11955                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11956            } catch (ActivityNotFoundException e) {
11957                Slog.w(TAG, "bug report receiver dissappeared", e);
11958            }
11959        }
11960    }
11961
11962    Intent createAppErrorIntentLocked(ProcessRecord r,
11963            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11964        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11965        if (report == null) {
11966            return null;
11967        }
11968        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11969        result.setComponent(r.errorReportReceiver);
11970        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11971        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11972        return result;
11973    }
11974
11975    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11976            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11977        if (r.errorReportReceiver == null) {
11978            return null;
11979        }
11980
11981        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11982            return null;
11983        }
11984
11985        ApplicationErrorReport report = new ApplicationErrorReport();
11986        report.packageName = r.info.packageName;
11987        report.installerPackageName = r.errorReportReceiver.getPackageName();
11988        report.processName = r.processName;
11989        report.time = timeMillis;
11990        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11991
11992        if (r.crashing || r.forceCrashReport) {
11993            report.type = ApplicationErrorReport.TYPE_CRASH;
11994            report.crashInfo = crashInfo;
11995        } else if (r.notResponding) {
11996            report.type = ApplicationErrorReport.TYPE_ANR;
11997            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11998
11999            report.anrInfo.activity = r.notRespondingReport.tag;
12000            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12001            report.anrInfo.info = r.notRespondingReport.longMsg;
12002        }
12003
12004        return report;
12005    }
12006
12007    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12008        enforceNotIsolatedCaller("getProcessesInErrorState");
12009        // assume our apps are happy - lazy create the list
12010        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12011
12012        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12013                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12014        int userId = UserHandle.getUserId(Binder.getCallingUid());
12015
12016        synchronized (this) {
12017
12018            // iterate across all processes
12019            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12020                ProcessRecord app = mLruProcesses.get(i);
12021                if (!allUsers && app.userId != userId) {
12022                    continue;
12023                }
12024                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12025                    // This one's in trouble, so we'll generate a report for it
12026                    // crashes are higher priority (in case there's a crash *and* an anr)
12027                    ActivityManager.ProcessErrorStateInfo report = null;
12028                    if (app.crashing) {
12029                        report = app.crashingReport;
12030                    } else if (app.notResponding) {
12031                        report = app.notRespondingReport;
12032                    }
12033
12034                    if (report != null) {
12035                        if (errList == null) {
12036                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12037                        }
12038                        errList.add(report);
12039                    } else {
12040                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12041                                " crashing = " + app.crashing +
12042                                " notResponding = " + app.notResponding);
12043                    }
12044                }
12045            }
12046        }
12047
12048        return errList;
12049    }
12050
12051    static int procStateToImportance(int procState, int memAdj,
12052            ActivityManager.RunningAppProcessInfo currApp) {
12053        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12054        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12055            currApp.lru = memAdj;
12056        } else {
12057            currApp.lru = 0;
12058        }
12059        return imp;
12060    }
12061
12062    private void fillInProcMemInfo(ProcessRecord app,
12063            ActivityManager.RunningAppProcessInfo outInfo) {
12064        outInfo.pid = app.pid;
12065        outInfo.uid = app.info.uid;
12066        if (mHeavyWeightProcess == app) {
12067            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12068        }
12069        if (app.persistent) {
12070            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12071        }
12072        if (app.activities.size() > 0) {
12073            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12074        }
12075        outInfo.lastTrimLevel = app.trimMemoryLevel;
12076        int adj = app.curAdj;
12077        int procState = app.curProcState;
12078        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12079        outInfo.importanceReasonCode = app.adjTypeCode;
12080        outInfo.processState = app.curProcState;
12081    }
12082
12083    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12084        enforceNotIsolatedCaller("getRunningAppProcesses");
12085        // Lazy instantiation of list
12086        List<ActivityManager.RunningAppProcessInfo> runList = null;
12087        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12088                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12089        int userId = UserHandle.getUserId(Binder.getCallingUid());
12090        synchronized (this) {
12091            // Iterate across all processes
12092            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12093                ProcessRecord app = mLruProcesses.get(i);
12094                if (!allUsers && app.userId != userId) {
12095                    continue;
12096                }
12097                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12098                    // Generate process state info for running application
12099                    ActivityManager.RunningAppProcessInfo currApp =
12100                        new ActivityManager.RunningAppProcessInfo(app.processName,
12101                                app.pid, app.getPackageList());
12102                    fillInProcMemInfo(app, currApp);
12103                    if (app.adjSource instanceof ProcessRecord) {
12104                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12105                        currApp.importanceReasonImportance =
12106                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12107                                        app.adjSourceProcState);
12108                    } else if (app.adjSource instanceof ActivityRecord) {
12109                        ActivityRecord r = (ActivityRecord)app.adjSource;
12110                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12111                    }
12112                    if (app.adjTarget instanceof ComponentName) {
12113                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12114                    }
12115                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12116                    //        + " lru=" + currApp.lru);
12117                    if (runList == null) {
12118                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12119                    }
12120                    runList.add(currApp);
12121                }
12122            }
12123        }
12124        return runList;
12125    }
12126
12127    public List<ApplicationInfo> getRunningExternalApplications() {
12128        enforceNotIsolatedCaller("getRunningExternalApplications");
12129        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12130        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12131        if (runningApps != null && runningApps.size() > 0) {
12132            Set<String> extList = new HashSet<String>();
12133            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12134                if (app.pkgList != null) {
12135                    for (String pkg : app.pkgList) {
12136                        extList.add(pkg);
12137                    }
12138                }
12139            }
12140            IPackageManager pm = AppGlobals.getPackageManager();
12141            for (String pkg : extList) {
12142                try {
12143                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12144                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12145                        retList.add(info);
12146                    }
12147                } catch (RemoteException e) {
12148                }
12149            }
12150        }
12151        return retList;
12152    }
12153
12154    @Override
12155    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12156        enforceNotIsolatedCaller("getMyMemoryState");
12157        synchronized (this) {
12158            ProcessRecord proc;
12159            synchronized (mPidsSelfLocked) {
12160                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12161            }
12162            fillInProcMemInfo(proc, outInfo);
12163        }
12164    }
12165
12166    @Override
12167    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12168        if (checkCallingPermission(android.Manifest.permission.DUMP)
12169                != PackageManager.PERMISSION_GRANTED) {
12170            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12171                    + Binder.getCallingPid()
12172                    + ", uid=" + Binder.getCallingUid()
12173                    + " without permission "
12174                    + android.Manifest.permission.DUMP);
12175            return;
12176        }
12177
12178        boolean dumpAll = false;
12179        boolean dumpClient = false;
12180        String dumpPackage = null;
12181
12182        int opti = 0;
12183        while (opti < args.length) {
12184            String opt = args[opti];
12185            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12186                break;
12187            }
12188            opti++;
12189            if ("-a".equals(opt)) {
12190                dumpAll = true;
12191            } else if ("-c".equals(opt)) {
12192                dumpClient = true;
12193            } else if ("-h".equals(opt)) {
12194                pw.println("Activity manager dump options:");
12195                pw.println("  [-a] [-c] [-h] [cmd] ...");
12196                pw.println("  cmd may be one of:");
12197                pw.println("    a[ctivities]: activity stack state");
12198                pw.println("    r[recents]: recent activities state");
12199                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12200                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12201                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12202                pw.println("    o[om]: out of memory management");
12203                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12204                pw.println("    provider [COMP_SPEC]: provider client-side state");
12205                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12206                pw.println("    service [COMP_SPEC]: service client-side state");
12207                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12208                pw.println("    all: dump all activities");
12209                pw.println("    top: dump the top activity");
12210                pw.println("    write: write all pending state to storage");
12211                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12212                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12213                pw.println("    a partial substring in a component name, a");
12214                pw.println("    hex object identifier.");
12215                pw.println("  -a: include all available server state.");
12216                pw.println("  -c: include client state.");
12217                return;
12218            } else {
12219                pw.println("Unknown argument: " + opt + "; use -h for help");
12220            }
12221        }
12222
12223        long origId = Binder.clearCallingIdentity();
12224        boolean more = false;
12225        // Is the caller requesting to dump a particular piece of data?
12226        if (opti < args.length) {
12227            String cmd = args[opti];
12228            opti++;
12229            if ("activities".equals(cmd) || "a".equals(cmd)) {
12230                synchronized (this) {
12231                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12232                }
12233            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12234                synchronized (this) {
12235                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12236                }
12237            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12238                String[] newArgs;
12239                String name;
12240                if (opti >= args.length) {
12241                    name = null;
12242                    newArgs = EMPTY_STRING_ARRAY;
12243                } else {
12244                    name = args[opti];
12245                    opti++;
12246                    newArgs = new String[args.length - opti];
12247                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12248                            args.length - opti);
12249                }
12250                synchronized (this) {
12251                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12252                }
12253            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12254                String[] newArgs;
12255                String name;
12256                if (opti >= args.length) {
12257                    name = null;
12258                    newArgs = EMPTY_STRING_ARRAY;
12259                } else {
12260                    name = args[opti];
12261                    opti++;
12262                    newArgs = new String[args.length - opti];
12263                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12264                            args.length - opti);
12265                }
12266                synchronized (this) {
12267                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12268                }
12269            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12270                String[] newArgs;
12271                String name;
12272                if (opti >= args.length) {
12273                    name = null;
12274                    newArgs = EMPTY_STRING_ARRAY;
12275                } else {
12276                    name = args[opti];
12277                    opti++;
12278                    newArgs = new String[args.length - opti];
12279                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12280                            args.length - opti);
12281                }
12282                synchronized (this) {
12283                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12284                }
12285            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12286                synchronized (this) {
12287                    dumpOomLocked(fd, pw, args, opti, true);
12288                }
12289            } else if ("provider".equals(cmd)) {
12290                String[] newArgs;
12291                String name;
12292                if (opti >= args.length) {
12293                    name = null;
12294                    newArgs = EMPTY_STRING_ARRAY;
12295                } else {
12296                    name = args[opti];
12297                    opti++;
12298                    newArgs = new String[args.length - opti];
12299                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12300                }
12301                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12302                    pw.println("No providers match: " + name);
12303                    pw.println("Use -h for help.");
12304                }
12305            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12306                synchronized (this) {
12307                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12308                }
12309            } else if ("service".equals(cmd)) {
12310                String[] newArgs;
12311                String name;
12312                if (opti >= args.length) {
12313                    name = null;
12314                    newArgs = EMPTY_STRING_ARRAY;
12315                } else {
12316                    name = args[opti];
12317                    opti++;
12318                    newArgs = new String[args.length - opti];
12319                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12320                            args.length - opti);
12321                }
12322                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12323                    pw.println("No services match: " + name);
12324                    pw.println("Use -h for help.");
12325                }
12326            } else if ("package".equals(cmd)) {
12327                String[] newArgs;
12328                if (opti >= args.length) {
12329                    pw.println("package: no package name specified");
12330                    pw.println("Use -h for help.");
12331                } else {
12332                    dumpPackage = args[opti];
12333                    opti++;
12334                    newArgs = new String[args.length - opti];
12335                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12336                            args.length - opti);
12337                    args = newArgs;
12338                    opti = 0;
12339                    more = true;
12340                }
12341            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12342                synchronized (this) {
12343                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12344                }
12345            } else if ("write".equals(cmd)) {
12346                mTaskPersister.flush();
12347                pw.println("All tasks persisted.");
12348                return;
12349            } else {
12350                // Dumping a single activity?
12351                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12352                    pw.println("Bad activity command, or no activities match: " + cmd);
12353                    pw.println("Use -h for help.");
12354                }
12355            }
12356            if (!more) {
12357                Binder.restoreCallingIdentity(origId);
12358                return;
12359            }
12360        }
12361
12362        // No piece of data specified, dump everything.
12363        synchronized (this) {
12364            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12365            pw.println();
12366            if (dumpAll) {
12367                pw.println("-------------------------------------------------------------------------------");
12368            }
12369            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12370            pw.println();
12371            if (dumpAll) {
12372                pw.println("-------------------------------------------------------------------------------");
12373            }
12374            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12375            pw.println();
12376            if (dumpAll) {
12377                pw.println("-------------------------------------------------------------------------------");
12378            }
12379            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12380            pw.println();
12381            if (dumpAll) {
12382                pw.println("-------------------------------------------------------------------------------");
12383            }
12384            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12385            pw.println();
12386            if (dumpAll) {
12387                pw.println("-------------------------------------------------------------------------------");
12388            }
12389            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12390            pw.println();
12391            if (dumpAll) {
12392                pw.println("-------------------------------------------------------------------------------");
12393            }
12394            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12395        }
12396        Binder.restoreCallingIdentity(origId);
12397    }
12398
12399    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12400            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12401        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12402
12403        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12404                dumpPackage);
12405        boolean needSep = printedAnything;
12406
12407        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12408                dumpPackage, needSep, "  mFocusedActivity: ");
12409        if (printed) {
12410            printedAnything = true;
12411            needSep = false;
12412        }
12413
12414        if (dumpPackage == null) {
12415            if (needSep) {
12416                pw.println();
12417            }
12418            needSep = true;
12419            printedAnything = true;
12420            mStackSupervisor.dump(pw, "  ");
12421        }
12422
12423        if (!printedAnything) {
12424            pw.println("  (nothing)");
12425        }
12426    }
12427
12428    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12429            int opti, boolean dumpAll, String dumpPackage) {
12430        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12431
12432        boolean printedAnything = false;
12433
12434        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12435            boolean printedHeader = false;
12436
12437            final int N = mRecentTasks.size();
12438            for (int i=0; i<N; i++) {
12439                TaskRecord tr = mRecentTasks.get(i);
12440                if (dumpPackage != null) {
12441                    if (tr.realActivity == null ||
12442                            !dumpPackage.equals(tr.realActivity)) {
12443                        continue;
12444                    }
12445                }
12446                if (!printedHeader) {
12447                    pw.println("  Recent tasks:");
12448                    printedHeader = true;
12449                    printedAnything = true;
12450                }
12451                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12452                        pw.println(tr);
12453                if (dumpAll) {
12454                    mRecentTasks.get(i).dump(pw, "    ");
12455                }
12456            }
12457        }
12458
12459        if (!printedAnything) {
12460            pw.println("  (nothing)");
12461        }
12462    }
12463
12464    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12465            int opti, boolean dumpAll, String dumpPackage) {
12466        boolean needSep = false;
12467        boolean printedAnything = false;
12468        int numPers = 0;
12469
12470        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12471
12472        if (dumpAll) {
12473            final int NP = mProcessNames.getMap().size();
12474            for (int ip=0; ip<NP; ip++) {
12475                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12476                final int NA = procs.size();
12477                for (int ia=0; ia<NA; ia++) {
12478                    ProcessRecord r = procs.valueAt(ia);
12479                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12480                        continue;
12481                    }
12482                    if (!needSep) {
12483                        pw.println("  All known processes:");
12484                        needSep = true;
12485                        printedAnything = true;
12486                    }
12487                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12488                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12489                        pw.print(" "); pw.println(r);
12490                    r.dump(pw, "    ");
12491                    if (r.persistent) {
12492                        numPers++;
12493                    }
12494                }
12495            }
12496        }
12497
12498        if (mIsolatedProcesses.size() > 0) {
12499            boolean printed = false;
12500            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12501                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12502                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12503                    continue;
12504                }
12505                if (!printed) {
12506                    if (needSep) {
12507                        pw.println();
12508                    }
12509                    pw.println("  Isolated process list (sorted by uid):");
12510                    printedAnything = true;
12511                    printed = true;
12512                    needSep = true;
12513                }
12514                pw.println(String.format("%sIsolated #%2d: %s",
12515                        "    ", i, r.toString()));
12516            }
12517        }
12518
12519        if (mLruProcesses.size() > 0) {
12520            if (needSep) {
12521                pw.println();
12522            }
12523            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12524                    pw.print(" total, non-act at ");
12525                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12526                    pw.print(", non-svc at ");
12527                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12528                    pw.println("):");
12529            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12530            needSep = true;
12531            printedAnything = true;
12532        }
12533
12534        if (dumpAll || dumpPackage != null) {
12535            synchronized (mPidsSelfLocked) {
12536                boolean printed = false;
12537                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12538                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12539                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12540                        continue;
12541                    }
12542                    if (!printed) {
12543                        if (needSep) pw.println();
12544                        needSep = true;
12545                        pw.println("  PID mappings:");
12546                        printed = true;
12547                        printedAnything = true;
12548                    }
12549                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12550                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12551                }
12552            }
12553        }
12554
12555        if (mForegroundProcesses.size() > 0) {
12556            synchronized (mPidsSelfLocked) {
12557                boolean printed = false;
12558                for (int i=0; i<mForegroundProcesses.size(); i++) {
12559                    ProcessRecord r = mPidsSelfLocked.get(
12560                            mForegroundProcesses.valueAt(i).pid);
12561                    if (dumpPackage != null && (r == null
12562                            || !r.pkgList.containsKey(dumpPackage))) {
12563                        continue;
12564                    }
12565                    if (!printed) {
12566                        if (needSep) pw.println();
12567                        needSep = true;
12568                        pw.println("  Foreground Processes:");
12569                        printed = true;
12570                        printedAnything = true;
12571                    }
12572                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12573                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12574                }
12575            }
12576        }
12577
12578        if (mPersistentStartingProcesses.size() > 0) {
12579            if (needSep) pw.println();
12580            needSep = true;
12581            printedAnything = true;
12582            pw.println("  Persisent processes that are starting:");
12583            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12584                    "Starting Norm", "Restarting PERS", dumpPackage);
12585        }
12586
12587        if (mRemovedProcesses.size() > 0) {
12588            if (needSep) pw.println();
12589            needSep = true;
12590            printedAnything = true;
12591            pw.println("  Processes that are being removed:");
12592            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12593                    "Removed Norm", "Removed PERS", dumpPackage);
12594        }
12595
12596        if (mProcessesOnHold.size() > 0) {
12597            if (needSep) pw.println();
12598            needSep = true;
12599            printedAnything = true;
12600            pw.println("  Processes that are on old until the system is ready:");
12601            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12602                    "OnHold Norm", "OnHold PERS", dumpPackage);
12603        }
12604
12605        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12606
12607        if (mProcessCrashTimes.getMap().size() > 0) {
12608            boolean printed = false;
12609            long now = SystemClock.uptimeMillis();
12610            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12611            final int NP = pmap.size();
12612            for (int ip=0; ip<NP; ip++) {
12613                String pname = pmap.keyAt(ip);
12614                SparseArray<Long> uids = pmap.valueAt(ip);
12615                final int N = uids.size();
12616                for (int i=0; i<N; i++) {
12617                    int puid = uids.keyAt(i);
12618                    ProcessRecord r = mProcessNames.get(pname, puid);
12619                    if (dumpPackage != null && (r == null
12620                            || !r.pkgList.containsKey(dumpPackage))) {
12621                        continue;
12622                    }
12623                    if (!printed) {
12624                        if (needSep) pw.println();
12625                        needSep = true;
12626                        pw.println("  Time since processes crashed:");
12627                        printed = true;
12628                        printedAnything = true;
12629                    }
12630                    pw.print("    Process "); pw.print(pname);
12631                            pw.print(" uid "); pw.print(puid);
12632                            pw.print(": last crashed ");
12633                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12634                            pw.println(" ago");
12635                }
12636            }
12637        }
12638
12639        if (mBadProcesses.getMap().size() > 0) {
12640            boolean printed = false;
12641            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12642            final int NP = pmap.size();
12643            for (int ip=0; ip<NP; ip++) {
12644                String pname = pmap.keyAt(ip);
12645                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12646                final int N = uids.size();
12647                for (int i=0; i<N; i++) {
12648                    int puid = uids.keyAt(i);
12649                    ProcessRecord r = mProcessNames.get(pname, puid);
12650                    if (dumpPackage != null && (r == null
12651                            || !r.pkgList.containsKey(dumpPackage))) {
12652                        continue;
12653                    }
12654                    if (!printed) {
12655                        if (needSep) pw.println();
12656                        needSep = true;
12657                        pw.println("  Bad processes:");
12658                        printedAnything = true;
12659                    }
12660                    BadProcessInfo info = uids.valueAt(i);
12661                    pw.print("    Bad process "); pw.print(pname);
12662                            pw.print(" uid "); pw.print(puid);
12663                            pw.print(": crashed at time "); pw.println(info.time);
12664                    if (info.shortMsg != null) {
12665                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12666                    }
12667                    if (info.longMsg != null) {
12668                        pw.print("      Long msg: "); pw.println(info.longMsg);
12669                    }
12670                    if (info.stack != null) {
12671                        pw.println("      Stack:");
12672                        int lastPos = 0;
12673                        for (int pos=0; pos<info.stack.length(); pos++) {
12674                            if (info.stack.charAt(pos) == '\n') {
12675                                pw.print("        ");
12676                                pw.write(info.stack, lastPos, pos-lastPos);
12677                                pw.println();
12678                                lastPos = pos+1;
12679                            }
12680                        }
12681                        if (lastPos < info.stack.length()) {
12682                            pw.print("        ");
12683                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12684                            pw.println();
12685                        }
12686                    }
12687                }
12688            }
12689        }
12690
12691        if (dumpPackage == null) {
12692            pw.println();
12693            needSep = false;
12694            pw.println("  mStartedUsers:");
12695            for (int i=0; i<mStartedUsers.size(); i++) {
12696                UserStartedState uss = mStartedUsers.valueAt(i);
12697                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12698                        pw.print(": "); uss.dump("", pw);
12699            }
12700            pw.print("  mStartedUserArray: [");
12701            for (int i=0; i<mStartedUserArray.length; i++) {
12702                if (i > 0) pw.print(", ");
12703                pw.print(mStartedUserArray[i]);
12704            }
12705            pw.println("]");
12706            pw.print("  mUserLru: [");
12707            for (int i=0; i<mUserLru.size(); i++) {
12708                if (i > 0) pw.print(", ");
12709                pw.print(mUserLru.get(i));
12710            }
12711            pw.println("]");
12712            if (dumpAll) {
12713                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12714            }
12715            synchronized (mUserProfileGroupIdsSelfLocked) {
12716                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12717                    pw.println("  mUserProfileGroupIds:");
12718                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12719                        pw.print("    User #");
12720                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12721                        pw.print(" -> profile #");
12722                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12723                    }
12724                }
12725            }
12726        }
12727        if (mHomeProcess != null && (dumpPackage == null
12728                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12729            if (needSep) {
12730                pw.println();
12731                needSep = false;
12732            }
12733            pw.println("  mHomeProcess: " + mHomeProcess);
12734        }
12735        if (mPreviousProcess != null && (dumpPackage == null
12736                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12737            if (needSep) {
12738                pw.println();
12739                needSep = false;
12740            }
12741            pw.println("  mPreviousProcess: " + mPreviousProcess);
12742        }
12743        if (dumpAll) {
12744            StringBuilder sb = new StringBuilder(128);
12745            sb.append("  mPreviousProcessVisibleTime: ");
12746            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12747            pw.println(sb);
12748        }
12749        if (mHeavyWeightProcess != null && (dumpPackage == null
12750                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12751            if (needSep) {
12752                pw.println();
12753                needSep = false;
12754            }
12755            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12756        }
12757        if (dumpPackage == null) {
12758            pw.println("  mConfiguration: " + mConfiguration);
12759        }
12760        if (dumpAll) {
12761            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12762            if (mCompatModePackages.getPackages().size() > 0) {
12763                boolean printed = false;
12764                for (Map.Entry<String, Integer> entry
12765                        : mCompatModePackages.getPackages().entrySet()) {
12766                    String pkg = entry.getKey();
12767                    int mode = entry.getValue();
12768                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12769                        continue;
12770                    }
12771                    if (!printed) {
12772                        pw.println("  mScreenCompatPackages:");
12773                        printed = true;
12774                    }
12775                    pw.print("    "); pw.print(pkg); pw.print(": ");
12776                            pw.print(mode); pw.println();
12777                }
12778            }
12779        }
12780        if (dumpPackage == null) {
12781            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12782                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12783                        + " mLockScreenShown " + lockScreenShownToString());
12784            }
12785            if (mShuttingDown || mRunningVoice) {
12786                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12787            }
12788        }
12789        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12790                || mOrigWaitForDebugger) {
12791            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12792                    || dumpPackage.equals(mOrigDebugApp)) {
12793                if (needSep) {
12794                    pw.println();
12795                    needSep = false;
12796                }
12797                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12798                        + " mDebugTransient=" + mDebugTransient
12799                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12800            }
12801        }
12802        if (mOpenGlTraceApp != null) {
12803            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12804                if (needSep) {
12805                    pw.println();
12806                    needSep = false;
12807                }
12808                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12809            }
12810        }
12811        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12812                || mProfileFd != null) {
12813            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12814                if (needSep) {
12815                    pw.println();
12816                    needSep = false;
12817                }
12818                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12819                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12820                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12821                        + mAutoStopProfiler);
12822                pw.println("  mProfileType=" + mProfileType);
12823            }
12824        }
12825        if (dumpPackage == null) {
12826            if (mAlwaysFinishActivities || mController != null) {
12827                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12828                        + " mController=" + mController);
12829            }
12830            if (dumpAll) {
12831                pw.println("  Total persistent processes: " + numPers);
12832                pw.println("  mProcessesReady=" + mProcessesReady
12833                        + " mSystemReady=" + mSystemReady
12834                        + " mBooted=" + mBooted
12835                        + " mFactoryTest=" + mFactoryTest);
12836                pw.println("  mBooting=" + mBooting
12837                        + " mCallFinishBooting=" + mCallFinishBooting
12838                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12839                pw.print("  mLastPowerCheckRealtime=");
12840                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12841                        pw.println("");
12842                pw.print("  mLastPowerCheckUptime=");
12843                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12844                        pw.println("");
12845                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12846                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12847                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12848                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12849                        + " (" + mLruProcesses.size() + " total)"
12850                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12851                        + " mNumServiceProcs=" + mNumServiceProcs
12852                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12853                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12854                        + " mLastMemoryLevel" + mLastMemoryLevel
12855                        + " mLastNumProcesses" + mLastNumProcesses);
12856                long now = SystemClock.uptimeMillis();
12857                pw.print("  mLastIdleTime=");
12858                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12859                        pw.print(" mLowRamSinceLastIdle=");
12860                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12861                        pw.println();
12862            }
12863        }
12864
12865        if (!printedAnything) {
12866            pw.println("  (nothing)");
12867        }
12868    }
12869
12870    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12871            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12872        if (mProcessesToGc.size() > 0) {
12873            boolean printed = false;
12874            long now = SystemClock.uptimeMillis();
12875            for (int i=0; i<mProcessesToGc.size(); i++) {
12876                ProcessRecord proc = mProcessesToGc.get(i);
12877                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12878                    continue;
12879                }
12880                if (!printed) {
12881                    if (needSep) pw.println();
12882                    needSep = true;
12883                    pw.println("  Processes that are waiting to GC:");
12884                    printed = true;
12885                }
12886                pw.print("    Process "); pw.println(proc);
12887                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12888                        pw.print(", last gced=");
12889                        pw.print(now-proc.lastRequestedGc);
12890                        pw.print(" ms ago, last lowMem=");
12891                        pw.print(now-proc.lastLowMemory);
12892                        pw.println(" ms ago");
12893
12894            }
12895        }
12896        return needSep;
12897    }
12898
12899    void printOomLevel(PrintWriter pw, String name, int adj) {
12900        pw.print("    ");
12901        if (adj >= 0) {
12902            pw.print(' ');
12903            if (adj < 10) pw.print(' ');
12904        } else {
12905            if (adj > -10) pw.print(' ');
12906        }
12907        pw.print(adj);
12908        pw.print(": ");
12909        pw.print(name);
12910        pw.print(" (");
12911        pw.print(mProcessList.getMemLevel(adj)/1024);
12912        pw.println(" kB)");
12913    }
12914
12915    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12916            int opti, boolean dumpAll) {
12917        boolean needSep = false;
12918
12919        if (mLruProcesses.size() > 0) {
12920            if (needSep) pw.println();
12921            needSep = true;
12922            pw.println("  OOM levels:");
12923            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12924            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12925            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12926            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12927            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12928            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12929            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12930            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12931            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12932            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12933            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12934            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12935            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12936            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12937
12938            if (needSep) pw.println();
12939            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12940                    pw.print(" total, non-act at ");
12941                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12942                    pw.print(", non-svc at ");
12943                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12944                    pw.println("):");
12945            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12946            needSep = true;
12947        }
12948
12949        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12950
12951        pw.println();
12952        pw.println("  mHomeProcess: " + mHomeProcess);
12953        pw.println("  mPreviousProcess: " + mPreviousProcess);
12954        if (mHeavyWeightProcess != null) {
12955            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12956        }
12957
12958        return true;
12959    }
12960
12961    /**
12962     * There are three ways to call this:
12963     *  - no provider specified: dump all the providers
12964     *  - a flattened component name that matched an existing provider was specified as the
12965     *    first arg: dump that one provider
12966     *  - the first arg isn't the flattened component name of an existing provider:
12967     *    dump all providers whose component contains the first arg as a substring
12968     */
12969    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12970            int opti, boolean dumpAll) {
12971        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12972    }
12973
12974    static class ItemMatcher {
12975        ArrayList<ComponentName> components;
12976        ArrayList<String> strings;
12977        ArrayList<Integer> objects;
12978        boolean all;
12979
12980        ItemMatcher() {
12981            all = true;
12982        }
12983
12984        void build(String name) {
12985            ComponentName componentName = ComponentName.unflattenFromString(name);
12986            if (componentName != null) {
12987                if (components == null) {
12988                    components = new ArrayList<ComponentName>();
12989                }
12990                components.add(componentName);
12991                all = false;
12992            } else {
12993                int objectId = 0;
12994                // Not a '/' separated full component name; maybe an object ID?
12995                try {
12996                    objectId = Integer.parseInt(name, 16);
12997                    if (objects == null) {
12998                        objects = new ArrayList<Integer>();
12999                    }
13000                    objects.add(objectId);
13001                    all = false;
13002                } catch (RuntimeException e) {
13003                    // Not an integer; just do string match.
13004                    if (strings == null) {
13005                        strings = new ArrayList<String>();
13006                    }
13007                    strings.add(name);
13008                    all = false;
13009                }
13010            }
13011        }
13012
13013        int build(String[] args, int opti) {
13014            for (; opti<args.length; opti++) {
13015                String name = args[opti];
13016                if ("--".equals(name)) {
13017                    return opti+1;
13018                }
13019                build(name);
13020            }
13021            return opti;
13022        }
13023
13024        boolean match(Object object, ComponentName comp) {
13025            if (all) {
13026                return true;
13027            }
13028            if (components != null) {
13029                for (int i=0; i<components.size(); i++) {
13030                    if (components.get(i).equals(comp)) {
13031                        return true;
13032                    }
13033                }
13034            }
13035            if (objects != null) {
13036                for (int i=0; i<objects.size(); i++) {
13037                    if (System.identityHashCode(object) == objects.get(i)) {
13038                        return true;
13039                    }
13040                }
13041            }
13042            if (strings != null) {
13043                String flat = comp.flattenToString();
13044                for (int i=0; i<strings.size(); i++) {
13045                    if (flat.contains(strings.get(i))) {
13046                        return true;
13047                    }
13048                }
13049            }
13050            return false;
13051        }
13052    }
13053
13054    /**
13055     * There are three things that cmd can be:
13056     *  - a flattened component name that matches an existing activity
13057     *  - the cmd arg isn't the flattened component name of an existing activity:
13058     *    dump all activity whose component contains the cmd as a substring
13059     *  - A hex number of the ActivityRecord object instance.
13060     */
13061    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13062            int opti, boolean dumpAll) {
13063        ArrayList<ActivityRecord> activities;
13064
13065        synchronized (this) {
13066            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13067        }
13068
13069        if (activities.size() <= 0) {
13070            return false;
13071        }
13072
13073        String[] newArgs = new String[args.length - opti];
13074        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13075
13076        TaskRecord lastTask = null;
13077        boolean needSep = false;
13078        for (int i=activities.size()-1; i>=0; i--) {
13079            ActivityRecord r = activities.get(i);
13080            if (needSep) {
13081                pw.println();
13082            }
13083            needSep = true;
13084            synchronized (this) {
13085                if (lastTask != r.task) {
13086                    lastTask = r.task;
13087                    pw.print("TASK "); pw.print(lastTask.affinity);
13088                            pw.print(" id="); pw.println(lastTask.taskId);
13089                    if (dumpAll) {
13090                        lastTask.dump(pw, "  ");
13091                    }
13092                }
13093            }
13094            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13095        }
13096        return true;
13097    }
13098
13099    /**
13100     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13101     * there is a thread associated with the activity.
13102     */
13103    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13104            final ActivityRecord r, String[] args, boolean dumpAll) {
13105        String innerPrefix = prefix + "  ";
13106        synchronized (this) {
13107            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13108                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13109                    pw.print(" pid=");
13110                    if (r.app != null) pw.println(r.app.pid);
13111                    else pw.println("(not running)");
13112            if (dumpAll) {
13113                r.dump(pw, innerPrefix);
13114            }
13115        }
13116        if (r.app != null && r.app.thread != null) {
13117            // flush anything that is already in the PrintWriter since the thread is going
13118            // to write to the file descriptor directly
13119            pw.flush();
13120            try {
13121                TransferPipe tp = new TransferPipe();
13122                try {
13123                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13124                            r.appToken, innerPrefix, args);
13125                    tp.go(fd);
13126                } finally {
13127                    tp.kill();
13128                }
13129            } catch (IOException e) {
13130                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13131            } catch (RemoteException e) {
13132                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13133            }
13134        }
13135    }
13136
13137    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13138            int opti, boolean dumpAll, String dumpPackage) {
13139        boolean needSep = false;
13140        boolean onlyHistory = false;
13141        boolean printedAnything = false;
13142
13143        if ("history".equals(dumpPackage)) {
13144            if (opti < args.length && "-s".equals(args[opti])) {
13145                dumpAll = false;
13146            }
13147            onlyHistory = true;
13148            dumpPackage = null;
13149        }
13150
13151        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13152        if (!onlyHistory && dumpAll) {
13153            if (mRegisteredReceivers.size() > 0) {
13154                boolean printed = false;
13155                Iterator it = mRegisteredReceivers.values().iterator();
13156                while (it.hasNext()) {
13157                    ReceiverList r = (ReceiverList)it.next();
13158                    if (dumpPackage != null && (r.app == null ||
13159                            !dumpPackage.equals(r.app.info.packageName))) {
13160                        continue;
13161                    }
13162                    if (!printed) {
13163                        pw.println("  Registered Receivers:");
13164                        needSep = true;
13165                        printed = true;
13166                        printedAnything = true;
13167                    }
13168                    pw.print("  * "); pw.println(r);
13169                    r.dump(pw, "    ");
13170                }
13171            }
13172
13173            if (mReceiverResolver.dump(pw, needSep ?
13174                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13175                    "    ", dumpPackage, false)) {
13176                needSep = true;
13177                printedAnything = true;
13178            }
13179        }
13180
13181        for (BroadcastQueue q : mBroadcastQueues) {
13182            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13183            printedAnything |= needSep;
13184        }
13185
13186        needSep = true;
13187
13188        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13189            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13190                if (needSep) {
13191                    pw.println();
13192                }
13193                needSep = true;
13194                printedAnything = true;
13195                pw.print("  Sticky broadcasts for user ");
13196                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13197                StringBuilder sb = new StringBuilder(128);
13198                for (Map.Entry<String, ArrayList<Intent>> ent
13199                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13200                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13201                    if (dumpAll) {
13202                        pw.println(":");
13203                        ArrayList<Intent> intents = ent.getValue();
13204                        final int N = intents.size();
13205                        for (int i=0; i<N; i++) {
13206                            sb.setLength(0);
13207                            sb.append("    Intent: ");
13208                            intents.get(i).toShortString(sb, false, true, false, false);
13209                            pw.println(sb.toString());
13210                            Bundle bundle = intents.get(i).getExtras();
13211                            if (bundle != null) {
13212                                pw.print("      ");
13213                                pw.println(bundle.toString());
13214                            }
13215                        }
13216                    } else {
13217                        pw.println("");
13218                    }
13219                }
13220            }
13221        }
13222
13223        if (!onlyHistory && dumpAll) {
13224            pw.println();
13225            for (BroadcastQueue queue : mBroadcastQueues) {
13226                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13227                        + queue.mBroadcastsScheduled);
13228            }
13229            pw.println("  mHandler:");
13230            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13231            needSep = true;
13232            printedAnything = true;
13233        }
13234
13235        if (!printedAnything) {
13236            pw.println("  (nothing)");
13237        }
13238    }
13239
13240    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13241            int opti, boolean dumpAll, String dumpPackage) {
13242        boolean needSep;
13243        boolean printedAnything = false;
13244
13245        ItemMatcher matcher = new ItemMatcher();
13246        matcher.build(args, opti);
13247
13248        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13249
13250        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13251        printedAnything |= needSep;
13252
13253        if (mLaunchingProviders.size() > 0) {
13254            boolean printed = false;
13255            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13256                ContentProviderRecord r = mLaunchingProviders.get(i);
13257                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13258                    continue;
13259                }
13260                if (!printed) {
13261                    if (needSep) pw.println();
13262                    needSep = true;
13263                    pw.println("  Launching content providers:");
13264                    printed = true;
13265                    printedAnything = true;
13266                }
13267                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13268                        pw.println(r);
13269            }
13270        }
13271
13272        if (mGrantedUriPermissions.size() > 0) {
13273            boolean printed = false;
13274            int dumpUid = -2;
13275            if (dumpPackage != null) {
13276                try {
13277                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13278                } catch (NameNotFoundException e) {
13279                    dumpUid = -1;
13280                }
13281            }
13282            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13283                int uid = mGrantedUriPermissions.keyAt(i);
13284                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13285                    continue;
13286                }
13287                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13288                if (!printed) {
13289                    if (needSep) pw.println();
13290                    needSep = true;
13291                    pw.println("  Granted Uri Permissions:");
13292                    printed = true;
13293                    printedAnything = true;
13294                }
13295                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13296                for (UriPermission perm : perms.values()) {
13297                    pw.print("    "); pw.println(perm);
13298                    if (dumpAll) {
13299                        perm.dump(pw, "      ");
13300                    }
13301                }
13302            }
13303        }
13304
13305        if (!printedAnything) {
13306            pw.println("  (nothing)");
13307        }
13308    }
13309
13310    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13311            int opti, boolean dumpAll, String dumpPackage) {
13312        boolean printed = false;
13313
13314        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13315
13316        if (mIntentSenderRecords.size() > 0) {
13317            Iterator<WeakReference<PendingIntentRecord>> it
13318                    = mIntentSenderRecords.values().iterator();
13319            while (it.hasNext()) {
13320                WeakReference<PendingIntentRecord> ref = it.next();
13321                PendingIntentRecord rec = ref != null ? ref.get(): null;
13322                if (dumpPackage != null && (rec == null
13323                        || !dumpPackage.equals(rec.key.packageName))) {
13324                    continue;
13325                }
13326                printed = true;
13327                if (rec != null) {
13328                    pw.print("  * "); pw.println(rec);
13329                    if (dumpAll) {
13330                        rec.dump(pw, "    ");
13331                    }
13332                } else {
13333                    pw.print("  * "); pw.println(ref);
13334                }
13335            }
13336        }
13337
13338        if (!printed) {
13339            pw.println("  (nothing)");
13340        }
13341    }
13342
13343    private static final int dumpProcessList(PrintWriter pw,
13344            ActivityManagerService service, List list,
13345            String prefix, String normalLabel, String persistentLabel,
13346            String dumpPackage) {
13347        int numPers = 0;
13348        final int N = list.size()-1;
13349        for (int i=N; i>=0; i--) {
13350            ProcessRecord r = (ProcessRecord)list.get(i);
13351            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13352                continue;
13353            }
13354            pw.println(String.format("%s%s #%2d: %s",
13355                    prefix, (r.persistent ? persistentLabel : normalLabel),
13356                    i, r.toString()));
13357            if (r.persistent) {
13358                numPers++;
13359            }
13360        }
13361        return numPers;
13362    }
13363
13364    private static final boolean dumpProcessOomList(PrintWriter pw,
13365            ActivityManagerService service, List<ProcessRecord> origList,
13366            String prefix, String normalLabel, String persistentLabel,
13367            boolean inclDetails, String dumpPackage) {
13368
13369        ArrayList<Pair<ProcessRecord, Integer>> list
13370                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13371        for (int i=0; i<origList.size(); i++) {
13372            ProcessRecord r = origList.get(i);
13373            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13374                continue;
13375            }
13376            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13377        }
13378
13379        if (list.size() <= 0) {
13380            return false;
13381        }
13382
13383        Comparator<Pair<ProcessRecord, Integer>> comparator
13384                = new Comparator<Pair<ProcessRecord, Integer>>() {
13385            @Override
13386            public int compare(Pair<ProcessRecord, Integer> object1,
13387                    Pair<ProcessRecord, Integer> object2) {
13388                if (object1.first.setAdj != object2.first.setAdj) {
13389                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13390                }
13391                if (object1.second.intValue() != object2.second.intValue()) {
13392                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13393                }
13394                return 0;
13395            }
13396        };
13397
13398        Collections.sort(list, comparator);
13399
13400        final long curRealtime = SystemClock.elapsedRealtime();
13401        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13402        final long curUptime = SystemClock.uptimeMillis();
13403        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13404
13405        for (int i=list.size()-1; i>=0; i--) {
13406            ProcessRecord r = list.get(i).first;
13407            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13408            char schedGroup;
13409            switch (r.setSchedGroup) {
13410                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13411                    schedGroup = 'B';
13412                    break;
13413                case Process.THREAD_GROUP_DEFAULT:
13414                    schedGroup = 'F';
13415                    break;
13416                default:
13417                    schedGroup = '?';
13418                    break;
13419            }
13420            char foreground;
13421            if (r.foregroundActivities) {
13422                foreground = 'A';
13423            } else if (r.foregroundServices) {
13424                foreground = 'S';
13425            } else {
13426                foreground = ' ';
13427            }
13428            String procState = ProcessList.makeProcStateString(r.curProcState);
13429            pw.print(prefix);
13430            pw.print(r.persistent ? persistentLabel : normalLabel);
13431            pw.print(" #");
13432            int num = (origList.size()-1)-list.get(i).second;
13433            if (num < 10) pw.print(' ');
13434            pw.print(num);
13435            pw.print(": ");
13436            pw.print(oomAdj);
13437            pw.print(' ');
13438            pw.print(schedGroup);
13439            pw.print('/');
13440            pw.print(foreground);
13441            pw.print('/');
13442            pw.print(procState);
13443            pw.print(" trm:");
13444            if (r.trimMemoryLevel < 10) pw.print(' ');
13445            pw.print(r.trimMemoryLevel);
13446            pw.print(' ');
13447            pw.print(r.toShortString());
13448            pw.print(" (");
13449            pw.print(r.adjType);
13450            pw.println(')');
13451            if (r.adjSource != null || r.adjTarget != null) {
13452                pw.print(prefix);
13453                pw.print("    ");
13454                if (r.adjTarget instanceof ComponentName) {
13455                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13456                } else if (r.adjTarget != null) {
13457                    pw.print(r.adjTarget.toString());
13458                } else {
13459                    pw.print("{null}");
13460                }
13461                pw.print("<=");
13462                if (r.adjSource instanceof ProcessRecord) {
13463                    pw.print("Proc{");
13464                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13465                    pw.println("}");
13466                } else if (r.adjSource != null) {
13467                    pw.println(r.adjSource.toString());
13468                } else {
13469                    pw.println("{null}");
13470                }
13471            }
13472            if (inclDetails) {
13473                pw.print(prefix);
13474                pw.print("    ");
13475                pw.print("oom: max="); pw.print(r.maxAdj);
13476                pw.print(" curRaw="); pw.print(r.curRawAdj);
13477                pw.print(" setRaw="); pw.print(r.setRawAdj);
13478                pw.print(" cur="); pw.print(r.curAdj);
13479                pw.print(" set="); pw.println(r.setAdj);
13480                pw.print(prefix);
13481                pw.print("    ");
13482                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13483                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13484                pw.print(" lastPss="); pw.print(r.lastPss);
13485                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13486                pw.print(prefix);
13487                pw.print("    ");
13488                pw.print("cached="); pw.print(r.cached);
13489                pw.print(" empty="); pw.print(r.empty);
13490                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13491
13492                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13493                    if (r.lastWakeTime != 0) {
13494                        long wtime;
13495                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13496                        synchronized (stats) {
13497                            wtime = stats.getProcessWakeTime(r.info.uid,
13498                                    r.pid, curRealtime);
13499                        }
13500                        long timeUsed = wtime - r.lastWakeTime;
13501                        pw.print(prefix);
13502                        pw.print("    ");
13503                        pw.print("keep awake over ");
13504                        TimeUtils.formatDuration(realtimeSince, pw);
13505                        pw.print(" used ");
13506                        TimeUtils.formatDuration(timeUsed, pw);
13507                        pw.print(" (");
13508                        pw.print((timeUsed*100)/realtimeSince);
13509                        pw.println("%)");
13510                    }
13511                    if (r.lastCpuTime != 0) {
13512                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13513                        pw.print(prefix);
13514                        pw.print("    ");
13515                        pw.print("run cpu over ");
13516                        TimeUtils.formatDuration(uptimeSince, pw);
13517                        pw.print(" used ");
13518                        TimeUtils.formatDuration(timeUsed, pw);
13519                        pw.print(" (");
13520                        pw.print((timeUsed*100)/uptimeSince);
13521                        pw.println("%)");
13522                    }
13523                }
13524            }
13525        }
13526        return true;
13527    }
13528
13529    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13530            String[] args) {
13531        ArrayList<ProcessRecord> procs;
13532        synchronized (this) {
13533            if (args != null && args.length > start
13534                    && args[start].charAt(0) != '-') {
13535                procs = new ArrayList<ProcessRecord>();
13536                int pid = -1;
13537                try {
13538                    pid = Integer.parseInt(args[start]);
13539                } catch (NumberFormatException e) {
13540                }
13541                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13542                    ProcessRecord proc = mLruProcesses.get(i);
13543                    if (proc.pid == pid) {
13544                        procs.add(proc);
13545                    } else if (allPkgs && proc.pkgList != null
13546                            && proc.pkgList.containsKey(args[start])) {
13547                        procs.add(proc);
13548                    } else if (proc.processName.equals(args[start])) {
13549                        procs.add(proc);
13550                    }
13551                }
13552                if (procs.size() <= 0) {
13553                    return null;
13554                }
13555            } else {
13556                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13557            }
13558        }
13559        return procs;
13560    }
13561
13562    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13563            PrintWriter pw, String[] args) {
13564        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13565        if (procs == null) {
13566            pw.println("No process found for: " + args[0]);
13567            return;
13568        }
13569
13570        long uptime = SystemClock.uptimeMillis();
13571        long realtime = SystemClock.elapsedRealtime();
13572        pw.println("Applications Graphics Acceleration Info:");
13573        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13574
13575        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13576            ProcessRecord r = procs.get(i);
13577            if (r.thread != null) {
13578                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13579                pw.flush();
13580                try {
13581                    TransferPipe tp = new TransferPipe();
13582                    try {
13583                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13584                        tp.go(fd);
13585                    } finally {
13586                        tp.kill();
13587                    }
13588                } catch (IOException e) {
13589                    pw.println("Failure while dumping the app: " + r);
13590                    pw.flush();
13591                } catch (RemoteException e) {
13592                    pw.println("Got a RemoteException while dumping the app " + r);
13593                    pw.flush();
13594                }
13595            }
13596        }
13597    }
13598
13599    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13600        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13601        if (procs == null) {
13602            pw.println("No process found for: " + args[0]);
13603            return;
13604        }
13605
13606        pw.println("Applications Database Info:");
13607
13608        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13609            ProcessRecord r = procs.get(i);
13610            if (r.thread != null) {
13611                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13612                pw.flush();
13613                try {
13614                    TransferPipe tp = new TransferPipe();
13615                    try {
13616                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13617                        tp.go(fd);
13618                    } finally {
13619                        tp.kill();
13620                    }
13621                } catch (IOException e) {
13622                    pw.println("Failure while dumping the app: " + r);
13623                    pw.flush();
13624                } catch (RemoteException e) {
13625                    pw.println("Got a RemoteException while dumping the app " + r);
13626                    pw.flush();
13627                }
13628            }
13629        }
13630    }
13631
13632    final static class MemItem {
13633        final boolean isProc;
13634        final String label;
13635        final String shortLabel;
13636        final long pss;
13637        final int id;
13638        final boolean hasActivities;
13639        ArrayList<MemItem> subitems;
13640
13641        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13642                boolean _hasActivities) {
13643            isProc = true;
13644            label = _label;
13645            shortLabel = _shortLabel;
13646            pss = _pss;
13647            id = _id;
13648            hasActivities = _hasActivities;
13649        }
13650
13651        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13652            isProc = false;
13653            label = _label;
13654            shortLabel = _shortLabel;
13655            pss = _pss;
13656            id = _id;
13657            hasActivities = false;
13658        }
13659    }
13660
13661    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13662            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13663        if (sort && !isCompact) {
13664            Collections.sort(items, new Comparator<MemItem>() {
13665                @Override
13666                public int compare(MemItem lhs, MemItem rhs) {
13667                    if (lhs.pss < rhs.pss) {
13668                        return 1;
13669                    } else if (lhs.pss > rhs.pss) {
13670                        return -1;
13671                    }
13672                    return 0;
13673                }
13674            });
13675        }
13676
13677        for (int i=0; i<items.size(); i++) {
13678            MemItem mi = items.get(i);
13679            if (!isCompact) {
13680                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13681            } else if (mi.isProc) {
13682                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13683                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13684                pw.println(mi.hasActivities ? ",a" : ",e");
13685            } else {
13686                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13687                pw.println(mi.pss);
13688            }
13689            if (mi.subitems != null) {
13690                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13691                        true, isCompact);
13692            }
13693        }
13694    }
13695
13696    // These are in KB.
13697    static final long[] DUMP_MEM_BUCKETS = new long[] {
13698        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13699        120*1024, 160*1024, 200*1024,
13700        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13701        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13702    };
13703
13704    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13705            boolean stackLike) {
13706        int start = label.lastIndexOf('.');
13707        if (start >= 0) start++;
13708        else start = 0;
13709        int end = label.length();
13710        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13711            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13712                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13713                out.append(bucket);
13714                out.append(stackLike ? "MB." : "MB ");
13715                out.append(label, start, end);
13716                return;
13717            }
13718        }
13719        out.append(memKB/1024);
13720        out.append(stackLike ? "MB." : "MB ");
13721        out.append(label, start, end);
13722    }
13723
13724    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13725            ProcessList.NATIVE_ADJ,
13726            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13727            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13728            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13729            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13730            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13731            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13732    };
13733    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13734            "Native",
13735            "System", "Persistent", "Persistent Service", "Foreground",
13736            "Visible", "Perceptible",
13737            "Heavy Weight", "Backup",
13738            "A Services", "Home",
13739            "Previous", "B Services", "Cached"
13740    };
13741    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13742            "native",
13743            "sys", "pers", "persvc", "fore",
13744            "vis", "percept",
13745            "heavy", "backup",
13746            "servicea", "home",
13747            "prev", "serviceb", "cached"
13748    };
13749
13750    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13751            long realtime, boolean isCheckinRequest, boolean isCompact) {
13752        if (isCheckinRequest || isCompact) {
13753            // short checkin version
13754            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13755        } else {
13756            pw.println("Applications Memory Usage (kB):");
13757            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13758        }
13759    }
13760
13761    private static final int KSM_SHARED = 0;
13762    private static final int KSM_SHARING = 1;
13763    private static final int KSM_UNSHARED = 2;
13764    private static final int KSM_VOLATILE = 3;
13765
13766    private final long[] getKsmInfo() {
13767        long[] longOut = new long[4];
13768        final int[] SINGLE_LONG_FORMAT = new int[] {
13769            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13770        };
13771        long[] longTmp = new long[1];
13772        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13773                SINGLE_LONG_FORMAT, null, longTmp, null);
13774        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13775        longTmp[0] = 0;
13776        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13777                SINGLE_LONG_FORMAT, null, longTmp, null);
13778        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13779        longTmp[0] = 0;
13780        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13781                SINGLE_LONG_FORMAT, null, longTmp, null);
13782        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13783        longTmp[0] = 0;
13784        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13785                SINGLE_LONG_FORMAT, null, longTmp, null);
13786        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13787        return longOut;
13788    }
13789
13790    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13791            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13792        boolean dumpDetails = false;
13793        boolean dumpFullDetails = false;
13794        boolean dumpDalvik = false;
13795        boolean oomOnly = false;
13796        boolean isCompact = false;
13797        boolean localOnly = false;
13798        boolean packages = false;
13799
13800        int opti = 0;
13801        while (opti < args.length) {
13802            String opt = args[opti];
13803            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13804                break;
13805            }
13806            opti++;
13807            if ("-a".equals(opt)) {
13808                dumpDetails = true;
13809                dumpFullDetails = true;
13810                dumpDalvik = true;
13811            } else if ("-d".equals(opt)) {
13812                dumpDalvik = true;
13813            } else if ("-c".equals(opt)) {
13814                isCompact = true;
13815            } else if ("--oom".equals(opt)) {
13816                oomOnly = true;
13817            } else if ("--local".equals(opt)) {
13818                localOnly = true;
13819            } else if ("--package".equals(opt)) {
13820                packages = true;
13821            } else if ("-h".equals(opt)) {
13822                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13823                pw.println("  -a: include all available information for each process.");
13824                pw.println("  -d: include dalvik details when dumping process details.");
13825                pw.println("  -c: dump in a compact machine-parseable representation.");
13826                pw.println("  --oom: only show processes organized by oom adj.");
13827                pw.println("  --local: only collect details locally, don't call process.");
13828                pw.println("  --package: interpret process arg as package, dumping all");
13829                pw.println("             processes that have loaded that package.");
13830                pw.println("If [process] is specified it can be the name or ");
13831                pw.println("pid of a specific process to dump.");
13832                return;
13833            } else {
13834                pw.println("Unknown argument: " + opt + "; use -h for help");
13835            }
13836        }
13837
13838        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13839        long uptime = SystemClock.uptimeMillis();
13840        long realtime = SystemClock.elapsedRealtime();
13841        final long[] tmpLong = new long[1];
13842
13843        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13844        if (procs == null) {
13845            // No Java processes.  Maybe they want to print a native process.
13846            if (args != null && args.length > opti
13847                    && args[opti].charAt(0) != '-') {
13848                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13849                        = new ArrayList<ProcessCpuTracker.Stats>();
13850                updateCpuStatsNow();
13851                int findPid = -1;
13852                try {
13853                    findPid = Integer.parseInt(args[opti]);
13854                } catch (NumberFormatException e) {
13855                }
13856                synchronized (mProcessCpuTracker) {
13857                    final int N = mProcessCpuTracker.countStats();
13858                    for (int i=0; i<N; i++) {
13859                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13860                        if (st.pid == findPid || (st.baseName != null
13861                                && st.baseName.equals(args[opti]))) {
13862                            nativeProcs.add(st);
13863                        }
13864                    }
13865                }
13866                if (nativeProcs.size() > 0) {
13867                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13868                            isCompact);
13869                    Debug.MemoryInfo mi = null;
13870                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13871                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13872                        final int pid = r.pid;
13873                        if (!isCheckinRequest && dumpDetails) {
13874                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13875                        }
13876                        if (mi == null) {
13877                            mi = new Debug.MemoryInfo();
13878                        }
13879                        if (dumpDetails || (!brief && !oomOnly)) {
13880                            Debug.getMemoryInfo(pid, mi);
13881                        } else {
13882                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13883                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13884                        }
13885                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13886                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13887                        if (isCheckinRequest) {
13888                            pw.println();
13889                        }
13890                    }
13891                    return;
13892                }
13893            }
13894            pw.println("No process found for: " + args[opti]);
13895            return;
13896        }
13897
13898        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13899            dumpDetails = true;
13900        }
13901
13902        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13903
13904        String[] innerArgs = new String[args.length-opti];
13905        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13906
13907        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13908        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13909        long nativePss=0, dalvikPss=0, otherPss=0;
13910        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13911
13912        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13913        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13914                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13915
13916        long totalPss = 0;
13917        long cachedPss = 0;
13918
13919        Debug.MemoryInfo mi = null;
13920        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13921            final ProcessRecord r = procs.get(i);
13922            final IApplicationThread thread;
13923            final int pid;
13924            final int oomAdj;
13925            final boolean hasActivities;
13926            synchronized (this) {
13927                thread = r.thread;
13928                pid = r.pid;
13929                oomAdj = r.getSetAdjWithServices();
13930                hasActivities = r.activities.size() > 0;
13931            }
13932            if (thread != null) {
13933                if (!isCheckinRequest && dumpDetails) {
13934                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13935                }
13936                if (mi == null) {
13937                    mi = new Debug.MemoryInfo();
13938                }
13939                if (dumpDetails || (!brief && !oomOnly)) {
13940                    Debug.getMemoryInfo(pid, mi);
13941                } else {
13942                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13943                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13944                }
13945                if (dumpDetails) {
13946                    if (localOnly) {
13947                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13948                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13949                        if (isCheckinRequest) {
13950                            pw.println();
13951                        }
13952                    } else {
13953                        try {
13954                            pw.flush();
13955                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13956                                    dumpDalvik, innerArgs);
13957                        } catch (RemoteException e) {
13958                            if (!isCheckinRequest) {
13959                                pw.println("Got RemoteException!");
13960                                pw.flush();
13961                            }
13962                        }
13963                    }
13964                }
13965
13966                final long myTotalPss = mi.getTotalPss();
13967                final long myTotalUss = mi.getTotalUss();
13968
13969                synchronized (this) {
13970                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13971                        // Record this for posterity if the process has been stable.
13972                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13973                    }
13974                }
13975
13976                if (!isCheckinRequest && mi != null) {
13977                    totalPss += myTotalPss;
13978                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13979                            (hasActivities ? " / activities)" : ")"),
13980                            r.processName, myTotalPss, pid, hasActivities);
13981                    procMems.add(pssItem);
13982                    procMemsMap.put(pid, pssItem);
13983
13984                    nativePss += mi.nativePss;
13985                    dalvikPss += mi.dalvikPss;
13986                    otherPss += mi.otherPss;
13987                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13988                        long mem = mi.getOtherPss(j);
13989                        miscPss[j] += mem;
13990                        otherPss -= mem;
13991                    }
13992
13993                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13994                        cachedPss += myTotalPss;
13995                    }
13996
13997                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13998                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13999                                || oomIndex == (oomPss.length-1)) {
14000                            oomPss[oomIndex] += myTotalPss;
14001                            if (oomProcs[oomIndex] == null) {
14002                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14003                            }
14004                            oomProcs[oomIndex].add(pssItem);
14005                            break;
14006                        }
14007                    }
14008                }
14009            }
14010        }
14011
14012        long nativeProcTotalPss = 0;
14013
14014        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14015            // If we are showing aggregations, also look for native processes to
14016            // include so that our aggregations are more accurate.
14017            updateCpuStatsNow();
14018            synchronized (mProcessCpuTracker) {
14019                final int N = mProcessCpuTracker.countStats();
14020                for (int i=0; i<N; i++) {
14021                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14022                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14023                        if (mi == null) {
14024                            mi = new Debug.MemoryInfo();
14025                        }
14026                        if (!brief && !oomOnly) {
14027                            Debug.getMemoryInfo(st.pid, mi);
14028                        } else {
14029                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14030                            mi.nativePrivateDirty = (int)tmpLong[0];
14031                        }
14032
14033                        final long myTotalPss = mi.getTotalPss();
14034                        totalPss += myTotalPss;
14035                        nativeProcTotalPss += myTotalPss;
14036
14037                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14038                                st.name, myTotalPss, st.pid, false);
14039                        procMems.add(pssItem);
14040
14041                        nativePss += mi.nativePss;
14042                        dalvikPss += mi.dalvikPss;
14043                        otherPss += mi.otherPss;
14044                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14045                            long mem = mi.getOtherPss(j);
14046                            miscPss[j] += mem;
14047                            otherPss -= mem;
14048                        }
14049                        oomPss[0] += myTotalPss;
14050                        if (oomProcs[0] == null) {
14051                            oomProcs[0] = new ArrayList<MemItem>();
14052                        }
14053                        oomProcs[0].add(pssItem);
14054                    }
14055                }
14056            }
14057
14058            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14059
14060            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14061            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14062            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14063            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14064                String label = Debug.MemoryInfo.getOtherLabel(j);
14065                catMems.add(new MemItem(label, label, miscPss[j], j));
14066            }
14067
14068            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14069            for (int j=0; j<oomPss.length; j++) {
14070                if (oomPss[j] != 0) {
14071                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14072                            : DUMP_MEM_OOM_LABEL[j];
14073                    MemItem item = new MemItem(label, label, oomPss[j],
14074                            DUMP_MEM_OOM_ADJ[j]);
14075                    item.subitems = oomProcs[j];
14076                    oomMems.add(item);
14077                }
14078            }
14079
14080            if (!brief && !oomOnly && !isCompact) {
14081                pw.println();
14082                pw.println("Total PSS by process:");
14083                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14084                pw.println();
14085            }
14086            if (!isCompact) {
14087                pw.println("Total PSS by OOM adjustment:");
14088            }
14089            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14090            if (!brief && !oomOnly) {
14091                PrintWriter out = categoryPw != null ? categoryPw : pw;
14092                if (!isCompact) {
14093                    out.println();
14094                    out.println("Total PSS by category:");
14095                }
14096                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14097            }
14098            if (!isCompact) {
14099                pw.println();
14100            }
14101            MemInfoReader memInfo = new MemInfoReader();
14102            memInfo.readMemInfo();
14103            if (nativeProcTotalPss > 0) {
14104                synchronized (this) {
14105                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14106                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14107                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14108                }
14109            }
14110            if (!brief) {
14111                if (!isCompact) {
14112                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14113                    pw.print(" kB (status ");
14114                    switch (mLastMemoryLevel) {
14115                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14116                            pw.println("normal)");
14117                            break;
14118                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14119                            pw.println("moderate)");
14120                            break;
14121                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14122                            pw.println("low)");
14123                            break;
14124                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14125                            pw.println("critical)");
14126                            break;
14127                        default:
14128                            pw.print(mLastMemoryLevel);
14129                            pw.println(")");
14130                            break;
14131                    }
14132                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14133                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14134                            pw.print(cachedPss); pw.print(" cached pss + ");
14135                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14136                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14137                } else {
14138                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14139                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14140                            + memInfo.getFreeSizeKb()); pw.print(",");
14141                    pw.println(totalPss - cachedPss);
14142                }
14143            }
14144            if (!isCompact) {
14145                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14146                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14147                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14148                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14149                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14150                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14151                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14152            }
14153            if (!brief) {
14154                if (memInfo.getZramTotalSizeKb() != 0) {
14155                    if (!isCompact) {
14156                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14157                                pw.print(" kB physical used for ");
14158                                pw.print(memInfo.getSwapTotalSizeKb()
14159                                        - memInfo.getSwapFreeSizeKb());
14160                                pw.print(" kB in swap (");
14161                                pw.print(memInfo.getSwapTotalSizeKb());
14162                                pw.println(" kB total swap)");
14163                    } else {
14164                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14165                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14166                                pw.println(memInfo.getSwapFreeSizeKb());
14167                    }
14168                }
14169                final long[] ksm = getKsmInfo();
14170                if (!isCompact) {
14171                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14172                            || ksm[KSM_VOLATILE] != 0) {
14173                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14174                                pw.print(" kB saved from shared ");
14175                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14176                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14177                                pw.print(" kB unshared; ");
14178                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14179                    }
14180                    pw.print("   Tuning: ");
14181                    pw.print(ActivityManager.staticGetMemoryClass());
14182                    pw.print(" (large ");
14183                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14184                    pw.print("), oom ");
14185                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14186                    pw.print(" kB");
14187                    pw.print(", restore limit ");
14188                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14189                    pw.print(" kB");
14190                    if (ActivityManager.isLowRamDeviceStatic()) {
14191                        pw.print(" (low-ram)");
14192                    }
14193                    if (ActivityManager.isHighEndGfx()) {
14194                        pw.print(" (high-end-gfx)");
14195                    }
14196                    pw.println();
14197                } else {
14198                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14199                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14200                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14201                    pw.print("tuning,");
14202                    pw.print(ActivityManager.staticGetMemoryClass());
14203                    pw.print(',');
14204                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14205                    pw.print(',');
14206                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14207                    if (ActivityManager.isLowRamDeviceStatic()) {
14208                        pw.print(",low-ram");
14209                    }
14210                    if (ActivityManager.isHighEndGfx()) {
14211                        pw.print(",high-end-gfx");
14212                    }
14213                    pw.println();
14214                }
14215            }
14216        }
14217    }
14218
14219    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14220            String name) {
14221        sb.append("  ");
14222        sb.append(ProcessList.makeOomAdjString(oomAdj));
14223        sb.append(' ');
14224        sb.append(ProcessList.makeProcStateString(procState));
14225        sb.append(' ');
14226        ProcessList.appendRamKb(sb, pss);
14227        sb.append(" kB: ");
14228        sb.append(name);
14229    }
14230
14231    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14232        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14233        sb.append(" (");
14234        sb.append(mi.pid);
14235        sb.append(") ");
14236        sb.append(mi.adjType);
14237        sb.append('\n');
14238        if (mi.adjReason != null) {
14239            sb.append("                      ");
14240            sb.append(mi.adjReason);
14241            sb.append('\n');
14242        }
14243    }
14244
14245    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14246        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14247        for (int i=0, N=memInfos.size(); i<N; i++) {
14248            ProcessMemInfo mi = memInfos.get(i);
14249            infoMap.put(mi.pid, mi);
14250        }
14251        updateCpuStatsNow();
14252        synchronized (mProcessCpuTracker) {
14253            final int N = mProcessCpuTracker.countStats();
14254            for (int i=0; i<N; i++) {
14255                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14256                if (st.vsize > 0) {
14257                    long pss = Debug.getPss(st.pid, null);
14258                    if (pss > 0) {
14259                        if (infoMap.indexOfKey(st.pid) < 0) {
14260                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14261                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14262                            mi.pss = pss;
14263                            memInfos.add(mi);
14264                        }
14265                    }
14266                }
14267            }
14268        }
14269
14270        long totalPss = 0;
14271        for (int i=0, N=memInfos.size(); i<N; i++) {
14272            ProcessMemInfo mi = memInfos.get(i);
14273            if (mi.pss == 0) {
14274                mi.pss = Debug.getPss(mi.pid, null);
14275            }
14276            totalPss += mi.pss;
14277        }
14278        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14279            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14280                if (lhs.oomAdj != rhs.oomAdj) {
14281                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14282                }
14283                if (lhs.pss != rhs.pss) {
14284                    return lhs.pss < rhs.pss ? 1 : -1;
14285                }
14286                return 0;
14287            }
14288        });
14289
14290        StringBuilder tag = new StringBuilder(128);
14291        StringBuilder stack = new StringBuilder(128);
14292        tag.append("Low on memory -- ");
14293        appendMemBucket(tag, totalPss, "total", false);
14294        appendMemBucket(stack, totalPss, "total", true);
14295
14296        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14297        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14298        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14299
14300        boolean firstLine = true;
14301        int lastOomAdj = Integer.MIN_VALUE;
14302        long extraNativeRam = 0;
14303        long cachedPss = 0;
14304        for (int i=0, N=memInfos.size(); i<N; i++) {
14305            ProcessMemInfo mi = memInfos.get(i);
14306
14307            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14308                cachedPss += mi.pss;
14309            }
14310
14311            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14312                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14313                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14314                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14315                if (lastOomAdj != mi.oomAdj) {
14316                    lastOomAdj = mi.oomAdj;
14317                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14318                        tag.append(" / ");
14319                    }
14320                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14321                        if (firstLine) {
14322                            stack.append(":");
14323                            firstLine = false;
14324                        }
14325                        stack.append("\n\t at ");
14326                    } else {
14327                        stack.append("$");
14328                    }
14329                } else {
14330                    tag.append(" ");
14331                    stack.append("$");
14332                }
14333                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14334                    appendMemBucket(tag, mi.pss, mi.name, false);
14335                }
14336                appendMemBucket(stack, mi.pss, mi.name, true);
14337                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14338                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14339                    stack.append("(");
14340                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14341                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14342                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14343                            stack.append(":");
14344                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14345                        }
14346                    }
14347                    stack.append(")");
14348                }
14349            }
14350
14351            appendMemInfo(fullNativeBuilder, mi);
14352            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14353                // The short form only has native processes that are >= 1MB.
14354                if (mi.pss >= 1000) {
14355                    appendMemInfo(shortNativeBuilder, mi);
14356                } else {
14357                    extraNativeRam += mi.pss;
14358                }
14359            } else {
14360                // Short form has all other details, but if we have collected RAM
14361                // from smaller native processes let's dump a summary of that.
14362                if (extraNativeRam > 0) {
14363                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14364                            -1, extraNativeRam, "(Other native)");
14365                    shortNativeBuilder.append('\n');
14366                    extraNativeRam = 0;
14367                }
14368                appendMemInfo(fullJavaBuilder, mi);
14369            }
14370        }
14371
14372        fullJavaBuilder.append("           ");
14373        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14374        fullJavaBuilder.append(" kB: TOTAL\n");
14375
14376        MemInfoReader memInfo = new MemInfoReader();
14377        memInfo.readMemInfo();
14378        final long[] infos = memInfo.getRawInfo();
14379
14380        StringBuilder memInfoBuilder = new StringBuilder(1024);
14381        Debug.getMemInfo(infos);
14382        memInfoBuilder.append("  MemInfo: ");
14383        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14384        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14385        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14386        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14387        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14388        memInfoBuilder.append("           ");
14389        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14390        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14391        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14392        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14393        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14394            memInfoBuilder.append("  ZRAM: ");
14395            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14396            memInfoBuilder.append(" kB RAM, ");
14397            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14398            memInfoBuilder.append(" kB swap total, ");
14399            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14400            memInfoBuilder.append(" kB swap free\n");
14401        }
14402        final long[] ksm = getKsmInfo();
14403        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14404                || ksm[KSM_VOLATILE] != 0) {
14405            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14406            memInfoBuilder.append(" kB saved from shared ");
14407            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14408            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14409            memInfoBuilder.append(" kB unshared; ");
14410            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14411        }
14412        memInfoBuilder.append("  Free RAM: ");
14413        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14414                + memInfo.getFreeSizeKb());
14415        memInfoBuilder.append(" kB\n");
14416        memInfoBuilder.append("  Used RAM: ");
14417        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14418        memInfoBuilder.append(" kB\n");
14419        memInfoBuilder.append("  Lost RAM: ");
14420        memInfoBuilder.append(memInfo.getTotalSizeKb()
14421                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14422                - memInfo.getKernelUsedSizeKb());
14423        memInfoBuilder.append(" kB\n");
14424        Slog.i(TAG, "Low on memory:");
14425        Slog.i(TAG, shortNativeBuilder.toString());
14426        Slog.i(TAG, fullJavaBuilder.toString());
14427        Slog.i(TAG, memInfoBuilder.toString());
14428
14429        StringBuilder dropBuilder = new StringBuilder(1024);
14430        /*
14431        StringWriter oomSw = new StringWriter();
14432        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14433        StringWriter catSw = new StringWriter();
14434        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14435        String[] emptyArgs = new String[] { };
14436        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14437        oomPw.flush();
14438        String oomString = oomSw.toString();
14439        */
14440        dropBuilder.append("Low on memory:");
14441        dropBuilder.append(stack);
14442        dropBuilder.append('\n');
14443        dropBuilder.append(fullNativeBuilder);
14444        dropBuilder.append(fullJavaBuilder);
14445        dropBuilder.append('\n');
14446        dropBuilder.append(memInfoBuilder);
14447        dropBuilder.append('\n');
14448        /*
14449        dropBuilder.append(oomString);
14450        dropBuilder.append('\n');
14451        */
14452        StringWriter catSw = new StringWriter();
14453        synchronized (ActivityManagerService.this) {
14454            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14455            String[] emptyArgs = new String[] { };
14456            catPw.println();
14457            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14458            catPw.println();
14459            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14460                    false, false, null);
14461            catPw.println();
14462            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14463            catPw.flush();
14464        }
14465        dropBuilder.append(catSw.toString());
14466        addErrorToDropBox("lowmem", null, "system_server", null,
14467                null, tag.toString(), dropBuilder.toString(), null, null);
14468        //Slog.i(TAG, "Sent to dropbox:");
14469        //Slog.i(TAG, dropBuilder.toString());
14470        synchronized (ActivityManagerService.this) {
14471            long now = SystemClock.uptimeMillis();
14472            if (mLastMemUsageReportTime < now) {
14473                mLastMemUsageReportTime = now;
14474            }
14475        }
14476    }
14477
14478    /**
14479     * Searches array of arguments for the specified string
14480     * @param args array of argument strings
14481     * @param value value to search for
14482     * @return true if the value is contained in the array
14483     */
14484    private static boolean scanArgs(String[] args, String value) {
14485        if (args != null) {
14486            for (String arg : args) {
14487                if (value.equals(arg)) {
14488                    return true;
14489                }
14490            }
14491        }
14492        return false;
14493    }
14494
14495    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14496            ContentProviderRecord cpr, boolean always) {
14497        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14498
14499        if (!inLaunching || always) {
14500            synchronized (cpr) {
14501                cpr.launchingApp = null;
14502                cpr.notifyAll();
14503            }
14504            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14505            String names[] = cpr.info.authority.split(";");
14506            for (int j = 0; j < names.length; j++) {
14507                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14508            }
14509        }
14510
14511        for (int i=0; i<cpr.connections.size(); i++) {
14512            ContentProviderConnection conn = cpr.connections.get(i);
14513            if (conn.waiting) {
14514                // If this connection is waiting for the provider, then we don't
14515                // need to mess with its process unless we are always removing
14516                // or for some reason the provider is not currently launching.
14517                if (inLaunching && !always) {
14518                    continue;
14519                }
14520            }
14521            ProcessRecord capp = conn.client;
14522            conn.dead = true;
14523            if (conn.stableCount > 0) {
14524                if (!capp.persistent && capp.thread != null
14525                        && capp.pid != 0
14526                        && capp.pid != MY_PID) {
14527                    capp.kill("depends on provider "
14528                            + cpr.name.flattenToShortString()
14529                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14530                }
14531            } else if (capp.thread != null && conn.provider.provider != null) {
14532                try {
14533                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14534                } catch (RemoteException e) {
14535                }
14536                // In the protocol here, we don't expect the client to correctly
14537                // clean up this connection, we'll just remove it.
14538                cpr.connections.remove(i);
14539                conn.client.conProviders.remove(conn);
14540            }
14541        }
14542
14543        if (inLaunching && always) {
14544            mLaunchingProviders.remove(cpr);
14545        }
14546        return inLaunching;
14547    }
14548
14549    /**
14550     * Main code for cleaning up a process when it has gone away.  This is
14551     * called both as a result of the process dying, or directly when stopping
14552     * a process when running in single process mode.
14553     *
14554     * @return Returns true if the given process has been restarted, so the
14555     * app that was passed in must remain on the process lists.
14556     */
14557    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14558            boolean restarting, boolean allowRestart, int index) {
14559        if (index >= 0) {
14560            removeLruProcessLocked(app);
14561            ProcessList.remove(app.pid);
14562        }
14563
14564        mProcessesToGc.remove(app);
14565        mPendingPssProcesses.remove(app);
14566
14567        // Dismiss any open dialogs.
14568        if (app.crashDialog != null && !app.forceCrashReport) {
14569            app.crashDialog.dismiss();
14570            app.crashDialog = null;
14571        }
14572        if (app.anrDialog != null) {
14573            app.anrDialog.dismiss();
14574            app.anrDialog = null;
14575        }
14576        if (app.waitDialog != null) {
14577            app.waitDialog.dismiss();
14578            app.waitDialog = null;
14579        }
14580
14581        app.crashing = false;
14582        app.notResponding = false;
14583
14584        app.resetPackageList(mProcessStats);
14585        app.unlinkDeathRecipient();
14586        app.makeInactive(mProcessStats);
14587        app.waitingToKill = null;
14588        app.forcingToForeground = null;
14589        updateProcessForegroundLocked(app, false, false);
14590        app.foregroundActivities = false;
14591        app.hasShownUi = false;
14592        app.treatLikeActivity = false;
14593        app.hasAboveClient = false;
14594        app.hasClientActivities = false;
14595
14596        mServices.killServicesLocked(app, allowRestart);
14597
14598        boolean restart = false;
14599
14600        // Remove published content providers.
14601        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14602            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14603            final boolean always = app.bad || !allowRestart;
14604            if (removeDyingProviderLocked(app, cpr, always) || always) {
14605                // We left the provider in the launching list, need to
14606                // restart it.
14607                restart = true;
14608            }
14609
14610            cpr.provider = null;
14611            cpr.proc = null;
14612        }
14613        app.pubProviders.clear();
14614
14615        // Take care of any launching providers waiting for this process.
14616        if (checkAppInLaunchingProvidersLocked(app, false)) {
14617            restart = true;
14618        }
14619
14620        // Unregister from connected content providers.
14621        if (!app.conProviders.isEmpty()) {
14622            for (int i=0; i<app.conProviders.size(); i++) {
14623                ContentProviderConnection conn = app.conProviders.get(i);
14624                conn.provider.connections.remove(conn);
14625            }
14626            app.conProviders.clear();
14627        }
14628
14629        // At this point there may be remaining entries in mLaunchingProviders
14630        // where we were the only one waiting, so they are no longer of use.
14631        // Look for these and clean up if found.
14632        // XXX Commented out for now.  Trying to figure out a way to reproduce
14633        // the actual situation to identify what is actually going on.
14634        if (false) {
14635            for (int i=0; i<mLaunchingProviders.size(); i++) {
14636                ContentProviderRecord cpr = (ContentProviderRecord)
14637                        mLaunchingProviders.get(i);
14638                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14639                    synchronized (cpr) {
14640                        cpr.launchingApp = null;
14641                        cpr.notifyAll();
14642                    }
14643                }
14644            }
14645        }
14646
14647        skipCurrentReceiverLocked(app);
14648
14649        // Unregister any receivers.
14650        for (int i=app.receivers.size()-1; i>=0; i--) {
14651            removeReceiverLocked(app.receivers.valueAt(i));
14652        }
14653        app.receivers.clear();
14654
14655        // If the app is undergoing backup, tell the backup manager about it
14656        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14657            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14658                    + mBackupTarget.appInfo + " died during backup");
14659            try {
14660                IBackupManager bm = IBackupManager.Stub.asInterface(
14661                        ServiceManager.getService(Context.BACKUP_SERVICE));
14662                bm.agentDisconnected(app.info.packageName);
14663            } catch (RemoteException e) {
14664                // can't happen; backup manager is local
14665            }
14666        }
14667
14668        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14669            ProcessChangeItem item = mPendingProcessChanges.get(i);
14670            if (item.pid == app.pid) {
14671                mPendingProcessChanges.remove(i);
14672                mAvailProcessChanges.add(item);
14673            }
14674        }
14675        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14676
14677        // If the caller is restarting this app, then leave it in its
14678        // current lists and let the caller take care of it.
14679        if (restarting) {
14680            return false;
14681        }
14682
14683        if (!app.persistent || app.isolated) {
14684            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14685                    "Removing non-persistent process during cleanup: " + app);
14686            mProcessNames.remove(app.processName, app.uid);
14687            mIsolatedProcesses.remove(app.uid);
14688            if (mHeavyWeightProcess == app) {
14689                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14690                        mHeavyWeightProcess.userId, 0));
14691                mHeavyWeightProcess = null;
14692            }
14693        } else if (!app.removed) {
14694            // This app is persistent, so we need to keep its record around.
14695            // If it is not already on the pending app list, add it there
14696            // and start a new process for it.
14697            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14698                mPersistentStartingProcesses.add(app);
14699                restart = true;
14700            }
14701        }
14702        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14703                "Clean-up removing on hold: " + app);
14704        mProcessesOnHold.remove(app);
14705
14706        if (app == mHomeProcess) {
14707            mHomeProcess = null;
14708        }
14709        if (app == mPreviousProcess) {
14710            mPreviousProcess = null;
14711        }
14712
14713        if (restart && !app.isolated) {
14714            // We have components that still need to be running in the
14715            // process, so re-launch it.
14716            if (index < 0) {
14717                ProcessList.remove(app.pid);
14718            }
14719            mProcessNames.put(app.processName, app.uid, app);
14720            startProcessLocked(app, "restart", app.processName);
14721            return true;
14722        } else if (app.pid > 0 && app.pid != MY_PID) {
14723            // Goodbye!
14724            boolean removed;
14725            synchronized (mPidsSelfLocked) {
14726                mPidsSelfLocked.remove(app.pid);
14727                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14728            }
14729            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14730            if (app.isolated) {
14731                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14732            }
14733            app.setPid(0);
14734        }
14735        return false;
14736    }
14737
14738    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14739        // Look through the content providers we are waiting to have launched,
14740        // and if any run in this process then either schedule a restart of
14741        // the process or kill the client waiting for it if this process has
14742        // gone bad.
14743        int NL = mLaunchingProviders.size();
14744        boolean restart = false;
14745        for (int i=0; i<NL; i++) {
14746            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14747            if (cpr.launchingApp == app) {
14748                if (!alwaysBad && !app.bad) {
14749                    restart = true;
14750                } else {
14751                    removeDyingProviderLocked(app, cpr, true);
14752                    // cpr should have been removed from mLaunchingProviders
14753                    NL = mLaunchingProviders.size();
14754                    i--;
14755                }
14756            }
14757        }
14758        return restart;
14759    }
14760
14761    // =========================================================
14762    // SERVICES
14763    // =========================================================
14764
14765    @Override
14766    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14767            int flags) {
14768        enforceNotIsolatedCaller("getServices");
14769        synchronized (this) {
14770            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14771        }
14772    }
14773
14774    @Override
14775    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14776        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14777        synchronized (this) {
14778            return mServices.getRunningServiceControlPanelLocked(name);
14779        }
14780    }
14781
14782    @Override
14783    public ComponentName startService(IApplicationThread caller, Intent service,
14784            String resolvedType, int userId) {
14785        enforceNotIsolatedCaller("startService");
14786        // Refuse possible leaked file descriptors
14787        if (service != null && service.hasFileDescriptors() == true) {
14788            throw new IllegalArgumentException("File descriptors passed in Intent");
14789        }
14790
14791        if (DEBUG_SERVICE)
14792            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14793        synchronized(this) {
14794            final int callingPid = Binder.getCallingPid();
14795            final int callingUid = Binder.getCallingUid();
14796            final long origId = Binder.clearCallingIdentity();
14797            ComponentName res = mServices.startServiceLocked(caller, service,
14798                    resolvedType, callingPid, callingUid, userId);
14799            Binder.restoreCallingIdentity(origId);
14800            return res;
14801        }
14802    }
14803
14804    ComponentName startServiceInPackage(int uid,
14805            Intent service, String resolvedType, int userId) {
14806        synchronized(this) {
14807            if (DEBUG_SERVICE)
14808                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14809            final long origId = Binder.clearCallingIdentity();
14810            ComponentName res = mServices.startServiceLocked(null, service,
14811                    resolvedType, -1, uid, userId);
14812            Binder.restoreCallingIdentity(origId);
14813            return res;
14814        }
14815    }
14816
14817    @Override
14818    public int stopService(IApplicationThread caller, Intent service,
14819            String resolvedType, int userId) {
14820        enforceNotIsolatedCaller("stopService");
14821        // Refuse possible leaked file descriptors
14822        if (service != null && service.hasFileDescriptors() == true) {
14823            throw new IllegalArgumentException("File descriptors passed in Intent");
14824        }
14825
14826        synchronized(this) {
14827            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14828        }
14829    }
14830
14831    @Override
14832    public IBinder peekService(Intent service, String resolvedType) {
14833        enforceNotIsolatedCaller("peekService");
14834        // Refuse possible leaked file descriptors
14835        if (service != null && service.hasFileDescriptors() == true) {
14836            throw new IllegalArgumentException("File descriptors passed in Intent");
14837        }
14838        synchronized(this) {
14839            return mServices.peekServiceLocked(service, resolvedType);
14840        }
14841    }
14842
14843    @Override
14844    public boolean stopServiceToken(ComponentName className, IBinder token,
14845            int startId) {
14846        synchronized(this) {
14847            return mServices.stopServiceTokenLocked(className, token, startId);
14848        }
14849    }
14850
14851    @Override
14852    public void setServiceForeground(ComponentName className, IBinder token,
14853            int id, Notification notification, boolean removeNotification) {
14854        synchronized(this) {
14855            mServices.setServiceForegroundLocked(className, token, id, notification,
14856                    removeNotification);
14857        }
14858    }
14859
14860    @Override
14861    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14862            boolean requireFull, String name, String callerPackage) {
14863        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14864                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14865    }
14866
14867    int unsafeConvertIncomingUser(int userId) {
14868        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14869                ? mCurrentUserId : userId;
14870    }
14871
14872    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14873            int allowMode, String name, String callerPackage) {
14874        final int callingUserId = UserHandle.getUserId(callingUid);
14875        if (callingUserId == userId) {
14876            return userId;
14877        }
14878
14879        // Note that we may be accessing mCurrentUserId outside of a lock...
14880        // shouldn't be a big deal, if this is being called outside
14881        // of a locked context there is intrinsically a race with
14882        // the value the caller will receive and someone else changing it.
14883        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14884        // we will switch to the calling user if access to the current user fails.
14885        int targetUserId = unsafeConvertIncomingUser(userId);
14886
14887        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14888            final boolean allow;
14889            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14890                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14891                // If the caller has this permission, they always pass go.  And collect $200.
14892                allow = true;
14893            } else if (allowMode == ALLOW_FULL_ONLY) {
14894                // We require full access, sucks to be you.
14895                allow = false;
14896            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14897                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14898                // If the caller does not have either permission, they are always doomed.
14899                allow = false;
14900            } else if (allowMode == ALLOW_NON_FULL) {
14901                // We are blanket allowing non-full access, you lucky caller!
14902                allow = true;
14903            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14904                // We may or may not allow this depending on whether the two users are
14905                // in the same profile.
14906                synchronized (mUserProfileGroupIdsSelfLocked) {
14907                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14908                            UserInfo.NO_PROFILE_GROUP_ID);
14909                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14910                            UserInfo.NO_PROFILE_GROUP_ID);
14911                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14912                            && callingProfile == targetProfile;
14913                }
14914            } else {
14915                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14916            }
14917            if (!allow) {
14918                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14919                    // In this case, they would like to just execute as their
14920                    // owner user instead of failing.
14921                    targetUserId = callingUserId;
14922                } else {
14923                    StringBuilder builder = new StringBuilder(128);
14924                    builder.append("Permission Denial: ");
14925                    builder.append(name);
14926                    if (callerPackage != null) {
14927                        builder.append(" from ");
14928                        builder.append(callerPackage);
14929                    }
14930                    builder.append(" asks to run as user ");
14931                    builder.append(userId);
14932                    builder.append(" but is calling from user ");
14933                    builder.append(UserHandle.getUserId(callingUid));
14934                    builder.append("; this requires ");
14935                    builder.append(INTERACT_ACROSS_USERS_FULL);
14936                    if (allowMode != ALLOW_FULL_ONLY) {
14937                        builder.append(" or ");
14938                        builder.append(INTERACT_ACROSS_USERS);
14939                    }
14940                    String msg = builder.toString();
14941                    Slog.w(TAG, msg);
14942                    throw new SecurityException(msg);
14943                }
14944            }
14945        }
14946        if (!allowAll && targetUserId < 0) {
14947            throw new IllegalArgumentException(
14948                    "Call does not support special user #" + targetUserId);
14949        }
14950        // Check shell permission
14951        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14952            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14953                    targetUserId)) {
14954                throw new SecurityException("Shell does not have permission to access user "
14955                        + targetUserId + "\n " + Debug.getCallers(3));
14956            }
14957        }
14958        return targetUserId;
14959    }
14960
14961    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14962            String className, int flags) {
14963        boolean result = false;
14964        // For apps that don't have pre-defined UIDs, check for permission
14965        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14966            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14967                if (ActivityManager.checkUidPermission(
14968                        INTERACT_ACROSS_USERS,
14969                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14970                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14971                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14972                            + " requests FLAG_SINGLE_USER, but app does not hold "
14973                            + INTERACT_ACROSS_USERS;
14974                    Slog.w(TAG, msg);
14975                    throw new SecurityException(msg);
14976                }
14977                // Permission passed
14978                result = true;
14979            }
14980        } else if ("system".equals(componentProcessName)) {
14981            result = true;
14982        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14983            // Phone app and persistent apps are allowed to export singleuser providers.
14984            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14985                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14986        }
14987        if (DEBUG_MU) {
14988            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14989                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14990        }
14991        return result;
14992    }
14993
14994    /**
14995     * Checks to see if the caller is in the same app as the singleton
14996     * component, or the component is in a special app. It allows special apps
14997     * to export singleton components but prevents exporting singleton
14998     * components for regular apps.
14999     */
15000    boolean isValidSingletonCall(int callingUid, int componentUid) {
15001        int componentAppId = UserHandle.getAppId(componentUid);
15002        return UserHandle.isSameApp(callingUid, componentUid)
15003                || componentAppId == Process.SYSTEM_UID
15004                || componentAppId == Process.PHONE_UID
15005                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15006                        == PackageManager.PERMISSION_GRANTED;
15007    }
15008
15009    public int bindService(IApplicationThread caller, IBinder token,
15010            Intent service, String resolvedType,
15011            IServiceConnection connection, int flags, int userId) {
15012        enforceNotIsolatedCaller("bindService");
15013
15014        // Refuse possible leaked file descriptors
15015        if (service != null && service.hasFileDescriptors() == true) {
15016            throw new IllegalArgumentException("File descriptors passed in Intent");
15017        }
15018
15019        synchronized(this) {
15020            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15021                    connection, flags, userId);
15022        }
15023    }
15024
15025    public boolean unbindService(IServiceConnection connection) {
15026        synchronized (this) {
15027            return mServices.unbindServiceLocked(connection);
15028        }
15029    }
15030
15031    public void publishService(IBinder token, Intent intent, IBinder service) {
15032        // Refuse possible leaked file descriptors
15033        if (intent != null && intent.hasFileDescriptors() == true) {
15034            throw new IllegalArgumentException("File descriptors passed in Intent");
15035        }
15036
15037        synchronized(this) {
15038            if (!(token instanceof ServiceRecord)) {
15039                throw new IllegalArgumentException("Invalid service token");
15040            }
15041            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15042        }
15043    }
15044
15045    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15046        // Refuse possible leaked file descriptors
15047        if (intent != null && intent.hasFileDescriptors() == true) {
15048            throw new IllegalArgumentException("File descriptors passed in Intent");
15049        }
15050
15051        synchronized(this) {
15052            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15053        }
15054    }
15055
15056    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15057        synchronized(this) {
15058            if (!(token instanceof ServiceRecord)) {
15059                throw new IllegalArgumentException("Invalid service token");
15060            }
15061            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15062        }
15063    }
15064
15065    // =========================================================
15066    // BACKUP AND RESTORE
15067    // =========================================================
15068
15069    // Cause the target app to be launched if necessary and its backup agent
15070    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15071    // activity manager to announce its creation.
15072    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15073        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15074        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15075
15076        synchronized(this) {
15077            // !!! TODO: currently no check here that we're already bound
15078            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15079            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15080            synchronized (stats) {
15081                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15082            }
15083
15084            // Backup agent is now in use, its package can't be stopped.
15085            try {
15086                AppGlobals.getPackageManager().setPackageStoppedState(
15087                        app.packageName, false, UserHandle.getUserId(app.uid));
15088            } catch (RemoteException e) {
15089            } catch (IllegalArgumentException e) {
15090                Slog.w(TAG, "Failed trying to unstop package "
15091                        + app.packageName + ": " + e);
15092            }
15093
15094            BackupRecord r = new BackupRecord(ss, app, backupMode);
15095            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15096                    ? new ComponentName(app.packageName, app.backupAgentName)
15097                    : new ComponentName("android", "FullBackupAgent");
15098            // startProcessLocked() returns existing proc's record if it's already running
15099            ProcessRecord proc = startProcessLocked(app.processName, app,
15100                    false, 0, "backup", hostingName, false, false, false);
15101            if (proc == null) {
15102                Slog.e(TAG, "Unable to start backup agent process " + r);
15103                return false;
15104            }
15105
15106            r.app = proc;
15107            mBackupTarget = r;
15108            mBackupAppName = app.packageName;
15109
15110            // Try not to kill the process during backup
15111            updateOomAdjLocked(proc);
15112
15113            // If the process is already attached, schedule the creation of the backup agent now.
15114            // If it is not yet live, this will be done when it attaches to the framework.
15115            if (proc.thread != null) {
15116                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15117                try {
15118                    proc.thread.scheduleCreateBackupAgent(app,
15119                            compatibilityInfoForPackageLocked(app), backupMode);
15120                } catch (RemoteException e) {
15121                    // Will time out on the backup manager side
15122                }
15123            } else {
15124                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15125            }
15126            // Invariants: at this point, the target app process exists and the application
15127            // is either already running or in the process of coming up.  mBackupTarget and
15128            // mBackupAppName describe the app, so that when it binds back to the AM we
15129            // know that it's scheduled for a backup-agent operation.
15130        }
15131
15132        return true;
15133    }
15134
15135    @Override
15136    public void clearPendingBackup() {
15137        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15138        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15139
15140        synchronized (this) {
15141            mBackupTarget = null;
15142            mBackupAppName = null;
15143        }
15144    }
15145
15146    // A backup agent has just come up
15147    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15148        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15149                + " = " + agent);
15150
15151        synchronized(this) {
15152            if (!agentPackageName.equals(mBackupAppName)) {
15153                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15154                return;
15155            }
15156        }
15157
15158        long oldIdent = Binder.clearCallingIdentity();
15159        try {
15160            IBackupManager bm = IBackupManager.Stub.asInterface(
15161                    ServiceManager.getService(Context.BACKUP_SERVICE));
15162            bm.agentConnected(agentPackageName, agent);
15163        } catch (RemoteException e) {
15164            // can't happen; the backup manager service is local
15165        } catch (Exception e) {
15166            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15167            e.printStackTrace();
15168        } finally {
15169            Binder.restoreCallingIdentity(oldIdent);
15170        }
15171    }
15172
15173    // done with this agent
15174    public void unbindBackupAgent(ApplicationInfo appInfo) {
15175        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15176        if (appInfo == null) {
15177            Slog.w(TAG, "unbind backup agent for null app");
15178            return;
15179        }
15180
15181        synchronized(this) {
15182            try {
15183                if (mBackupAppName == null) {
15184                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15185                    return;
15186                }
15187
15188                if (!mBackupAppName.equals(appInfo.packageName)) {
15189                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15190                    return;
15191                }
15192
15193                // Not backing this app up any more; reset its OOM adjustment
15194                final ProcessRecord proc = mBackupTarget.app;
15195                updateOomAdjLocked(proc);
15196
15197                // If the app crashed during backup, 'thread' will be null here
15198                if (proc.thread != null) {
15199                    try {
15200                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15201                                compatibilityInfoForPackageLocked(appInfo));
15202                    } catch (Exception e) {
15203                        Slog.e(TAG, "Exception when unbinding backup agent:");
15204                        e.printStackTrace();
15205                    }
15206                }
15207            } finally {
15208                mBackupTarget = null;
15209                mBackupAppName = null;
15210            }
15211        }
15212    }
15213    // =========================================================
15214    // BROADCASTS
15215    // =========================================================
15216
15217    private final List getStickiesLocked(String action, IntentFilter filter,
15218            List cur, int userId) {
15219        final ContentResolver resolver = mContext.getContentResolver();
15220        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15221        if (stickies == null) {
15222            return cur;
15223        }
15224        final ArrayList<Intent> list = stickies.get(action);
15225        if (list == null) {
15226            return cur;
15227        }
15228        int N = list.size();
15229        for (int i=0; i<N; i++) {
15230            Intent intent = list.get(i);
15231            if (filter.match(resolver, intent, true, TAG) >= 0) {
15232                if (cur == null) {
15233                    cur = new ArrayList<Intent>();
15234                }
15235                cur.add(intent);
15236            }
15237        }
15238        return cur;
15239    }
15240
15241    boolean isPendingBroadcastProcessLocked(int pid) {
15242        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15243                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15244    }
15245
15246    void skipPendingBroadcastLocked(int pid) {
15247            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15248            for (BroadcastQueue queue : mBroadcastQueues) {
15249                queue.skipPendingBroadcastLocked(pid);
15250            }
15251    }
15252
15253    // The app just attached; send any pending broadcasts that it should receive
15254    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15255        boolean didSomething = false;
15256        for (BroadcastQueue queue : mBroadcastQueues) {
15257            didSomething |= queue.sendPendingBroadcastsLocked(app);
15258        }
15259        return didSomething;
15260    }
15261
15262    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15263            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15264        enforceNotIsolatedCaller("registerReceiver");
15265        int callingUid;
15266        int callingPid;
15267        synchronized(this) {
15268            ProcessRecord callerApp = null;
15269            if (caller != null) {
15270                callerApp = getRecordForAppLocked(caller);
15271                if (callerApp == null) {
15272                    throw new SecurityException(
15273                            "Unable to find app for caller " + caller
15274                            + " (pid=" + Binder.getCallingPid()
15275                            + ") when registering receiver " + receiver);
15276                }
15277                if (callerApp.info.uid != Process.SYSTEM_UID &&
15278                        !callerApp.pkgList.containsKey(callerPackage) &&
15279                        !"android".equals(callerPackage)) {
15280                    throw new SecurityException("Given caller package " + callerPackage
15281                            + " is not running in process " + callerApp);
15282                }
15283                callingUid = callerApp.info.uid;
15284                callingPid = callerApp.pid;
15285            } else {
15286                callerPackage = null;
15287                callingUid = Binder.getCallingUid();
15288                callingPid = Binder.getCallingPid();
15289            }
15290
15291            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15292                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15293
15294            List allSticky = null;
15295
15296            // Look for any matching sticky broadcasts...
15297            Iterator actions = filter.actionsIterator();
15298            if (actions != null) {
15299                while (actions.hasNext()) {
15300                    String action = (String)actions.next();
15301                    allSticky = getStickiesLocked(action, filter, allSticky,
15302                            UserHandle.USER_ALL);
15303                    allSticky = getStickiesLocked(action, filter, allSticky,
15304                            UserHandle.getUserId(callingUid));
15305                }
15306            } else {
15307                allSticky = getStickiesLocked(null, filter, allSticky,
15308                        UserHandle.USER_ALL);
15309                allSticky = getStickiesLocked(null, filter, allSticky,
15310                        UserHandle.getUserId(callingUid));
15311            }
15312
15313            // The first sticky in the list is returned directly back to
15314            // the client.
15315            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15316
15317            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15318                    + ": " + sticky);
15319
15320            if (receiver == null) {
15321                return sticky;
15322            }
15323
15324            ReceiverList rl
15325                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15326            if (rl == null) {
15327                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15328                        userId, receiver);
15329                if (rl.app != null) {
15330                    rl.app.receivers.add(rl);
15331                } else {
15332                    try {
15333                        receiver.asBinder().linkToDeath(rl, 0);
15334                    } catch (RemoteException e) {
15335                        return sticky;
15336                    }
15337                    rl.linkedToDeath = true;
15338                }
15339                mRegisteredReceivers.put(receiver.asBinder(), rl);
15340            } else if (rl.uid != callingUid) {
15341                throw new IllegalArgumentException(
15342                        "Receiver requested to register for uid " + callingUid
15343                        + " was previously registered for uid " + rl.uid);
15344            } else if (rl.pid != callingPid) {
15345                throw new IllegalArgumentException(
15346                        "Receiver requested to register for pid " + callingPid
15347                        + " was previously registered for pid " + rl.pid);
15348            } else if (rl.userId != userId) {
15349                throw new IllegalArgumentException(
15350                        "Receiver requested to register for user " + userId
15351                        + " was previously registered for user " + rl.userId);
15352            }
15353            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15354                    permission, callingUid, userId);
15355            rl.add(bf);
15356            if (!bf.debugCheck()) {
15357                Slog.w(TAG, "==> For Dynamic broadast");
15358            }
15359            mReceiverResolver.addFilter(bf);
15360
15361            // Enqueue broadcasts for all existing stickies that match
15362            // this filter.
15363            if (allSticky != null) {
15364                ArrayList receivers = new ArrayList();
15365                receivers.add(bf);
15366
15367                int N = allSticky.size();
15368                for (int i=0; i<N; i++) {
15369                    Intent intent = (Intent)allSticky.get(i);
15370                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15371                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15372                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15373                            null, null, false, true, true, -1);
15374                    queue.enqueueParallelBroadcastLocked(r);
15375                    queue.scheduleBroadcastsLocked();
15376                }
15377            }
15378
15379            return sticky;
15380        }
15381    }
15382
15383    public void unregisterReceiver(IIntentReceiver receiver) {
15384        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15385
15386        final long origId = Binder.clearCallingIdentity();
15387        try {
15388            boolean doTrim = false;
15389
15390            synchronized(this) {
15391                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15392                if (rl != null) {
15393                    if (rl.curBroadcast != null) {
15394                        BroadcastRecord r = rl.curBroadcast;
15395                        final boolean doNext = finishReceiverLocked(
15396                                receiver.asBinder(), r.resultCode, r.resultData,
15397                                r.resultExtras, r.resultAbort);
15398                        if (doNext) {
15399                            doTrim = true;
15400                            r.queue.processNextBroadcast(false);
15401                        }
15402                    }
15403
15404                    if (rl.app != null) {
15405                        rl.app.receivers.remove(rl);
15406                    }
15407                    removeReceiverLocked(rl);
15408                    if (rl.linkedToDeath) {
15409                        rl.linkedToDeath = false;
15410                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15411                    }
15412                }
15413            }
15414
15415            // If we actually concluded any broadcasts, we might now be able
15416            // to trim the recipients' apps from our working set
15417            if (doTrim) {
15418                trimApplications();
15419                return;
15420            }
15421
15422        } finally {
15423            Binder.restoreCallingIdentity(origId);
15424        }
15425    }
15426
15427    void removeReceiverLocked(ReceiverList rl) {
15428        mRegisteredReceivers.remove(rl.receiver.asBinder());
15429        int N = rl.size();
15430        for (int i=0; i<N; i++) {
15431            mReceiverResolver.removeFilter(rl.get(i));
15432        }
15433    }
15434
15435    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15436        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15437            ProcessRecord r = mLruProcesses.get(i);
15438            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15439                try {
15440                    r.thread.dispatchPackageBroadcast(cmd, packages);
15441                } catch (RemoteException ex) {
15442                }
15443            }
15444        }
15445    }
15446
15447    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15448            int callingUid, int[] users) {
15449        List<ResolveInfo> receivers = null;
15450        try {
15451            HashSet<ComponentName> singleUserReceivers = null;
15452            boolean scannedFirstReceivers = false;
15453            for (int user : users) {
15454                // Skip users that have Shell restrictions
15455                if (callingUid == Process.SHELL_UID
15456                        && getUserManagerLocked().hasUserRestriction(
15457                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15458                    continue;
15459                }
15460                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15461                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15462                if (user != 0 && newReceivers != null) {
15463                    // If this is not the primary user, we need to check for
15464                    // any receivers that should be filtered out.
15465                    for (int i=0; i<newReceivers.size(); i++) {
15466                        ResolveInfo ri = newReceivers.get(i);
15467                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15468                            newReceivers.remove(i);
15469                            i--;
15470                        }
15471                    }
15472                }
15473                if (newReceivers != null && newReceivers.size() == 0) {
15474                    newReceivers = null;
15475                }
15476                if (receivers == null) {
15477                    receivers = newReceivers;
15478                } else if (newReceivers != null) {
15479                    // We need to concatenate the additional receivers
15480                    // found with what we have do far.  This would be easy,
15481                    // but we also need to de-dup any receivers that are
15482                    // singleUser.
15483                    if (!scannedFirstReceivers) {
15484                        // Collect any single user receivers we had already retrieved.
15485                        scannedFirstReceivers = true;
15486                        for (int i=0; i<receivers.size(); i++) {
15487                            ResolveInfo ri = receivers.get(i);
15488                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15489                                ComponentName cn = new ComponentName(
15490                                        ri.activityInfo.packageName, ri.activityInfo.name);
15491                                if (singleUserReceivers == null) {
15492                                    singleUserReceivers = new HashSet<ComponentName>();
15493                                }
15494                                singleUserReceivers.add(cn);
15495                            }
15496                        }
15497                    }
15498                    // Add the new results to the existing results, tracking
15499                    // and de-dupping single user receivers.
15500                    for (int i=0; i<newReceivers.size(); i++) {
15501                        ResolveInfo ri = newReceivers.get(i);
15502                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15503                            ComponentName cn = new ComponentName(
15504                                    ri.activityInfo.packageName, ri.activityInfo.name);
15505                            if (singleUserReceivers == null) {
15506                                singleUserReceivers = new HashSet<ComponentName>();
15507                            }
15508                            if (!singleUserReceivers.contains(cn)) {
15509                                singleUserReceivers.add(cn);
15510                                receivers.add(ri);
15511                            }
15512                        } else {
15513                            receivers.add(ri);
15514                        }
15515                    }
15516                }
15517            }
15518        } catch (RemoteException ex) {
15519            // pm is in same process, this will never happen.
15520        }
15521        return receivers;
15522    }
15523
15524    private final int broadcastIntentLocked(ProcessRecord callerApp,
15525            String callerPackage, Intent intent, String resolvedType,
15526            IIntentReceiver resultTo, int resultCode, String resultData,
15527            Bundle map, String requiredPermission, int appOp,
15528            boolean ordered, boolean sticky, int callingPid, int callingUid,
15529            int userId) {
15530        intent = new Intent(intent);
15531
15532        // By default broadcasts do not go to stopped apps.
15533        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15534
15535        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15536            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15537            + " ordered=" + ordered + " userid=" + userId);
15538        if ((resultTo != null) && !ordered) {
15539            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15540        }
15541
15542        userId = handleIncomingUser(callingPid, callingUid, userId,
15543                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15544
15545        // Make sure that the user who is receiving this broadcast is started.
15546        // If not, we will just skip it.
15547
15548        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15549            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15550                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15551                Slog.w(TAG, "Skipping broadcast of " + intent
15552                        + ": user " + userId + " is stopped");
15553                return ActivityManager.BROADCAST_SUCCESS;
15554            }
15555        }
15556
15557        /*
15558         * Prevent non-system code (defined here to be non-persistent
15559         * processes) from sending protected broadcasts.
15560         */
15561        int callingAppId = UserHandle.getAppId(callingUid);
15562        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15563            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15564            || callingAppId == Process.NFC_UID || callingUid == 0) {
15565            // Always okay.
15566        } else if (callerApp == null || !callerApp.persistent) {
15567            try {
15568                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15569                        intent.getAction())) {
15570                    String msg = "Permission Denial: not allowed to send broadcast "
15571                            + intent.getAction() + " from pid="
15572                            + callingPid + ", uid=" + callingUid;
15573                    Slog.w(TAG, msg);
15574                    throw new SecurityException(msg);
15575                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15576                    // Special case for compatibility: we don't want apps to send this,
15577                    // but historically it has not been protected and apps may be using it
15578                    // to poke their own app widget.  So, instead of making it protected,
15579                    // just limit it to the caller.
15580                    if (callerApp == null) {
15581                        String msg = "Permission Denial: not allowed to send broadcast "
15582                                + intent.getAction() + " from unknown caller.";
15583                        Slog.w(TAG, msg);
15584                        throw new SecurityException(msg);
15585                    } else if (intent.getComponent() != null) {
15586                        // They are good enough to send to an explicit component...  verify
15587                        // it is being sent to the calling app.
15588                        if (!intent.getComponent().getPackageName().equals(
15589                                callerApp.info.packageName)) {
15590                            String msg = "Permission Denial: not allowed to send broadcast "
15591                                    + intent.getAction() + " to "
15592                                    + intent.getComponent().getPackageName() + " from "
15593                                    + callerApp.info.packageName;
15594                            Slog.w(TAG, msg);
15595                            throw new SecurityException(msg);
15596                        }
15597                    } else {
15598                        // Limit broadcast to their own package.
15599                        intent.setPackage(callerApp.info.packageName);
15600                    }
15601                }
15602            } catch (RemoteException e) {
15603                Slog.w(TAG, "Remote exception", e);
15604                return ActivityManager.BROADCAST_SUCCESS;
15605            }
15606        }
15607
15608        // Handle special intents: if this broadcast is from the package
15609        // manager about a package being removed, we need to remove all of
15610        // its activities from the history stack.
15611        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15612                intent.getAction());
15613        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15614                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15615                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15616                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15617                || uidRemoved) {
15618            if (checkComponentPermission(
15619                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15620                    callingPid, callingUid, -1, true)
15621                    == PackageManager.PERMISSION_GRANTED) {
15622                if (uidRemoved) {
15623                    final Bundle intentExtras = intent.getExtras();
15624                    final int uid = intentExtras != null
15625                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15626                    if (uid >= 0) {
15627                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15628                        synchronized (bs) {
15629                            bs.removeUidStatsLocked(uid);
15630                        }
15631                        mAppOpsService.uidRemoved(uid);
15632                    }
15633                } else {
15634                    // If resources are unavailable just force stop all
15635                    // those packages and flush the attribute cache as well.
15636                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15637                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15638                        if (list != null && (list.length > 0)) {
15639                            for (String pkg : list) {
15640                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15641                                        "storage unmount");
15642                            }
15643                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15644                            sendPackageBroadcastLocked(
15645                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15646                        }
15647                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15648                            intent.getAction())) {
15649                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15650                    } else {
15651                        Uri data = intent.getData();
15652                        String ssp;
15653                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15654                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15655                                    intent.getAction());
15656                            boolean fullUninstall = removed &&
15657                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15658                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15659                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15660                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15661                                        false, fullUninstall, userId,
15662                                        removed ? "pkg removed" : "pkg changed");
15663                            }
15664                            if (removed) {
15665                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15666                                        new String[] {ssp}, userId);
15667                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15668                                    mAppOpsService.packageRemoved(
15669                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15670
15671                                    // Remove all permissions granted from/to this package
15672                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15673                                }
15674                            }
15675                        }
15676                    }
15677                }
15678            } else {
15679                String msg = "Permission Denial: " + intent.getAction()
15680                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15681                        + ", uid=" + callingUid + ")"
15682                        + " requires "
15683                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15684                Slog.w(TAG, msg);
15685                throw new SecurityException(msg);
15686            }
15687
15688        // Special case for adding a package: by default turn on compatibility
15689        // mode.
15690        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15691            Uri data = intent.getData();
15692            String ssp;
15693            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15694                mCompatModePackages.handlePackageAddedLocked(ssp,
15695                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15696            }
15697        }
15698
15699        /*
15700         * If this is the time zone changed action, queue up a message that will reset the timezone
15701         * of all currently running processes. This message will get queued up before the broadcast
15702         * happens.
15703         */
15704        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15705            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15706        }
15707
15708        /*
15709         * If the user set the time, let all running processes know.
15710         */
15711        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15712            final int is24Hour = intent.getBooleanExtra(
15713                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15714            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15715            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15716            synchronized (stats) {
15717                stats.noteCurrentTimeChangedLocked();
15718            }
15719        }
15720
15721        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15722            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15723        }
15724
15725        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15726            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15727            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15728        }
15729
15730        // Add to the sticky list if requested.
15731        if (sticky) {
15732            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15733                    callingPid, callingUid)
15734                    != PackageManager.PERMISSION_GRANTED) {
15735                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15736                        + callingPid + ", uid=" + callingUid
15737                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15738                Slog.w(TAG, msg);
15739                throw new SecurityException(msg);
15740            }
15741            if (requiredPermission != null) {
15742                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15743                        + " and enforce permission " + requiredPermission);
15744                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15745            }
15746            if (intent.getComponent() != null) {
15747                throw new SecurityException(
15748                        "Sticky broadcasts can't target a specific component");
15749            }
15750            // We use userId directly here, since the "all" target is maintained
15751            // as a separate set of sticky broadcasts.
15752            if (userId != UserHandle.USER_ALL) {
15753                // But first, if this is not a broadcast to all users, then
15754                // make sure it doesn't conflict with an existing broadcast to
15755                // all users.
15756                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15757                        UserHandle.USER_ALL);
15758                if (stickies != null) {
15759                    ArrayList<Intent> list = stickies.get(intent.getAction());
15760                    if (list != null) {
15761                        int N = list.size();
15762                        int i;
15763                        for (i=0; i<N; i++) {
15764                            if (intent.filterEquals(list.get(i))) {
15765                                throw new IllegalArgumentException(
15766                                        "Sticky broadcast " + intent + " for user "
15767                                        + userId + " conflicts with existing global broadcast");
15768                            }
15769                        }
15770                    }
15771                }
15772            }
15773            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15774            if (stickies == null) {
15775                stickies = new ArrayMap<String, ArrayList<Intent>>();
15776                mStickyBroadcasts.put(userId, stickies);
15777            }
15778            ArrayList<Intent> list = stickies.get(intent.getAction());
15779            if (list == null) {
15780                list = new ArrayList<Intent>();
15781                stickies.put(intent.getAction(), list);
15782            }
15783            int N = list.size();
15784            int i;
15785            for (i=0; i<N; i++) {
15786                if (intent.filterEquals(list.get(i))) {
15787                    // This sticky already exists, replace it.
15788                    list.set(i, new Intent(intent));
15789                    break;
15790                }
15791            }
15792            if (i >= N) {
15793                list.add(new Intent(intent));
15794            }
15795        }
15796
15797        int[] users;
15798        if (userId == UserHandle.USER_ALL) {
15799            // Caller wants broadcast to go to all started users.
15800            users = mStartedUserArray;
15801        } else {
15802            // Caller wants broadcast to go to one specific user.
15803            users = new int[] {userId};
15804        }
15805
15806        // Figure out who all will receive this broadcast.
15807        List receivers = null;
15808        List<BroadcastFilter> registeredReceivers = null;
15809        // Need to resolve the intent to interested receivers...
15810        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15811                 == 0) {
15812            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15813        }
15814        if (intent.getComponent() == null) {
15815            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15816                // Query one target user at a time, excluding shell-restricted users
15817                UserManagerService ums = getUserManagerLocked();
15818                for (int i = 0; i < users.length; i++) {
15819                    if (ums.hasUserRestriction(
15820                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15821                        continue;
15822                    }
15823                    List<BroadcastFilter> registeredReceiversForUser =
15824                            mReceiverResolver.queryIntent(intent,
15825                                    resolvedType, false, users[i]);
15826                    if (registeredReceivers == null) {
15827                        registeredReceivers = registeredReceiversForUser;
15828                    } else if (registeredReceiversForUser != null) {
15829                        registeredReceivers.addAll(registeredReceiversForUser);
15830                    }
15831                }
15832            } else {
15833                registeredReceivers = mReceiverResolver.queryIntent(intent,
15834                        resolvedType, false, userId);
15835            }
15836        }
15837
15838        final boolean replacePending =
15839                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15840
15841        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15842                + " replacePending=" + replacePending);
15843
15844        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15845        if (!ordered && NR > 0) {
15846            // If we are not serializing this broadcast, then send the
15847            // registered receivers separately so they don't wait for the
15848            // components to be launched.
15849            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15850            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15851                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15852                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15853                    ordered, sticky, false, userId);
15854            if (DEBUG_BROADCAST) Slog.v(
15855                    TAG, "Enqueueing parallel broadcast " + r);
15856            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15857            if (!replaced) {
15858                queue.enqueueParallelBroadcastLocked(r);
15859                queue.scheduleBroadcastsLocked();
15860            }
15861            registeredReceivers = null;
15862            NR = 0;
15863        }
15864
15865        // Merge into one list.
15866        int ir = 0;
15867        if (receivers != null) {
15868            // A special case for PACKAGE_ADDED: do not allow the package
15869            // being added to see this broadcast.  This prevents them from
15870            // using this as a back door to get run as soon as they are
15871            // installed.  Maybe in the future we want to have a special install
15872            // broadcast or such for apps, but we'd like to deliberately make
15873            // this decision.
15874            String skipPackages[] = null;
15875            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15876                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15877                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15878                Uri data = intent.getData();
15879                if (data != null) {
15880                    String pkgName = data.getSchemeSpecificPart();
15881                    if (pkgName != null) {
15882                        skipPackages = new String[] { pkgName };
15883                    }
15884                }
15885            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15886                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15887            }
15888            if (skipPackages != null && (skipPackages.length > 0)) {
15889                for (String skipPackage : skipPackages) {
15890                    if (skipPackage != null) {
15891                        int NT = receivers.size();
15892                        for (int it=0; it<NT; it++) {
15893                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15894                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15895                                receivers.remove(it);
15896                                it--;
15897                                NT--;
15898                            }
15899                        }
15900                    }
15901                }
15902            }
15903
15904            int NT = receivers != null ? receivers.size() : 0;
15905            int it = 0;
15906            ResolveInfo curt = null;
15907            BroadcastFilter curr = null;
15908            while (it < NT && ir < NR) {
15909                if (curt == null) {
15910                    curt = (ResolveInfo)receivers.get(it);
15911                }
15912                if (curr == null) {
15913                    curr = registeredReceivers.get(ir);
15914                }
15915                if (curr.getPriority() >= curt.priority) {
15916                    // Insert this broadcast record into the final list.
15917                    receivers.add(it, curr);
15918                    ir++;
15919                    curr = null;
15920                    it++;
15921                    NT++;
15922                } else {
15923                    // Skip to the next ResolveInfo in the final list.
15924                    it++;
15925                    curt = null;
15926                }
15927            }
15928        }
15929        while (ir < NR) {
15930            if (receivers == null) {
15931                receivers = new ArrayList();
15932            }
15933            receivers.add(registeredReceivers.get(ir));
15934            ir++;
15935        }
15936
15937        if ((receivers != null && receivers.size() > 0)
15938                || resultTo != null) {
15939            BroadcastQueue queue = broadcastQueueForIntent(intent);
15940            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15941                    callerPackage, callingPid, callingUid, resolvedType,
15942                    requiredPermission, appOp, receivers, resultTo, resultCode,
15943                    resultData, map, ordered, sticky, false, userId);
15944            if (DEBUG_BROADCAST) Slog.v(
15945                    TAG, "Enqueueing ordered broadcast " + r
15946                    + ": prev had " + queue.mOrderedBroadcasts.size());
15947            if (DEBUG_BROADCAST) {
15948                int seq = r.intent.getIntExtra("seq", -1);
15949                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15950            }
15951            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15952            if (!replaced) {
15953                queue.enqueueOrderedBroadcastLocked(r);
15954                queue.scheduleBroadcastsLocked();
15955            }
15956        }
15957
15958        return ActivityManager.BROADCAST_SUCCESS;
15959    }
15960
15961    final Intent verifyBroadcastLocked(Intent intent) {
15962        // Refuse possible leaked file descriptors
15963        if (intent != null && intent.hasFileDescriptors() == true) {
15964            throw new IllegalArgumentException("File descriptors passed in Intent");
15965        }
15966
15967        int flags = intent.getFlags();
15968
15969        if (!mProcessesReady) {
15970            // if the caller really truly claims to know what they're doing, go
15971            // ahead and allow the broadcast without launching any receivers
15972            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15973                intent = new Intent(intent);
15974                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15975            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15976                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15977                        + " before boot completion");
15978                throw new IllegalStateException("Cannot broadcast before boot completed");
15979            }
15980        }
15981
15982        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15983            throw new IllegalArgumentException(
15984                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15985        }
15986
15987        return intent;
15988    }
15989
15990    public final int broadcastIntent(IApplicationThread caller,
15991            Intent intent, String resolvedType, IIntentReceiver resultTo,
15992            int resultCode, String resultData, Bundle map,
15993            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15994        enforceNotIsolatedCaller("broadcastIntent");
15995        synchronized(this) {
15996            intent = verifyBroadcastLocked(intent);
15997
15998            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15999            final int callingPid = Binder.getCallingPid();
16000            final int callingUid = Binder.getCallingUid();
16001            final long origId = Binder.clearCallingIdentity();
16002            int res = broadcastIntentLocked(callerApp,
16003                    callerApp != null ? callerApp.info.packageName : null,
16004                    intent, resolvedType, resultTo,
16005                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16006                    callingPid, callingUid, userId);
16007            Binder.restoreCallingIdentity(origId);
16008            return res;
16009        }
16010    }
16011
16012    int broadcastIntentInPackage(String packageName, int uid,
16013            Intent intent, String resolvedType, IIntentReceiver resultTo,
16014            int resultCode, String resultData, Bundle map,
16015            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16016        synchronized(this) {
16017            intent = verifyBroadcastLocked(intent);
16018
16019            final long origId = Binder.clearCallingIdentity();
16020            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16021                    resultTo, resultCode, resultData, map, requiredPermission,
16022                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16023            Binder.restoreCallingIdentity(origId);
16024            return res;
16025        }
16026    }
16027
16028    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16029        // Refuse possible leaked file descriptors
16030        if (intent != null && intent.hasFileDescriptors() == true) {
16031            throw new IllegalArgumentException("File descriptors passed in Intent");
16032        }
16033
16034        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16035                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16036
16037        synchronized(this) {
16038            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16039                    != PackageManager.PERMISSION_GRANTED) {
16040                String msg = "Permission Denial: unbroadcastIntent() from pid="
16041                        + Binder.getCallingPid()
16042                        + ", uid=" + Binder.getCallingUid()
16043                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16044                Slog.w(TAG, msg);
16045                throw new SecurityException(msg);
16046            }
16047            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16048            if (stickies != null) {
16049                ArrayList<Intent> list = stickies.get(intent.getAction());
16050                if (list != null) {
16051                    int N = list.size();
16052                    int i;
16053                    for (i=0; i<N; i++) {
16054                        if (intent.filterEquals(list.get(i))) {
16055                            list.remove(i);
16056                            break;
16057                        }
16058                    }
16059                    if (list.size() <= 0) {
16060                        stickies.remove(intent.getAction());
16061                    }
16062                }
16063                if (stickies.size() <= 0) {
16064                    mStickyBroadcasts.remove(userId);
16065                }
16066            }
16067        }
16068    }
16069
16070    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16071            String resultData, Bundle resultExtras, boolean resultAbort) {
16072        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16073        if (r == null) {
16074            Slog.w(TAG, "finishReceiver called but not found on queue");
16075            return false;
16076        }
16077
16078        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16079    }
16080
16081    void backgroundServicesFinishedLocked(int userId) {
16082        for (BroadcastQueue queue : mBroadcastQueues) {
16083            queue.backgroundServicesFinishedLocked(userId);
16084        }
16085    }
16086
16087    public void finishReceiver(IBinder who, int resultCode, String resultData,
16088            Bundle resultExtras, boolean resultAbort) {
16089        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16090
16091        // Refuse possible leaked file descriptors
16092        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16093            throw new IllegalArgumentException("File descriptors passed in Bundle");
16094        }
16095
16096        final long origId = Binder.clearCallingIdentity();
16097        try {
16098            boolean doNext = false;
16099            BroadcastRecord r;
16100
16101            synchronized(this) {
16102                r = broadcastRecordForReceiverLocked(who);
16103                if (r != null) {
16104                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16105                        resultData, resultExtras, resultAbort, true);
16106                }
16107            }
16108
16109            if (doNext) {
16110                r.queue.processNextBroadcast(false);
16111            }
16112            trimApplications();
16113        } finally {
16114            Binder.restoreCallingIdentity(origId);
16115        }
16116    }
16117
16118    // =========================================================
16119    // INSTRUMENTATION
16120    // =========================================================
16121
16122    public boolean startInstrumentation(ComponentName className,
16123            String profileFile, int flags, Bundle arguments,
16124            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16125            int userId, String abiOverride) {
16126        enforceNotIsolatedCaller("startInstrumentation");
16127        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16128                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16129        // Refuse possible leaked file descriptors
16130        if (arguments != null && arguments.hasFileDescriptors()) {
16131            throw new IllegalArgumentException("File descriptors passed in Bundle");
16132        }
16133
16134        synchronized(this) {
16135            InstrumentationInfo ii = null;
16136            ApplicationInfo ai = null;
16137            try {
16138                ii = mContext.getPackageManager().getInstrumentationInfo(
16139                    className, STOCK_PM_FLAGS);
16140                ai = AppGlobals.getPackageManager().getApplicationInfo(
16141                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16142            } catch (PackageManager.NameNotFoundException e) {
16143            } catch (RemoteException e) {
16144            }
16145            if (ii == null) {
16146                reportStartInstrumentationFailure(watcher, className,
16147                        "Unable to find instrumentation info for: " + className);
16148                return false;
16149            }
16150            if (ai == null) {
16151                reportStartInstrumentationFailure(watcher, className,
16152                        "Unable to find instrumentation target package: " + ii.targetPackage);
16153                return false;
16154            }
16155
16156            int match = mContext.getPackageManager().checkSignatures(
16157                    ii.targetPackage, ii.packageName);
16158            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16159                String msg = "Permission Denial: starting instrumentation "
16160                        + className + " from pid="
16161                        + Binder.getCallingPid()
16162                        + ", uid=" + Binder.getCallingPid()
16163                        + " not allowed because package " + ii.packageName
16164                        + " does not have a signature matching the target "
16165                        + ii.targetPackage;
16166                reportStartInstrumentationFailure(watcher, className, msg);
16167                throw new SecurityException(msg);
16168            }
16169
16170            final long origId = Binder.clearCallingIdentity();
16171            // Instrumentation can kill and relaunch even persistent processes
16172            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16173                    "start instr");
16174            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16175            app.instrumentationClass = className;
16176            app.instrumentationInfo = ai;
16177            app.instrumentationProfileFile = profileFile;
16178            app.instrumentationArguments = arguments;
16179            app.instrumentationWatcher = watcher;
16180            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16181            app.instrumentationResultClass = className;
16182            Binder.restoreCallingIdentity(origId);
16183        }
16184
16185        return true;
16186    }
16187
16188    /**
16189     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16190     * error to the logs, but if somebody is watching, send the report there too.  This enables
16191     * the "am" command to report errors with more information.
16192     *
16193     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16194     * @param cn The component name of the instrumentation.
16195     * @param report The error report.
16196     */
16197    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16198            ComponentName cn, String report) {
16199        Slog.w(TAG, report);
16200        try {
16201            if (watcher != null) {
16202                Bundle results = new Bundle();
16203                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16204                results.putString("Error", report);
16205                watcher.instrumentationStatus(cn, -1, results);
16206            }
16207        } catch (RemoteException e) {
16208            Slog.w(TAG, e);
16209        }
16210    }
16211
16212    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16213        if (app.instrumentationWatcher != null) {
16214            try {
16215                // NOTE:  IInstrumentationWatcher *must* be oneway here
16216                app.instrumentationWatcher.instrumentationFinished(
16217                    app.instrumentationClass,
16218                    resultCode,
16219                    results);
16220            } catch (RemoteException e) {
16221            }
16222        }
16223        if (app.instrumentationUiAutomationConnection != null) {
16224            try {
16225                app.instrumentationUiAutomationConnection.shutdown();
16226            } catch (RemoteException re) {
16227                /* ignore */
16228            }
16229            // Only a UiAutomation can set this flag and now that
16230            // it is finished we make sure it is reset to its default.
16231            mUserIsMonkey = false;
16232        }
16233        app.instrumentationWatcher = null;
16234        app.instrumentationUiAutomationConnection = null;
16235        app.instrumentationClass = null;
16236        app.instrumentationInfo = null;
16237        app.instrumentationProfileFile = null;
16238        app.instrumentationArguments = null;
16239
16240        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16241                "finished inst");
16242    }
16243
16244    public void finishInstrumentation(IApplicationThread target,
16245            int resultCode, Bundle results) {
16246        int userId = UserHandle.getCallingUserId();
16247        // Refuse possible leaked file descriptors
16248        if (results != null && results.hasFileDescriptors()) {
16249            throw new IllegalArgumentException("File descriptors passed in Intent");
16250        }
16251
16252        synchronized(this) {
16253            ProcessRecord app = getRecordForAppLocked(target);
16254            if (app == null) {
16255                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16256                return;
16257            }
16258            final long origId = Binder.clearCallingIdentity();
16259            finishInstrumentationLocked(app, resultCode, results);
16260            Binder.restoreCallingIdentity(origId);
16261        }
16262    }
16263
16264    // =========================================================
16265    // CONFIGURATION
16266    // =========================================================
16267
16268    public ConfigurationInfo getDeviceConfigurationInfo() {
16269        ConfigurationInfo config = new ConfigurationInfo();
16270        synchronized (this) {
16271            config.reqTouchScreen = mConfiguration.touchscreen;
16272            config.reqKeyboardType = mConfiguration.keyboard;
16273            config.reqNavigation = mConfiguration.navigation;
16274            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16275                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16276                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16277            }
16278            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16279                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16280                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16281            }
16282            config.reqGlEsVersion = GL_ES_VERSION;
16283        }
16284        return config;
16285    }
16286
16287    ActivityStack getFocusedStack() {
16288        return mStackSupervisor.getFocusedStack();
16289    }
16290
16291    public Configuration getConfiguration() {
16292        Configuration ci;
16293        synchronized(this) {
16294            ci = new Configuration(mConfiguration);
16295        }
16296        return ci;
16297    }
16298
16299    public void updatePersistentConfiguration(Configuration values) {
16300        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16301                "updateConfiguration()");
16302        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16303                "updateConfiguration()");
16304        if (values == null) {
16305            throw new NullPointerException("Configuration must not be null");
16306        }
16307
16308        synchronized(this) {
16309            final long origId = Binder.clearCallingIdentity();
16310            updateConfigurationLocked(values, null, true, false);
16311            Binder.restoreCallingIdentity(origId);
16312        }
16313    }
16314
16315    public void updateConfiguration(Configuration values) {
16316        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16317                "updateConfiguration()");
16318
16319        synchronized(this) {
16320            if (values == null && mWindowManager != null) {
16321                // sentinel: fetch the current configuration from the window manager
16322                values = mWindowManager.computeNewConfiguration();
16323            }
16324
16325            if (mWindowManager != null) {
16326                mProcessList.applyDisplaySize(mWindowManager);
16327            }
16328
16329            final long origId = Binder.clearCallingIdentity();
16330            if (values != null) {
16331                Settings.System.clearConfiguration(values);
16332            }
16333            updateConfigurationLocked(values, null, false, false);
16334            Binder.restoreCallingIdentity(origId);
16335        }
16336    }
16337
16338    /**
16339     * Do either or both things: (1) change the current configuration, and (2)
16340     * make sure the given activity is running with the (now) current
16341     * configuration.  Returns true if the activity has been left running, or
16342     * false if <var>starting</var> is being destroyed to match the new
16343     * configuration.
16344     * @param persistent TODO
16345     */
16346    boolean updateConfigurationLocked(Configuration values,
16347            ActivityRecord starting, boolean persistent, boolean initLocale) {
16348        int changes = 0;
16349
16350        if (values != null) {
16351            Configuration newConfig = new Configuration(mConfiguration);
16352            changes = newConfig.updateFrom(values);
16353            if (changes != 0) {
16354                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16355                    Slog.i(TAG, "Updating configuration to: " + values);
16356                }
16357
16358                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16359
16360                if (values.locale != null && !initLocale) {
16361                    saveLocaleLocked(values.locale,
16362                                     !values.locale.equals(mConfiguration.locale),
16363                                     values.userSetLocale);
16364                }
16365
16366                mConfigurationSeq++;
16367                if (mConfigurationSeq <= 0) {
16368                    mConfigurationSeq = 1;
16369                }
16370                newConfig.seq = mConfigurationSeq;
16371                mConfiguration = newConfig;
16372                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16373                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16374                //mUsageStatsService.noteStartConfig(newConfig);
16375
16376                final Configuration configCopy = new Configuration(mConfiguration);
16377
16378                // TODO: If our config changes, should we auto dismiss any currently
16379                // showing dialogs?
16380                mShowDialogs = shouldShowDialogs(newConfig);
16381
16382                AttributeCache ac = AttributeCache.instance();
16383                if (ac != null) {
16384                    ac.updateConfiguration(configCopy);
16385                }
16386
16387                // Make sure all resources in our process are updated
16388                // right now, so that anyone who is going to retrieve
16389                // resource values after we return will be sure to get
16390                // the new ones.  This is especially important during
16391                // boot, where the first config change needs to guarantee
16392                // all resources have that config before following boot
16393                // code is executed.
16394                mSystemThread.applyConfigurationToResources(configCopy);
16395
16396                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16397                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16398                    msg.obj = new Configuration(configCopy);
16399                    mHandler.sendMessage(msg);
16400                }
16401
16402                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16403                    ProcessRecord app = mLruProcesses.get(i);
16404                    try {
16405                        if (app.thread != null) {
16406                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16407                                    + app.processName + " new config " + mConfiguration);
16408                            app.thread.scheduleConfigurationChanged(configCopy);
16409                        }
16410                    } catch (Exception e) {
16411                    }
16412                }
16413                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16414                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16415                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16416                        | Intent.FLAG_RECEIVER_FOREGROUND);
16417                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16418                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16419                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16420                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16421                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16422                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16423                    broadcastIntentLocked(null, null, intent,
16424                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16425                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16426                }
16427            }
16428        }
16429
16430        boolean kept = true;
16431        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16432        // mainStack is null during startup.
16433        if (mainStack != null) {
16434            if (changes != 0 && starting == null) {
16435                // If the configuration changed, and the caller is not already
16436                // in the process of starting an activity, then find the top
16437                // activity to check if its configuration needs to change.
16438                starting = mainStack.topRunningActivityLocked(null);
16439            }
16440
16441            if (starting != null) {
16442                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16443                // And we need to make sure at this point that all other activities
16444                // are made visible with the correct configuration.
16445                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16446            }
16447        }
16448
16449        if (values != null && mWindowManager != null) {
16450            mWindowManager.setNewConfiguration(mConfiguration);
16451        }
16452
16453        return kept;
16454    }
16455
16456    /**
16457     * Decide based on the configuration whether we should shouw the ANR,
16458     * crash, etc dialogs.  The idea is that if there is no affordnace to
16459     * press the on-screen buttons, we shouldn't show the dialog.
16460     *
16461     * A thought: SystemUI might also want to get told about this, the Power
16462     * dialog / global actions also might want different behaviors.
16463     */
16464    private static final boolean shouldShowDialogs(Configuration config) {
16465        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16466                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16467    }
16468
16469    /**
16470     * Save the locale.  You must be inside a synchronized (this) block.
16471     */
16472    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16473        if(isDiff) {
16474            SystemProperties.set("user.language", l.getLanguage());
16475            SystemProperties.set("user.region", l.getCountry());
16476        }
16477
16478        if(isPersist) {
16479            SystemProperties.set("persist.sys.language", l.getLanguage());
16480            SystemProperties.set("persist.sys.country", l.getCountry());
16481            SystemProperties.set("persist.sys.localevar", l.getVariant());
16482
16483            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16484        }
16485    }
16486
16487    @Override
16488    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16489        synchronized (this) {
16490            ActivityRecord srec = ActivityRecord.forToken(token);
16491            if (srec.task != null && srec.task.stack != null) {
16492                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16493            }
16494        }
16495        return false;
16496    }
16497
16498    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16499            Intent resultData) {
16500
16501        synchronized (this) {
16502            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16503            if (stack != null) {
16504                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16505            }
16506            return false;
16507        }
16508    }
16509
16510    public int getLaunchedFromUid(IBinder activityToken) {
16511        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16512        if (srec == null) {
16513            return -1;
16514        }
16515        return srec.launchedFromUid;
16516    }
16517
16518    public String getLaunchedFromPackage(IBinder activityToken) {
16519        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16520        if (srec == null) {
16521            return null;
16522        }
16523        return srec.launchedFromPackage;
16524    }
16525
16526    // =========================================================
16527    // LIFETIME MANAGEMENT
16528    // =========================================================
16529
16530    // Returns which broadcast queue the app is the current [or imminent] receiver
16531    // on, or 'null' if the app is not an active broadcast recipient.
16532    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16533        BroadcastRecord r = app.curReceiver;
16534        if (r != null) {
16535            return r.queue;
16536        }
16537
16538        // It's not the current receiver, but it might be starting up to become one
16539        synchronized (this) {
16540            for (BroadcastQueue queue : mBroadcastQueues) {
16541                r = queue.mPendingBroadcast;
16542                if (r != null && r.curApp == app) {
16543                    // found it; report which queue it's in
16544                    return queue;
16545                }
16546            }
16547        }
16548
16549        return null;
16550    }
16551
16552    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16553            boolean doingAll, long now) {
16554        if (mAdjSeq == app.adjSeq) {
16555            // This adjustment has already been computed.
16556            return app.curRawAdj;
16557        }
16558
16559        if (app.thread == null) {
16560            app.adjSeq = mAdjSeq;
16561            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16562            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16563            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16564        }
16565
16566        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16567        app.adjSource = null;
16568        app.adjTarget = null;
16569        app.empty = false;
16570        app.cached = false;
16571
16572        final int activitiesSize = app.activities.size();
16573
16574        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16575            // The max adjustment doesn't allow this app to be anything
16576            // below foreground, so it is not worth doing work for it.
16577            app.adjType = "fixed";
16578            app.adjSeq = mAdjSeq;
16579            app.curRawAdj = app.maxAdj;
16580            app.foregroundActivities = false;
16581            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16582            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16583            // System processes can do UI, and when they do we want to have
16584            // them trim their memory after the user leaves the UI.  To
16585            // facilitate this, here we need to determine whether or not it
16586            // is currently showing UI.
16587            app.systemNoUi = true;
16588            if (app == TOP_APP) {
16589                app.systemNoUi = false;
16590            } else if (activitiesSize > 0) {
16591                for (int j = 0; j < activitiesSize; j++) {
16592                    final ActivityRecord r = app.activities.get(j);
16593                    if (r.visible) {
16594                        app.systemNoUi = false;
16595                    }
16596                }
16597            }
16598            if (!app.systemNoUi) {
16599                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16600            }
16601            return (app.curAdj=app.maxAdj);
16602        }
16603
16604        app.systemNoUi = false;
16605
16606        // Determine the importance of the process, starting with most
16607        // important to least, and assign an appropriate OOM adjustment.
16608        int adj;
16609        int schedGroup;
16610        int procState;
16611        boolean foregroundActivities = false;
16612        BroadcastQueue queue;
16613        if (app == TOP_APP) {
16614            // The last app on the list is the foreground app.
16615            adj = ProcessList.FOREGROUND_APP_ADJ;
16616            schedGroup = Process.THREAD_GROUP_DEFAULT;
16617            app.adjType = "top-activity";
16618            foregroundActivities = true;
16619            procState = ActivityManager.PROCESS_STATE_TOP;
16620        } else if (app.instrumentationClass != null) {
16621            // Don't want to kill running instrumentation.
16622            adj = ProcessList.FOREGROUND_APP_ADJ;
16623            schedGroup = Process.THREAD_GROUP_DEFAULT;
16624            app.adjType = "instrumentation";
16625            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16626        } else if ((queue = isReceivingBroadcast(app)) != null) {
16627            // An app that is currently receiving a broadcast also
16628            // counts as being in the foreground for OOM killer purposes.
16629            // It's placed in a sched group based on the nature of the
16630            // broadcast as reflected by which queue it's active in.
16631            adj = ProcessList.FOREGROUND_APP_ADJ;
16632            schedGroup = (queue == mFgBroadcastQueue)
16633                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16634            app.adjType = "broadcast";
16635            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16636        } else if (app.executingServices.size() > 0) {
16637            // An app that is currently executing a service callback also
16638            // counts as being in the foreground.
16639            adj = ProcessList.FOREGROUND_APP_ADJ;
16640            schedGroup = app.execServicesFg ?
16641                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16642            app.adjType = "exec-service";
16643            procState = ActivityManager.PROCESS_STATE_SERVICE;
16644            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16645        } else {
16646            // As far as we know the process is empty.  We may change our mind later.
16647            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16648            // At this point we don't actually know the adjustment.  Use the cached adj
16649            // value that the caller wants us to.
16650            adj = cachedAdj;
16651            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16652            app.cached = true;
16653            app.empty = true;
16654            app.adjType = "cch-empty";
16655        }
16656
16657        // Examine all activities if not already foreground.
16658        if (!foregroundActivities && activitiesSize > 0) {
16659            for (int j = 0; j < activitiesSize; j++) {
16660                final ActivityRecord r = app.activities.get(j);
16661                if (r.app != app) {
16662                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16663                            + app + "?!?");
16664                    continue;
16665                }
16666                if (r.visible) {
16667                    // App has a visible activity; only upgrade adjustment.
16668                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16669                        adj = ProcessList.VISIBLE_APP_ADJ;
16670                        app.adjType = "visible";
16671                    }
16672                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16673                        procState = ActivityManager.PROCESS_STATE_TOP;
16674                    }
16675                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16676                    app.cached = false;
16677                    app.empty = false;
16678                    foregroundActivities = true;
16679                    break;
16680                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16681                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16682                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16683                        app.adjType = "pausing";
16684                    }
16685                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16686                        procState = ActivityManager.PROCESS_STATE_TOP;
16687                    }
16688                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16689                    app.cached = false;
16690                    app.empty = false;
16691                    foregroundActivities = true;
16692                } else if (r.state == ActivityState.STOPPING) {
16693                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16694                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16695                        app.adjType = "stopping";
16696                    }
16697                    // For the process state, we will at this point consider the
16698                    // process to be cached.  It will be cached either as an activity
16699                    // or empty depending on whether the activity is finishing.  We do
16700                    // this so that we can treat the process as cached for purposes of
16701                    // memory trimming (determing current memory level, trim command to
16702                    // send to process) since there can be an arbitrary number of stopping
16703                    // processes and they should soon all go into the cached state.
16704                    if (!r.finishing) {
16705                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16706                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16707                        }
16708                    }
16709                    app.cached = false;
16710                    app.empty = false;
16711                    foregroundActivities = true;
16712                } else {
16713                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16714                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16715                        app.adjType = "cch-act";
16716                    }
16717                }
16718            }
16719        }
16720
16721        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16722            if (app.foregroundServices) {
16723                // The user is aware of this app, so make it visible.
16724                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16725                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16726                app.cached = false;
16727                app.adjType = "fg-service";
16728                schedGroup = Process.THREAD_GROUP_DEFAULT;
16729            } else if (app.forcingToForeground != null) {
16730                // The user is aware of this app, so make it visible.
16731                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16732                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16733                app.cached = false;
16734                app.adjType = "force-fg";
16735                app.adjSource = app.forcingToForeground;
16736                schedGroup = Process.THREAD_GROUP_DEFAULT;
16737            }
16738        }
16739
16740        if (app == mHeavyWeightProcess) {
16741            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16742                // We don't want to kill the current heavy-weight process.
16743                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16744                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16745                app.cached = false;
16746                app.adjType = "heavy";
16747            }
16748            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16749                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16750            }
16751        }
16752
16753        if (app == mHomeProcess) {
16754            if (adj > ProcessList.HOME_APP_ADJ) {
16755                // This process is hosting what we currently consider to be the
16756                // home app, so we don't want to let it go into the background.
16757                adj = ProcessList.HOME_APP_ADJ;
16758                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16759                app.cached = false;
16760                app.adjType = "home";
16761            }
16762            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16763                procState = ActivityManager.PROCESS_STATE_HOME;
16764            }
16765        }
16766
16767        if (app == mPreviousProcess && app.activities.size() > 0) {
16768            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16769                // This was the previous process that showed UI to the user.
16770                // We want to try to keep it around more aggressively, to give
16771                // a good experience around switching between two apps.
16772                adj = ProcessList.PREVIOUS_APP_ADJ;
16773                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16774                app.cached = false;
16775                app.adjType = "previous";
16776            }
16777            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16778                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16779            }
16780        }
16781
16782        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16783                + " reason=" + app.adjType);
16784
16785        // By default, we use the computed adjustment.  It may be changed if
16786        // there are applications dependent on our services or providers, but
16787        // this gives us a baseline and makes sure we don't get into an
16788        // infinite recursion.
16789        app.adjSeq = mAdjSeq;
16790        app.curRawAdj = adj;
16791        app.hasStartedServices = false;
16792
16793        if (mBackupTarget != null && app == mBackupTarget.app) {
16794            // If possible we want to avoid killing apps while they're being backed up
16795            if (adj > ProcessList.BACKUP_APP_ADJ) {
16796                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16797                adj = ProcessList.BACKUP_APP_ADJ;
16798                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16799                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16800                }
16801                app.adjType = "backup";
16802                app.cached = false;
16803            }
16804            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16805                procState = ActivityManager.PROCESS_STATE_BACKUP;
16806            }
16807        }
16808
16809        boolean mayBeTop = false;
16810
16811        for (int is = app.services.size()-1;
16812                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16813                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16814                        || procState > ActivityManager.PROCESS_STATE_TOP);
16815                is--) {
16816            ServiceRecord s = app.services.valueAt(is);
16817            if (s.startRequested) {
16818                app.hasStartedServices = true;
16819                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16820                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16821                }
16822                if (app.hasShownUi && app != mHomeProcess) {
16823                    // If this process has shown some UI, let it immediately
16824                    // go to the LRU list because it may be pretty heavy with
16825                    // UI stuff.  We'll tag it with a label just to help
16826                    // debug and understand what is going on.
16827                    if (adj > ProcessList.SERVICE_ADJ) {
16828                        app.adjType = "cch-started-ui-services";
16829                    }
16830                } else {
16831                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16832                        // This service has seen some activity within
16833                        // recent memory, so we will keep its process ahead
16834                        // of the background processes.
16835                        if (adj > ProcessList.SERVICE_ADJ) {
16836                            adj = ProcessList.SERVICE_ADJ;
16837                            app.adjType = "started-services";
16838                            app.cached = false;
16839                        }
16840                    }
16841                    // If we have let the service slide into the background
16842                    // state, still have some text describing what it is doing
16843                    // even though the service no longer has an impact.
16844                    if (adj > ProcessList.SERVICE_ADJ) {
16845                        app.adjType = "cch-started-services";
16846                    }
16847                }
16848            }
16849            for (int conni = s.connections.size()-1;
16850                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16851                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16852                            || procState > ActivityManager.PROCESS_STATE_TOP);
16853                    conni--) {
16854                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16855                for (int i = 0;
16856                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16857                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16858                                || procState > ActivityManager.PROCESS_STATE_TOP);
16859                        i++) {
16860                    // XXX should compute this based on the max of
16861                    // all connected clients.
16862                    ConnectionRecord cr = clist.get(i);
16863                    if (cr.binding.client == app) {
16864                        // Binding to ourself is not interesting.
16865                        continue;
16866                    }
16867                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16868                        ProcessRecord client = cr.binding.client;
16869                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16870                                TOP_APP, doingAll, now);
16871                        int clientProcState = client.curProcState;
16872                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16873                            // If the other app is cached for any reason, for purposes here
16874                            // we are going to consider it empty.  The specific cached state
16875                            // doesn't propagate except under certain conditions.
16876                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16877                        }
16878                        String adjType = null;
16879                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16880                            // Not doing bind OOM management, so treat
16881                            // this guy more like a started service.
16882                            if (app.hasShownUi && app != mHomeProcess) {
16883                                // If this process has shown some UI, let it immediately
16884                                // go to the LRU list because it may be pretty heavy with
16885                                // UI stuff.  We'll tag it with a label just to help
16886                                // debug and understand what is going on.
16887                                if (adj > clientAdj) {
16888                                    adjType = "cch-bound-ui-services";
16889                                }
16890                                app.cached = false;
16891                                clientAdj = adj;
16892                                clientProcState = procState;
16893                            } else {
16894                                if (now >= (s.lastActivity
16895                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16896                                    // This service has not seen activity within
16897                                    // recent memory, so allow it to drop to the
16898                                    // LRU list if there is no other reason to keep
16899                                    // it around.  We'll also tag it with a label just
16900                                    // to help debug and undertand what is going on.
16901                                    if (adj > clientAdj) {
16902                                        adjType = "cch-bound-services";
16903                                    }
16904                                    clientAdj = adj;
16905                                }
16906                            }
16907                        }
16908                        if (adj > clientAdj) {
16909                            // If this process has recently shown UI, and
16910                            // the process that is binding to it is less
16911                            // important than being visible, then we don't
16912                            // care about the binding as much as we care
16913                            // about letting this process get into the LRU
16914                            // list to be killed and restarted if needed for
16915                            // memory.
16916                            if (app.hasShownUi && app != mHomeProcess
16917                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16918                                adjType = "cch-bound-ui-services";
16919                            } else {
16920                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16921                                        |Context.BIND_IMPORTANT)) != 0) {
16922                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16923                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16924                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16925                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16926                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16927                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16928                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16929                                    adj = clientAdj;
16930                                } else {
16931                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16932                                        adj = ProcessList.VISIBLE_APP_ADJ;
16933                                    }
16934                                }
16935                                if (!client.cached) {
16936                                    app.cached = false;
16937                                }
16938                                adjType = "service";
16939                            }
16940                        }
16941                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16942                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16943                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16944                            }
16945                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16946                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16947                                    // Special handling of clients who are in the top state.
16948                                    // We *may* want to consider this process to be in the
16949                                    // top state as well, but only if there is not another
16950                                    // reason for it to be running.  Being on the top is a
16951                                    // special state, meaning you are specifically running
16952                                    // for the current top app.  If the process is already
16953                                    // running in the background for some other reason, it
16954                                    // is more important to continue considering it to be
16955                                    // in the background state.
16956                                    mayBeTop = true;
16957                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16958                                } else {
16959                                    // Special handling for above-top states (persistent
16960                                    // processes).  These should not bring the current process
16961                                    // into the top state, since they are not on top.  Instead
16962                                    // give them the best state after that.
16963                                    clientProcState =
16964                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16965                                }
16966                            }
16967                        } else {
16968                            if (clientProcState <
16969                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16970                                clientProcState =
16971                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16972                            }
16973                        }
16974                        if (procState > clientProcState) {
16975                            procState = clientProcState;
16976                        }
16977                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16978                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16979                            app.pendingUiClean = true;
16980                        }
16981                        if (adjType != null) {
16982                            app.adjType = adjType;
16983                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16984                                    .REASON_SERVICE_IN_USE;
16985                            app.adjSource = cr.binding.client;
16986                            app.adjSourceProcState = clientProcState;
16987                            app.adjTarget = s.name;
16988                        }
16989                    }
16990                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16991                        app.treatLikeActivity = true;
16992                    }
16993                    final ActivityRecord a = cr.activity;
16994                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16995                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16996                                (a.visible || a.state == ActivityState.RESUMED
16997                                 || a.state == ActivityState.PAUSING)) {
16998                            adj = ProcessList.FOREGROUND_APP_ADJ;
16999                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17000                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17001                            }
17002                            app.cached = false;
17003                            app.adjType = "service";
17004                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17005                                    .REASON_SERVICE_IN_USE;
17006                            app.adjSource = a;
17007                            app.adjSourceProcState = procState;
17008                            app.adjTarget = s.name;
17009                        }
17010                    }
17011                }
17012            }
17013        }
17014
17015        for (int provi = app.pubProviders.size()-1;
17016                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17017                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17018                        || procState > ActivityManager.PROCESS_STATE_TOP);
17019                provi--) {
17020            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17021            for (int i = cpr.connections.size()-1;
17022                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17023                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17024                            || procState > ActivityManager.PROCESS_STATE_TOP);
17025                    i--) {
17026                ContentProviderConnection conn = cpr.connections.get(i);
17027                ProcessRecord client = conn.client;
17028                if (client == app) {
17029                    // Being our own client is not interesting.
17030                    continue;
17031                }
17032                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17033                int clientProcState = client.curProcState;
17034                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17035                    // If the other app is cached for any reason, for purposes here
17036                    // we are going to consider it empty.
17037                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17038                }
17039                if (adj > clientAdj) {
17040                    if (app.hasShownUi && app != mHomeProcess
17041                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17042                        app.adjType = "cch-ui-provider";
17043                    } else {
17044                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17045                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17046                        app.adjType = "provider";
17047                    }
17048                    app.cached &= client.cached;
17049                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17050                            .REASON_PROVIDER_IN_USE;
17051                    app.adjSource = client;
17052                    app.adjSourceProcState = clientProcState;
17053                    app.adjTarget = cpr.name;
17054                }
17055                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17056                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17057                        // Special handling of clients who are in the top state.
17058                        // We *may* want to consider this process to be in the
17059                        // top state as well, but only if there is not another
17060                        // reason for it to be running.  Being on the top is a
17061                        // special state, meaning you are specifically running
17062                        // for the current top app.  If the process is already
17063                        // running in the background for some other reason, it
17064                        // is more important to continue considering it to be
17065                        // in the background state.
17066                        mayBeTop = true;
17067                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17068                    } else {
17069                        // Special handling for above-top states (persistent
17070                        // processes).  These should not bring the current process
17071                        // into the top state, since they are not on top.  Instead
17072                        // give them the best state after that.
17073                        clientProcState =
17074                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17075                    }
17076                }
17077                if (procState > clientProcState) {
17078                    procState = clientProcState;
17079                }
17080                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17081                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17082                }
17083            }
17084            // If the provider has external (non-framework) process
17085            // dependencies, ensure that its adjustment is at least
17086            // FOREGROUND_APP_ADJ.
17087            if (cpr.hasExternalProcessHandles()) {
17088                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17089                    adj = ProcessList.FOREGROUND_APP_ADJ;
17090                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17091                    app.cached = false;
17092                    app.adjType = "provider";
17093                    app.adjTarget = cpr.name;
17094                }
17095                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17096                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17097                }
17098            }
17099        }
17100
17101        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17102            // A client of one of our services or providers is in the top state.  We
17103            // *may* want to be in the top state, but not if we are already running in
17104            // the background for some other reason.  For the decision here, we are going
17105            // to pick out a few specific states that we want to remain in when a client
17106            // is top (states that tend to be longer-term) and otherwise allow it to go
17107            // to the top state.
17108            switch (procState) {
17109                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17110                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17111                case ActivityManager.PROCESS_STATE_SERVICE:
17112                    // These all are longer-term states, so pull them up to the top
17113                    // of the background states, but not all the way to the top state.
17114                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17115                    break;
17116                default:
17117                    // Otherwise, top is a better choice, so take it.
17118                    procState = ActivityManager.PROCESS_STATE_TOP;
17119                    break;
17120            }
17121        }
17122
17123        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17124            if (app.hasClientActivities) {
17125                // This is a cached process, but with client activities.  Mark it so.
17126                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17127                app.adjType = "cch-client-act";
17128            } else if (app.treatLikeActivity) {
17129                // This is a cached process, but somebody wants us to treat it like it has
17130                // an activity, okay!
17131                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17132                app.adjType = "cch-as-act";
17133            }
17134        }
17135
17136        if (adj == ProcessList.SERVICE_ADJ) {
17137            if (doingAll) {
17138                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17139                mNewNumServiceProcs++;
17140                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17141                if (!app.serviceb) {
17142                    // This service isn't far enough down on the LRU list to
17143                    // normally be a B service, but if we are low on RAM and it
17144                    // is large we want to force it down since we would prefer to
17145                    // keep launcher over it.
17146                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17147                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17148                        app.serviceHighRam = true;
17149                        app.serviceb = true;
17150                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17151                    } else {
17152                        mNewNumAServiceProcs++;
17153                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17154                    }
17155                } else {
17156                    app.serviceHighRam = false;
17157                }
17158            }
17159            if (app.serviceb) {
17160                adj = ProcessList.SERVICE_B_ADJ;
17161            }
17162        }
17163
17164        app.curRawAdj = adj;
17165
17166        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17167        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17168        if (adj > app.maxAdj) {
17169            adj = app.maxAdj;
17170            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17171                schedGroup = Process.THREAD_GROUP_DEFAULT;
17172            }
17173        }
17174
17175        // Do final modification to adj.  Everything we do between here and applying
17176        // the final setAdj must be done in this function, because we will also use
17177        // it when computing the final cached adj later.  Note that we don't need to
17178        // worry about this for max adj above, since max adj will always be used to
17179        // keep it out of the cached vaues.
17180        app.curAdj = app.modifyRawOomAdj(adj);
17181        app.curSchedGroup = schedGroup;
17182        app.curProcState = procState;
17183        app.foregroundActivities = foregroundActivities;
17184
17185        return app.curRawAdj;
17186    }
17187
17188    /**
17189     * Schedule PSS collection of a process.
17190     */
17191    void requestPssLocked(ProcessRecord proc, int procState) {
17192        if (mPendingPssProcesses.contains(proc)) {
17193            return;
17194        }
17195        if (mPendingPssProcesses.size() == 0) {
17196            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17197        }
17198        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17199        proc.pssProcState = procState;
17200        mPendingPssProcesses.add(proc);
17201    }
17202
17203    /**
17204     * Schedule PSS collection of all processes.
17205     */
17206    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17207        if (!always) {
17208            if (now < (mLastFullPssTime +
17209                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17210                return;
17211            }
17212        }
17213        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17214        mLastFullPssTime = now;
17215        mFullPssPending = true;
17216        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17217        mPendingPssProcesses.clear();
17218        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17219            ProcessRecord app = mLruProcesses.get(i);
17220            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17221                app.pssProcState = app.setProcState;
17222                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17223                        isSleeping(), now);
17224                mPendingPssProcesses.add(app);
17225            }
17226        }
17227        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17228    }
17229
17230    /**
17231     * Ask a given process to GC right now.
17232     */
17233    final void performAppGcLocked(ProcessRecord app) {
17234        try {
17235            app.lastRequestedGc = SystemClock.uptimeMillis();
17236            if (app.thread != null) {
17237                if (app.reportLowMemory) {
17238                    app.reportLowMemory = false;
17239                    app.thread.scheduleLowMemory();
17240                } else {
17241                    app.thread.processInBackground();
17242                }
17243            }
17244        } catch (Exception e) {
17245            // whatever.
17246        }
17247    }
17248
17249    /**
17250     * Returns true if things are idle enough to perform GCs.
17251     */
17252    private final boolean canGcNowLocked() {
17253        boolean processingBroadcasts = false;
17254        for (BroadcastQueue q : mBroadcastQueues) {
17255            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17256                processingBroadcasts = true;
17257            }
17258        }
17259        return !processingBroadcasts
17260                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17261    }
17262
17263    /**
17264     * Perform GCs on all processes that are waiting for it, but only
17265     * if things are idle.
17266     */
17267    final void performAppGcsLocked() {
17268        final int N = mProcessesToGc.size();
17269        if (N <= 0) {
17270            return;
17271        }
17272        if (canGcNowLocked()) {
17273            while (mProcessesToGc.size() > 0) {
17274                ProcessRecord proc = mProcessesToGc.remove(0);
17275                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17276                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17277                            <= SystemClock.uptimeMillis()) {
17278                        // To avoid spamming the system, we will GC processes one
17279                        // at a time, waiting a few seconds between each.
17280                        performAppGcLocked(proc);
17281                        scheduleAppGcsLocked();
17282                        return;
17283                    } else {
17284                        // It hasn't been long enough since we last GCed this
17285                        // process...  put it in the list to wait for its time.
17286                        addProcessToGcListLocked(proc);
17287                        break;
17288                    }
17289                }
17290            }
17291
17292            scheduleAppGcsLocked();
17293        }
17294    }
17295
17296    /**
17297     * If all looks good, perform GCs on all processes waiting for them.
17298     */
17299    final void performAppGcsIfAppropriateLocked() {
17300        if (canGcNowLocked()) {
17301            performAppGcsLocked();
17302            return;
17303        }
17304        // Still not idle, wait some more.
17305        scheduleAppGcsLocked();
17306    }
17307
17308    /**
17309     * Schedule the execution of all pending app GCs.
17310     */
17311    final void scheduleAppGcsLocked() {
17312        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17313
17314        if (mProcessesToGc.size() > 0) {
17315            // Schedule a GC for the time to the next process.
17316            ProcessRecord proc = mProcessesToGc.get(0);
17317            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17318
17319            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17320            long now = SystemClock.uptimeMillis();
17321            if (when < (now+GC_TIMEOUT)) {
17322                when = now + GC_TIMEOUT;
17323            }
17324            mHandler.sendMessageAtTime(msg, when);
17325        }
17326    }
17327
17328    /**
17329     * Add a process to the array of processes waiting to be GCed.  Keeps the
17330     * list in sorted order by the last GC time.  The process can't already be
17331     * on the list.
17332     */
17333    final void addProcessToGcListLocked(ProcessRecord proc) {
17334        boolean added = false;
17335        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17336            if (mProcessesToGc.get(i).lastRequestedGc <
17337                    proc.lastRequestedGc) {
17338                added = true;
17339                mProcessesToGc.add(i+1, proc);
17340                break;
17341            }
17342        }
17343        if (!added) {
17344            mProcessesToGc.add(0, proc);
17345        }
17346    }
17347
17348    /**
17349     * Set up to ask a process to GC itself.  This will either do it
17350     * immediately, or put it on the list of processes to gc the next
17351     * time things are idle.
17352     */
17353    final void scheduleAppGcLocked(ProcessRecord app) {
17354        long now = SystemClock.uptimeMillis();
17355        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17356            return;
17357        }
17358        if (!mProcessesToGc.contains(app)) {
17359            addProcessToGcListLocked(app);
17360            scheduleAppGcsLocked();
17361        }
17362    }
17363
17364    final void checkExcessivePowerUsageLocked(boolean doKills) {
17365        updateCpuStatsNow();
17366
17367        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17368        boolean doWakeKills = doKills;
17369        boolean doCpuKills = doKills;
17370        if (mLastPowerCheckRealtime == 0) {
17371            doWakeKills = false;
17372        }
17373        if (mLastPowerCheckUptime == 0) {
17374            doCpuKills = false;
17375        }
17376        if (stats.isScreenOn()) {
17377            doWakeKills = false;
17378        }
17379        final long curRealtime = SystemClock.elapsedRealtime();
17380        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17381        final long curUptime = SystemClock.uptimeMillis();
17382        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17383        mLastPowerCheckRealtime = curRealtime;
17384        mLastPowerCheckUptime = curUptime;
17385        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17386            doWakeKills = false;
17387        }
17388        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17389            doCpuKills = false;
17390        }
17391        int i = mLruProcesses.size();
17392        while (i > 0) {
17393            i--;
17394            ProcessRecord app = mLruProcesses.get(i);
17395            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17396                long wtime;
17397                synchronized (stats) {
17398                    wtime = stats.getProcessWakeTime(app.info.uid,
17399                            app.pid, curRealtime);
17400                }
17401                long wtimeUsed = wtime - app.lastWakeTime;
17402                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17403                if (DEBUG_POWER) {
17404                    StringBuilder sb = new StringBuilder(128);
17405                    sb.append("Wake for ");
17406                    app.toShortString(sb);
17407                    sb.append(": over ");
17408                    TimeUtils.formatDuration(realtimeSince, sb);
17409                    sb.append(" used ");
17410                    TimeUtils.formatDuration(wtimeUsed, sb);
17411                    sb.append(" (");
17412                    sb.append((wtimeUsed*100)/realtimeSince);
17413                    sb.append("%)");
17414                    Slog.i(TAG, sb.toString());
17415                    sb.setLength(0);
17416                    sb.append("CPU for ");
17417                    app.toShortString(sb);
17418                    sb.append(": over ");
17419                    TimeUtils.formatDuration(uptimeSince, sb);
17420                    sb.append(" used ");
17421                    TimeUtils.formatDuration(cputimeUsed, sb);
17422                    sb.append(" (");
17423                    sb.append((cputimeUsed*100)/uptimeSince);
17424                    sb.append("%)");
17425                    Slog.i(TAG, sb.toString());
17426                }
17427                // If a process has held a wake lock for more
17428                // than 50% of the time during this period,
17429                // that sounds bad.  Kill!
17430                if (doWakeKills && realtimeSince > 0
17431                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17432                    synchronized (stats) {
17433                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17434                                realtimeSince, wtimeUsed);
17435                    }
17436                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17437                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17438                } else if (doCpuKills && uptimeSince > 0
17439                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17440                    synchronized (stats) {
17441                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17442                                uptimeSince, cputimeUsed);
17443                    }
17444                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17445                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17446                } else {
17447                    app.lastWakeTime = wtime;
17448                    app.lastCpuTime = app.curCpuTime;
17449                }
17450            }
17451        }
17452    }
17453
17454    private final boolean applyOomAdjLocked(ProcessRecord app,
17455            ProcessRecord TOP_APP, boolean doingAll, long now) {
17456        boolean success = true;
17457
17458        if (app.curRawAdj != app.setRawAdj) {
17459            app.setRawAdj = app.curRawAdj;
17460        }
17461
17462        int changes = 0;
17463
17464        if (app.curAdj != app.setAdj) {
17465            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17466            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17467                TAG, "Set " + app.pid + " " + app.processName +
17468                " adj " + app.curAdj + ": " + app.adjType);
17469            app.setAdj = app.curAdj;
17470        }
17471
17472        if (app.setSchedGroup != app.curSchedGroup) {
17473            app.setSchedGroup = app.curSchedGroup;
17474            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17475                    "Setting process group of " + app.processName
17476                    + " to " + app.curSchedGroup);
17477            if (app.waitingToKill != null &&
17478                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17479                app.kill(app.waitingToKill, true);
17480                success = false;
17481            } else {
17482                if (true) {
17483                    long oldId = Binder.clearCallingIdentity();
17484                    try {
17485                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17486                    } catch (Exception e) {
17487                        Slog.w(TAG, "Failed setting process group of " + app.pid
17488                                + " to " + app.curSchedGroup);
17489                        e.printStackTrace();
17490                    } finally {
17491                        Binder.restoreCallingIdentity(oldId);
17492                    }
17493                } else {
17494                    if (app.thread != null) {
17495                        try {
17496                            app.thread.setSchedulingGroup(app.curSchedGroup);
17497                        } catch (RemoteException e) {
17498                        }
17499                    }
17500                }
17501                Process.setSwappiness(app.pid,
17502                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17503            }
17504        }
17505        if (app.repForegroundActivities != app.foregroundActivities) {
17506            app.repForegroundActivities = app.foregroundActivities;
17507            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17508        }
17509        if (app.repProcState != app.curProcState) {
17510            app.repProcState = app.curProcState;
17511            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17512            if (app.thread != null) {
17513                try {
17514                    if (false) {
17515                        //RuntimeException h = new RuntimeException("here");
17516                        Slog.i(TAG, "Sending new process state " + app.repProcState
17517                                + " to " + app /*, h*/);
17518                    }
17519                    app.thread.setProcessState(app.repProcState);
17520                } catch (RemoteException e) {
17521                }
17522            }
17523        }
17524        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17525                app.setProcState)) {
17526            app.lastStateTime = now;
17527            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17528                    isSleeping(), now);
17529            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17530                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17531                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17532                    + (app.nextPssTime-now) + ": " + app);
17533        } else {
17534            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17535                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17536                requestPssLocked(app, app.setProcState);
17537                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17538                        isSleeping(), now);
17539            } else if (false && DEBUG_PSS) {
17540                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17541            }
17542        }
17543        if (app.setProcState != app.curProcState) {
17544            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17545                    "Proc state change of " + app.processName
17546                    + " to " + app.curProcState);
17547            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17548            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17549            if (setImportant && !curImportant) {
17550                // This app is no longer something we consider important enough to allow to
17551                // use arbitrary amounts of battery power.  Note
17552                // its current wake lock time to later know to kill it if
17553                // it is not behaving well.
17554                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17555                synchronized (stats) {
17556                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17557                            app.pid, SystemClock.elapsedRealtime());
17558                }
17559                app.lastCpuTime = app.curCpuTime;
17560
17561            }
17562            app.setProcState = app.curProcState;
17563            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17564                app.notCachedSinceIdle = false;
17565            }
17566            if (!doingAll) {
17567                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17568            } else {
17569                app.procStateChanged = true;
17570            }
17571        }
17572
17573        if (changes != 0) {
17574            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17575            int i = mPendingProcessChanges.size()-1;
17576            ProcessChangeItem item = null;
17577            while (i >= 0) {
17578                item = mPendingProcessChanges.get(i);
17579                if (item.pid == app.pid) {
17580                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17581                    break;
17582                }
17583                i--;
17584            }
17585            if (i < 0) {
17586                // No existing item in pending changes; need a new one.
17587                final int NA = mAvailProcessChanges.size();
17588                if (NA > 0) {
17589                    item = mAvailProcessChanges.remove(NA-1);
17590                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17591                } else {
17592                    item = new ProcessChangeItem();
17593                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17594                }
17595                item.changes = 0;
17596                item.pid = app.pid;
17597                item.uid = app.info.uid;
17598                if (mPendingProcessChanges.size() == 0) {
17599                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17600                            "*** Enqueueing dispatch processes changed!");
17601                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17602                }
17603                mPendingProcessChanges.add(item);
17604            }
17605            item.changes |= changes;
17606            item.processState = app.repProcState;
17607            item.foregroundActivities = app.repForegroundActivities;
17608            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17609                    + Integer.toHexString(System.identityHashCode(item))
17610                    + " " + app.toShortString() + ": changes=" + item.changes
17611                    + " procState=" + item.processState
17612                    + " foreground=" + item.foregroundActivities
17613                    + " type=" + app.adjType + " source=" + app.adjSource
17614                    + " target=" + app.adjTarget);
17615        }
17616
17617        return success;
17618    }
17619
17620    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17621        if (proc.thread != null) {
17622            if (proc.baseProcessTracker != null) {
17623                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17624            }
17625            if (proc.repProcState >= 0) {
17626                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17627                        proc.repProcState);
17628            }
17629        }
17630    }
17631
17632    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17633            ProcessRecord TOP_APP, boolean doingAll, long now) {
17634        if (app.thread == null) {
17635            return false;
17636        }
17637
17638        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17639
17640        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17641    }
17642
17643    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17644            boolean oomAdj) {
17645        if (isForeground != proc.foregroundServices) {
17646            proc.foregroundServices = isForeground;
17647            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17648                    proc.info.uid);
17649            if (isForeground) {
17650                if (curProcs == null) {
17651                    curProcs = new ArrayList<ProcessRecord>();
17652                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17653                }
17654                if (!curProcs.contains(proc)) {
17655                    curProcs.add(proc);
17656                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17657                            proc.info.packageName, proc.info.uid);
17658                }
17659            } else {
17660                if (curProcs != null) {
17661                    if (curProcs.remove(proc)) {
17662                        mBatteryStatsService.noteEvent(
17663                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17664                                proc.info.packageName, proc.info.uid);
17665                        if (curProcs.size() <= 0) {
17666                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17667                        }
17668                    }
17669                }
17670            }
17671            if (oomAdj) {
17672                updateOomAdjLocked();
17673            }
17674        }
17675    }
17676
17677    private final ActivityRecord resumedAppLocked() {
17678        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17679        String pkg;
17680        int uid;
17681        if (act != null) {
17682            pkg = act.packageName;
17683            uid = act.info.applicationInfo.uid;
17684        } else {
17685            pkg = null;
17686            uid = -1;
17687        }
17688        // Has the UID or resumed package name changed?
17689        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17690                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17691            if (mCurResumedPackage != null) {
17692                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17693                        mCurResumedPackage, mCurResumedUid);
17694            }
17695            mCurResumedPackage = pkg;
17696            mCurResumedUid = uid;
17697            if (mCurResumedPackage != null) {
17698                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17699                        mCurResumedPackage, mCurResumedUid);
17700            }
17701        }
17702        return act;
17703    }
17704
17705    final boolean updateOomAdjLocked(ProcessRecord app) {
17706        final ActivityRecord TOP_ACT = resumedAppLocked();
17707        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17708        final boolean wasCached = app.cached;
17709
17710        mAdjSeq++;
17711
17712        // This is the desired cached adjusment we want to tell it to use.
17713        // If our app is currently cached, we know it, and that is it.  Otherwise,
17714        // we don't know it yet, and it needs to now be cached we will then
17715        // need to do a complete oom adj.
17716        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17717                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17718        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17719                SystemClock.uptimeMillis());
17720        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17721            // Changed to/from cached state, so apps after it in the LRU
17722            // list may also be changed.
17723            updateOomAdjLocked();
17724        }
17725        return success;
17726    }
17727
17728    final void updateOomAdjLocked() {
17729        final ActivityRecord TOP_ACT = resumedAppLocked();
17730        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17731        final long now = SystemClock.uptimeMillis();
17732        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17733        final int N = mLruProcesses.size();
17734
17735        if (false) {
17736            RuntimeException e = new RuntimeException();
17737            e.fillInStackTrace();
17738            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17739        }
17740
17741        mAdjSeq++;
17742        mNewNumServiceProcs = 0;
17743        mNewNumAServiceProcs = 0;
17744
17745        final int emptyProcessLimit;
17746        final int cachedProcessLimit;
17747        if (mProcessLimit <= 0) {
17748            emptyProcessLimit = cachedProcessLimit = 0;
17749        } else if (mProcessLimit == 1) {
17750            emptyProcessLimit = 1;
17751            cachedProcessLimit = 0;
17752        } else {
17753            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17754            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17755        }
17756
17757        // Let's determine how many processes we have running vs.
17758        // how many slots we have for background processes; we may want
17759        // to put multiple processes in a slot of there are enough of
17760        // them.
17761        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17762                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17763        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17764        if (numEmptyProcs > cachedProcessLimit) {
17765            // If there are more empty processes than our limit on cached
17766            // processes, then use the cached process limit for the factor.
17767            // This ensures that the really old empty processes get pushed
17768            // down to the bottom, so if we are running low on memory we will
17769            // have a better chance at keeping around more cached processes
17770            // instead of a gazillion empty processes.
17771            numEmptyProcs = cachedProcessLimit;
17772        }
17773        int emptyFactor = numEmptyProcs/numSlots;
17774        if (emptyFactor < 1) emptyFactor = 1;
17775        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17776        if (cachedFactor < 1) cachedFactor = 1;
17777        int stepCached = 0;
17778        int stepEmpty = 0;
17779        int numCached = 0;
17780        int numEmpty = 0;
17781        int numTrimming = 0;
17782
17783        mNumNonCachedProcs = 0;
17784        mNumCachedHiddenProcs = 0;
17785
17786        // First update the OOM adjustment for each of the
17787        // application processes based on their current state.
17788        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17789        int nextCachedAdj = curCachedAdj+1;
17790        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17791        int nextEmptyAdj = curEmptyAdj+2;
17792        for (int i=N-1; i>=0; i--) {
17793            ProcessRecord app = mLruProcesses.get(i);
17794            if (!app.killedByAm && app.thread != null) {
17795                app.procStateChanged = false;
17796                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17797
17798                // If we haven't yet assigned the final cached adj
17799                // to the process, do that now.
17800                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17801                    switch (app.curProcState) {
17802                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17803                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17804                            // This process is a cached process holding activities...
17805                            // assign it the next cached value for that type, and then
17806                            // step that cached level.
17807                            app.curRawAdj = curCachedAdj;
17808                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17809                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17810                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17811                                    + ")");
17812                            if (curCachedAdj != nextCachedAdj) {
17813                                stepCached++;
17814                                if (stepCached >= cachedFactor) {
17815                                    stepCached = 0;
17816                                    curCachedAdj = nextCachedAdj;
17817                                    nextCachedAdj += 2;
17818                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17819                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17820                                    }
17821                                }
17822                            }
17823                            break;
17824                        default:
17825                            // For everything else, assign next empty cached process
17826                            // level and bump that up.  Note that this means that
17827                            // long-running services that have dropped down to the
17828                            // cached level will be treated as empty (since their process
17829                            // state is still as a service), which is what we want.
17830                            app.curRawAdj = curEmptyAdj;
17831                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17832                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17833                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17834                                    + ")");
17835                            if (curEmptyAdj != nextEmptyAdj) {
17836                                stepEmpty++;
17837                                if (stepEmpty >= emptyFactor) {
17838                                    stepEmpty = 0;
17839                                    curEmptyAdj = nextEmptyAdj;
17840                                    nextEmptyAdj += 2;
17841                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17842                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17843                                    }
17844                                }
17845                            }
17846                            break;
17847                    }
17848                }
17849
17850                applyOomAdjLocked(app, TOP_APP, true, now);
17851
17852                // Count the number of process types.
17853                switch (app.curProcState) {
17854                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17855                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17856                        mNumCachedHiddenProcs++;
17857                        numCached++;
17858                        if (numCached > cachedProcessLimit) {
17859                            app.kill("cached #" + numCached, true);
17860                        }
17861                        break;
17862                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17863                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17864                                && app.lastActivityTime < oldTime) {
17865                            app.kill("empty for "
17866                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17867                                    / 1000) + "s", true);
17868                        } else {
17869                            numEmpty++;
17870                            if (numEmpty > emptyProcessLimit) {
17871                                app.kill("empty #" + numEmpty, true);
17872                            }
17873                        }
17874                        break;
17875                    default:
17876                        mNumNonCachedProcs++;
17877                        break;
17878                }
17879
17880                if (app.isolated && app.services.size() <= 0) {
17881                    // If this is an isolated process, and there are no
17882                    // services running in it, then the process is no longer
17883                    // needed.  We agressively kill these because we can by
17884                    // definition not re-use the same process again, and it is
17885                    // good to avoid having whatever code was running in them
17886                    // left sitting around after no longer needed.
17887                    app.kill("isolated not needed", true);
17888                }
17889
17890                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17891                        && !app.killedByAm) {
17892                    numTrimming++;
17893                }
17894            }
17895        }
17896
17897        mNumServiceProcs = mNewNumServiceProcs;
17898
17899        // Now determine the memory trimming level of background processes.
17900        // Unfortunately we need to start at the back of the list to do this
17901        // properly.  We only do this if the number of background apps we
17902        // are managing to keep around is less than half the maximum we desire;
17903        // if we are keeping a good number around, we'll let them use whatever
17904        // memory they want.
17905        final int numCachedAndEmpty = numCached + numEmpty;
17906        int memFactor;
17907        if (numCached <= ProcessList.TRIM_CACHED_APPS
17908                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17909            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17910                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17911            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17912                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17913            } else {
17914                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17915            }
17916        } else {
17917            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17918        }
17919        // We always allow the memory level to go up (better).  We only allow it to go
17920        // down if we are in a state where that is allowed, *and* the total number of processes
17921        // has gone down since last time.
17922        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17923                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17924                + " last=" + mLastNumProcesses);
17925        if (memFactor > mLastMemoryLevel) {
17926            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17927                memFactor = mLastMemoryLevel;
17928                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17929            }
17930        }
17931        mLastMemoryLevel = memFactor;
17932        mLastNumProcesses = mLruProcesses.size();
17933        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17934        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17935        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17936            if (mLowRamStartTime == 0) {
17937                mLowRamStartTime = now;
17938            }
17939            int step = 0;
17940            int fgTrimLevel;
17941            switch (memFactor) {
17942                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17943                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17944                    break;
17945                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17946                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17947                    break;
17948                default:
17949                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17950                    break;
17951            }
17952            int factor = numTrimming/3;
17953            int minFactor = 2;
17954            if (mHomeProcess != null) minFactor++;
17955            if (mPreviousProcess != null) minFactor++;
17956            if (factor < minFactor) factor = minFactor;
17957            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17958            for (int i=N-1; i>=0; i--) {
17959                ProcessRecord app = mLruProcesses.get(i);
17960                if (allChanged || app.procStateChanged) {
17961                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17962                    app.procStateChanged = false;
17963                }
17964                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17965                        && !app.killedByAm) {
17966                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17967                        try {
17968                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17969                                    "Trimming memory of " + app.processName
17970                                    + " to " + curLevel);
17971                            app.thread.scheduleTrimMemory(curLevel);
17972                        } catch (RemoteException e) {
17973                        }
17974                        if (false) {
17975                            // For now we won't do this; our memory trimming seems
17976                            // to be good enough at this point that destroying
17977                            // activities causes more harm than good.
17978                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17979                                    && app != mHomeProcess && app != mPreviousProcess) {
17980                                // Need to do this on its own message because the stack may not
17981                                // be in a consistent state at this point.
17982                                // For these apps we will also finish their activities
17983                                // to help them free memory.
17984                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17985                            }
17986                        }
17987                    }
17988                    app.trimMemoryLevel = curLevel;
17989                    step++;
17990                    if (step >= factor) {
17991                        step = 0;
17992                        switch (curLevel) {
17993                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17994                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17995                                break;
17996                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17997                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17998                                break;
17999                        }
18000                    }
18001                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18002                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18003                            && app.thread != null) {
18004                        try {
18005                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18006                                    "Trimming memory of heavy-weight " + app.processName
18007                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18008                            app.thread.scheduleTrimMemory(
18009                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18010                        } catch (RemoteException e) {
18011                        }
18012                    }
18013                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18014                } else {
18015                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18016                            || app.systemNoUi) && app.pendingUiClean) {
18017                        // If this application is now in the background and it
18018                        // had done UI, then give it the special trim level to
18019                        // have it free UI resources.
18020                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18021                        if (app.trimMemoryLevel < level && app.thread != null) {
18022                            try {
18023                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18024                                        "Trimming memory of bg-ui " + app.processName
18025                                        + " to " + level);
18026                                app.thread.scheduleTrimMemory(level);
18027                            } catch (RemoteException e) {
18028                            }
18029                        }
18030                        app.pendingUiClean = false;
18031                    }
18032                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18033                        try {
18034                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18035                                    "Trimming memory of fg " + app.processName
18036                                    + " to " + fgTrimLevel);
18037                            app.thread.scheduleTrimMemory(fgTrimLevel);
18038                        } catch (RemoteException e) {
18039                        }
18040                    }
18041                    app.trimMemoryLevel = fgTrimLevel;
18042                }
18043            }
18044        } else {
18045            if (mLowRamStartTime != 0) {
18046                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18047                mLowRamStartTime = 0;
18048            }
18049            for (int i=N-1; i>=0; i--) {
18050                ProcessRecord app = mLruProcesses.get(i);
18051                if (allChanged || app.procStateChanged) {
18052                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18053                    app.procStateChanged = false;
18054                }
18055                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18056                        || app.systemNoUi) && app.pendingUiClean) {
18057                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18058                            && app.thread != null) {
18059                        try {
18060                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18061                                    "Trimming memory of ui hidden " + app.processName
18062                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18063                            app.thread.scheduleTrimMemory(
18064                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18065                        } catch (RemoteException e) {
18066                        }
18067                    }
18068                    app.pendingUiClean = false;
18069                }
18070                app.trimMemoryLevel = 0;
18071            }
18072        }
18073
18074        if (mAlwaysFinishActivities) {
18075            // Need to do this on its own message because the stack may not
18076            // be in a consistent state at this point.
18077            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18078        }
18079
18080        if (allChanged) {
18081            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18082        }
18083
18084        if (mProcessStats.shouldWriteNowLocked(now)) {
18085            mHandler.post(new Runnable() {
18086                @Override public void run() {
18087                    synchronized (ActivityManagerService.this) {
18088                        mProcessStats.writeStateAsyncLocked();
18089                    }
18090                }
18091            });
18092        }
18093
18094        if (DEBUG_OOM_ADJ) {
18095            if (false) {
18096                RuntimeException here = new RuntimeException("here");
18097                here.fillInStackTrace();
18098                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18099            } else {
18100                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18101            }
18102        }
18103    }
18104
18105    final void trimApplications() {
18106        synchronized (this) {
18107            int i;
18108
18109            // First remove any unused application processes whose package
18110            // has been removed.
18111            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18112                final ProcessRecord app = mRemovedProcesses.get(i);
18113                if (app.activities.size() == 0
18114                        && app.curReceiver == null && app.services.size() == 0) {
18115                    Slog.i(
18116                        TAG, "Exiting empty application process "
18117                        + app.processName + " ("
18118                        + (app.thread != null ? app.thread.asBinder() : null)
18119                        + ")\n");
18120                    if (app.pid > 0 && app.pid != MY_PID) {
18121                        app.kill("empty", false);
18122                    } else {
18123                        try {
18124                            app.thread.scheduleExit();
18125                        } catch (Exception e) {
18126                            // Ignore exceptions.
18127                        }
18128                    }
18129                    cleanUpApplicationRecordLocked(app, false, true, -1);
18130                    mRemovedProcesses.remove(i);
18131
18132                    if (app.persistent) {
18133                        addAppLocked(app.info, false, null /* ABI override */);
18134                    }
18135                }
18136            }
18137
18138            // Now update the oom adj for all processes.
18139            updateOomAdjLocked();
18140        }
18141    }
18142
18143    /** This method sends the specified signal to each of the persistent apps */
18144    public void signalPersistentProcesses(int sig) throws RemoteException {
18145        if (sig != Process.SIGNAL_USR1) {
18146            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18147        }
18148
18149        synchronized (this) {
18150            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18151                    != PackageManager.PERMISSION_GRANTED) {
18152                throw new SecurityException("Requires permission "
18153                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18154            }
18155
18156            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18157                ProcessRecord r = mLruProcesses.get(i);
18158                if (r.thread != null && r.persistent) {
18159                    Process.sendSignal(r.pid, sig);
18160                }
18161            }
18162        }
18163    }
18164
18165    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18166        if (proc == null || proc == mProfileProc) {
18167            proc = mProfileProc;
18168            profileType = mProfileType;
18169            clearProfilerLocked();
18170        }
18171        if (proc == null) {
18172            return;
18173        }
18174        try {
18175            proc.thread.profilerControl(false, null, profileType);
18176        } catch (RemoteException e) {
18177            throw new IllegalStateException("Process disappeared");
18178        }
18179    }
18180
18181    private void clearProfilerLocked() {
18182        if (mProfileFd != null) {
18183            try {
18184                mProfileFd.close();
18185            } catch (IOException e) {
18186            }
18187        }
18188        mProfileApp = null;
18189        mProfileProc = null;
18190        mProfileFile = null;
18191        mProfileType = 0;
18192        mAutoStopProfiler = false;
18193        mSamplingInterval = 0;
18194    }
18195
18196    public boolean profileControl(String process, int userId, boolean start,
18197            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18198
18199        try {
18200            synchronized (this) {
18201                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18202                // its own permission.
18203                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18204                        != PackageManager.PERMISSION_GRANTED) {
18205                    throw new SecurityException("Requires permission "
18206                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18207                }
18208
18209                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18210                    throw new IllegalArgumentException("null profile info or fd");
18211                }
18212
18213                ProcessRecord proc = null;
18214                if (process != null) {
18215                    proc = findProcessLocked(process, userId, "profileControl");
18216                }
18217
18218                if (start && (proc == null || proc.thread == null)) {
18219                    throw new IllegalArgumentException("Unknown process: " + process);
18220                }
18221
18222                if (start) {
18223                    stopProfilerLocked(null, 0);
18224                    setProfileApp(proc.info, proc.processName, profilerInfo);
18225                    mProfileProc = proc;
18226                    mProfileType = profileType;
18227                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18228                    try {
18229                        fd = fd.dup();
18230                    } catch (IOException e) {
18231                        fd = null;
18232                    }
18233                    profilerInfo.profileFd = fd;
18234                    proc.thread.profilerControl(start, profilerInfo, profileType);
18235                    fd = null;
18236                    mProfileFd = null;
18237                } else {
18238                    stopProfilerLocked(proc, profileType);
18239                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18240                        try {
18241                            profilerInfo.profileFd.close();
18242                        } catch (IOException e) {
18243                        }
18244                    }
18245                }
18246
18247                return true;
18248            }
18249        } catch (RemoteException e) {
18250            throw new IllegalStateException("Process disappeared");
18251        } finally {
18252            if (profilerInfo != null && profilerInfo.profileFd != null) {
18253                try {
18254                    profilerInfo.profileFd.close();
18255                } catch (IOException e) {
18256                }
18257            }
18258        }
18259    }
18260
18261    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18262        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18263                userId, true, ALLOW_FULL_ONLY, callName, null);
18264        ProcessRecord proc = null;
18265        try {
18266            int pid = Integer.parseInt(process);
18267            synchronized (mPidsSelfLocked) {
18268                proc = mPidsSelfLocked.get(pid);
18269            }
18270        } catch (NumberFormatException e) {
18271        }
18272
18273        if (proc == null) {
18274            ArrayMap<String, SparseArray<ProcessRecord>> all
18275                    = mProcessNames.getMap();
18276            SparseArray<ProcessRecord> procs = all.get(process);
18277            if (procs != null && procs.size() > 0) {
18278                proc = procs.valueAt(0);
18279                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18280                    for (int i=1; i<procs.size(); i++) {
18281                        ProcessRecord thisProc = procs.valueAt(i);
18282                        if (thisProc.userId == userId) {
18283                            proc = thisProc;
18284                            break;
18285                        }
18286                    }
18287                }
18288            }
18289        }
18290
18291        return proc;
18292    }
18293
18294    public boolean dumpHeap(String process, int userId, boolean managed,
18295            String path, ParcelFileDescriptor fd) throws RemoteException {
18296
18297        try {
18298            synchronized (this) {
18299                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18300                // its own permission (same as profileControl).
18301                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18302                        != PackageManager.PERMISSION_GRANTED) {
18303                    throw new SecurityException("Requires permission "
18304                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18305                }
18306
18307                if (fd == null) {
18308                    throw new IllegalArgumentException("null fd");
18309                }
18310
18311                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18312                if (proc == null || proc.thread == null) {
18313                    throw new IllegalArgumentException("Unknown process: " + process);
18314                }
18315
18316                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18317                if (!isDebuggable) {
18318                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18319                        throw new SecurityException("Process not debuggable: " + proc);
18320                    }
18321                }
18322
18323                proc.thread.dumpHeap(managed, path, fd);
18324                fd = null;
18325                return true;
18326            }
18327        } catch (RemoteException e) {
18328            throw new IllegalStateException("Process disappeared");
18329        } finally {
18330            if (fd != null) {
18331                try {
18332                    fd.close();
18333                } catch (IOException e) {
18334                }
18335            }
18336        }
18337    }
18338
18339    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18340    public void monitor() {
18341        synchronized (this) { }
18342    }
18343
18344    void onCoreSettingsChange(Bundle settings) {
18345        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18346            ProcessRecord processRecord = mLruProcesses.get(i);
18347            try {
18348                if (processRecord.thread != null) {
18349                    processRecord.thread.setCoreSettings(settings);
18350                }
18351            } catch (RemoteException re) {
18352                /* ignore */
18353            }
18354        }
18355    }
18356
18357    // Multi-user methods
18358
18359    /**
18360     * Start user, if its not already running, but don't bring it to foreground.
18361     */
18362    @Override
18363    public boolean startUserInBackground(final int userId) {
18364        return startUser(userId, /* foreground */ false);
18365    }
18366
18367    /**
18368     * Start user, if its not already running, and bring it to foreground.
18369     */
18370    boolean startUserInForeground(final int userId, Dialog dlg) {
18371        boolean result = startUser(userId, /* foreground */ true);
18372        dlg.dismiss();
18373        return result;
18374    }
18375
18376    /**
18377     * Refreshes the list of users related to the current user when either a
18378     * user switch happens or when a new related user is started in the
18379     * background.
18380     */
18381    private void updateCurrentProfileIdsLocked() {
18382        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18383                mCurrentUserId, false /* enabledOnly */);
18384        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18385        for (int i = 0; i < currentProfileIds.length; i++) {
18386            currentProfileIds[i] = profiles.get(i).id;
18387        }
18388        mCurrentProfileIds = currentProfileIds;
18389
18390        synchronized (mUserProfileGroupIdsSelfLocked) {
18391            mUserProfileGroupIdsSelfLocked.clear();
18392            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18393            for (int i = 0; i < users.size(); i++) {
18394                UserInfo user = users.get(i);
18395                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18396                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18397                }
18398            }
18399        }
18400    }
18401
18402    private Set getProfileIdsLocked(int userId) {
18403        Set userIds = new HashSet<Integer>();
18404        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18405                userId, false /* enabledOnly */);
18406        for (UserInfo user : profiles) {
18407            userIds.add(Integer.valueOf(user.id));
18408        }
18409        return userIds;
18410    }
18411
18412    @Override
18413    public boolean switchUser(final int userId) {
18414        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18415        String userName;
18416        synchronized (this) {
18417            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18418            if (userInfo == null) {
18419                Slog.w(TAG, "No user info for user #" + userId);
18420                return false;
18421            }
18422            if (userInfo.isManagedProfile()) {
18423                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18424                return false;
18425            }
18426            userName = userInfo.name;
18427            mTargetUserId = userId;
18428        }
18429        mHandler.removeMessages(START_USER_SWITCH_MSG);
18430        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18431        return true;
18432    }
18433
18434    private void showUserSwitchDialog(int userId, String userName) {
18435        // The dialog will show and then initiate the user switch by calling startUserInForeground
18436        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18437                true /* above system */);
18438        d.show();
18439    }
18440
18441    private boolean startUser(final int userId, final boolean foreground) {
18442        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18443                != PackageManager.PERMISSION_GRANTED) {
18444            String msg = "Permission Denial: switchUser() from pid="
18445                    + Binder.getCallingPid()
18446                    + ", uid=" + Binder.getCallingUid()
18447                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18448            Slog.w(TAG, msg);
18449            throw new SecurityException(msg);
18450        }
18451
18452        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18453
18454        final long ident = Binder.clearCallingIdentity();
18455        try {
18456            synchronized (this) {
18457                final int oldUserId = mCurrentUserId;
18458                if (oldUserId == userId) {
18459                    return true;
18460                }
18461
18462                mStackSupervisor.setLockTaskModeLocked(null, false);
18463
18464                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18465                if (userInfo == null) {
18466                    Slog.w(TAG, "No user info for user #" + userId);
18467                    return false;
18468                }
18469                if (foreground && userInfo.isManagedProfile()) {
18470                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18471                    return false;
18472                }
18473
18474                if (foreground) {
18475                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18476                            R.anim.screen_user_enter);
18477                }
18478
18479                boolean needStart = false;
18480
18481                // If the user we are switching to is not currently started, then
18482                // we need to start it now.
18483                if (mStartedUsers.get(userId) == null) {
18484                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18485                    updateStartedUserArrayLocked();
18486                    needStart = true;
18487                }
18488
18489                final Integer userIdInt = Integer.valueOf(userId);
18490                mUserLru.remove(userIdInt);
18491                mUserLru.add(userIdInt);
18492
18493                if (foreground) {
18494                    mCurrentUserId = userId;
18495                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18496                    updateCurrentProfileIdsLocked();
18497                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18498                    // Once the internal notion of the active user has switched, we lock the device
18499                    // with the option to show the user switcher on the keyguard.
18500                    mWindowManager.lockNow(null);
18501                } else {
18502                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18503                    updateCurrentProfileIdsLocked();
18504                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18505                    mUserLru.remove(currentUserIdInt);
18506                    mUserLru.add(currentUserIdInt);
18507                }
18508
18509                final UserStartedState uss = mStartedUsers.get(userId);
18510
18511                // Make sure user is in the started state.  If it is currently
18512                // stopping, we need to knock that off.
18513                if (uss.mState == UserStartedState.STATE_STOPPING) {
18514                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18515                    // so we can just fairly silently bring the user back from
18516                    // the almost-dead.
18517                    uss.mState = UserStartedState.STATE_RUNNING;
18518                    updateStartedUserArrayLocked();
18519                    needStart = true;
18520                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18521                    // This means ACTION_SHUTDOWN has been sent, so we will
18522                    // need to treat this as a new boot of the user.
18523                    uss.mState = UserStartedState.STATE_BOOTING;
18524                    updateStartedUserArrayLocked();
18525                    needStart = true;
18526                }
18527
18528                if (uss.mState == UserStartedState.STATE_BOOTING) {
18529                    // Booting up a new user, need to tell system services about it.
18530                    // Note that this is on the same handler as scheduling of broadcasts,
18531                    // which is important because it needs to go first.
18532                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18533                }
18534
18535                if (foreground) {
18536                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18537                            oldUserId));
18538                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18539                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18540                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18541                            oldUserId, userId, uss));
18542                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18543                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18544                }
18545
18546                if (needStart) {
18547                    // Send USER_STARTED broadcast
18548                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18549                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18550                            | Intent.FLAG_RECEIVER_FOREGROUND);
18551                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18552                    broadcastIntentLocked(null, null, intent,
18553                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18554                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18555                }
18556
18557                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18558                    if (userId != UserHandle.USER_OWNER) {
18559                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18560                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18561                        broadcastIntentLocked(null, null, intent, null,
18562                                new IIntentReceiver.Stub() {
18563                                    public void performReceive(Intent intent, int resultCode,
18564                                            String data, Bundle extras, boolean ordered,
18565                                            boolean sticky, int sendingUser) {
18566                                        onUserInitialized(uss, foreground, oldUserId, userId);
18567                                    }
18568                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18569                                true, false, MY_PID, Process.SYSTEM_UID,
18570                                userId);
18571                        uss.initializing = true;
18572                    } else {
18573                        getUserManagerLocked().makeInitialized(userInfo.id);
18574                    }
18575                }
18576
18577                if (foreground) {
18578                    if (!uss.initializing) {
18579                        moveUserToForeground(uss, oldUserId, userId);
18580                    }
18581                } else {
18582                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18583                }
18584
18585                if (needStart) {
18586                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18587                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18588                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18589                    broadcastIntentLocked(null, null, intent,
18590                            null, new IIntentReceiver.Stub() {
18591                                @Override
18592                                public void performReceive(Intent intent, int resultCode, String data,
18593                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18594                                        throws RemoteException {
18595                                }
18596                            }, 0, null, null,
18597                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18598                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18599                }
18600            }
18601        } finally {
18602            Binder.restoreCallingIdentity(ident);
18603        }
18604
18605        return true;
18606    }
18607
18608    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18609        long ident = Binder.clearCallingIdentity();
18610        try {
18611            Intent intent;
18612            if (oldUserId >= 0) {
18613                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18614                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18615                int count = profiles.size();
18616                for (int i = 0; i < count; i++) {
18617                    int profileUserId = profiles.get(i).id;
18618                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18619                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18620                            | Intent.FLAG_RECEIVER_FOREGROUND);
18621                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18622                    broadcastIntentLocked(null, null, intent,
18623                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18624                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18625                }
18626            }
18627            if (newUserId >= 0) {
18628                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18629                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18630                int count = profiles.size();
18631                for (int i = 0; i < count; i++) {
18632                    int profileUserId = profiles.get(i).id;
18633                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18634                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18635                            | Intent.FLAG_RECEIVER_FOREGROUND);
18636                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18637                    broadcastIntentLocked(null, null, intent,
18638                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18639                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18640                }
18641                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18642                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18643                        | Intent.FLAG_RECEIVER_FOREGROUND);
18644                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18645                broadcastIntentLocked(null, null, intent,
18646                        null, null, 0, null, null,
18647                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18648                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18649            }
18650        } finally {
18651            Binder.restoreCallingIdentity(ident);
18652        }
18653    }
18654
18655    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18656            final int newUserId) {
18657        final int N = mUserSwitchObservers.beginBroadcast();
18658        if (N > 0) {
18659            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18660                int mCount = 0;
18661                @Override
18662                public void sendResult(Bundle data) throws RemoteException {
18663                    synchronized (ActivityManagerService.this) {
18664                        if (mCurUserSwitchCallback == this) {
18665                            mCount++;
18666                            if (mCount == N) {
18667                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18668                            }
18669                        }
18670                    }
18671                }
18672            };
18673            synchronized (this) {
18674                uss.switching = true;
18675                mCurUserSwitchCallback = callback;
18676            }
18677            for (int i=0; i<N; i++) {
18678                try {
18679                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18680                            newUserId, callback);
18681                } catch (RemoteException e) {
18682                }
18683            }
18684        } else {
18685            synchronized (this) {
18686                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18687            }
18688        }
18689        mUserSwitchObservers.finishBroadcast();
18690    }
18691
18692    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18693        synchronized (this) {
18694            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18695            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18696        }
18697    }
18698
18699    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18700        mCurUserSwitchCallback = null;
18701        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18702        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18703                oldUserId, newUserId, uss));
18704    }
18705
18706    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18707        synchronized (this) {
18708            if (foreground) {
18709                moveUserToForeground(uss, oldUserId, newUserId);
18710            }
18711        }
18712
18713        completeSwitchAndInitalize(uss, newUserId, true, false);
18714    }
18715
18716    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18717        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18718        if (homeInFront) {
18719            startHomeActivityLocked(newUserId);
18720        } else {
18721            mStackSupervisor.resumeTopActivitiesLocked();
18722        }
18723        EventLogTags.writeAmSwitchUser(newUserId);
18724        getUserManagerLocked().userForeground(newUserId);
18725        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18726    }
18727
18728    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18729        completeSwitchAndInitalize(uss, newUserId, false, true);
18730    }
18731
18732    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18733            boolean clearInitializing, boolean clearSwitching) {
18734        boolean unfrozen = false;
18735        synchronized (this) {
18736            if (clearInitializing) {
18737                uss.initializing = false;
18738                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18739            }
18740            if (clearSwitching) {
18741                uss.switching = false;
18742            }
18743            if (!uss.switching && !uss.initializing) {
18744                mWindowManager.stopFreezingScreen();
18745                unfrozen = true;
18746            }
18747        }
18748        if (unfrozen) {
18749            final int N = mUserSwitchObservers.beginBroadcast();
18750            for (int i=0; i<N; i++) {
18751                try {
18752                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18753                } catch (RemoteException e) {
18754                }
18755            }
18756            mUserSwitchObservers.finishBroadcast();
18757        }
18758    }
18759
18760    void scheduleStartProfilesLocked() {
18761        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18762            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18763                    DateUtils.SECOND_IN_MILLIS);
18764        }
18765    }
18766
18767    void startProfilesLocked() {
18768        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18769        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18770                mCurrentUserId, false /* enabledOnly */);
18771        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18772        for (UserInfo user : profiles) {
18773            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18774                    && user.id != mCurrentUserId) {
18775                toStart.add(user);
18776            }
18777        }
18778        final int n = toStart.size();
18779        int i = 0;
18780        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18781            startUserInBackground(toStart.get(i).id);
18782        }
18783        if (i < n) {
18784            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18785        }
18786    }
18787
18788    void finishUserBoot(UserStartedState uss) {
18789        synchronized (this) {
18790            if (uss.mState == UserStartedState.STATE_BOOTING
18791                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18792                uss.mState = UserStartedState.STATE_RUNNING;
18793                final int userId = uss.mHandle.getIdentifier();
18794                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18795                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18796                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18797                broadcastIntentLocked(null, null, intent,
18798                        null, null, 0, null, null,
18799                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18800                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18801            }
18802        }
18803    }
18804
18805    void finishUserSwitch(UserStartedState uss) {
18806        synchronized (this) {
18807            finishUserBoot(uss);
18808
18809            startProfilesLocked();
18810
18811            int num = mUserLru.size();
18812            int i = 0;
18813            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18814                Integer oldUserId = mUserLru.get(i);
18815                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18816                if (oldUss == null) {
18817                    // Shouldn't happen, but be sane if it does.
18818                    mUserLru.remove(i);
18819                    num--;
18820                    continue;
18821                }
18822                if (oldUss.mState == UserStartedState.STATE_STOPPING
18823                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18824                    // This user is already stopping, doesn't count.
18825                    num--;
18826                    i++;
18827                    continue;
18828                }
18829                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18830                    // Owner and current can't be stopped, but count as running.
18831                    i++;
18832                    continue;
18833                }
18834                // This is a user to be stopped.
18835                stopUserLocked(oldUserId, null);
18836                num--;
18837                i++;
18838            }
18839        }
18840    }
18841
18842    @Override
18843    public int stopUser(final int userId, final IStopUserCallback callback) {
18844        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18845                != PackageManager.PERMISSION_GRANTED) {
18846            String msg = "Permission Denial: switchUser() from pid="
18847                    + Binder.getCallingPid()
18848                    + ", uid=" + Binder.getCallingUid()
18849                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18850            Slog.w(TAG, msg);
18851            throw new SecurityException(msg);
18852        }
18853        if (userId <= 0) {
18854            throw new IllegalArgumentException("Can't stop primary user " + userId);
18855        }
18856        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18857        synchronized (this) {
18858            return stopUserLocked(userId, callback);
18859        }
18860    }
18861
18862    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18863        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18864        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18865            return ActivityManager.USER_OP_IS_CURRENT;
18866        }
18867
18868        final UserStartedState uss = mStartedUsers.get(userId);
18869        if (uss == null) {
18870            // User is not started, nothing to do...  but we do need to
18871            // callback if requested.
18872            if (callback != null) {
18873                mHandler.post(new Runnable() {
18874                    @Override
18875                    public void run() {
18876                        try {
18877                            callback.userStopped(userId);
18878                        } catch (RemoteException e) {
18879                        }
18880                    }
18881                });
18882            }
18883            return ActivityManager.USER_OP_SUCCESS;
18884        }
18885
18886        if (callback != null) {
18887            uss.mStopCallbacks.add(callback);
18888        }
18889
18890        if (uss.mState != UserStartedState.STATE_STOPPING
18891                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18892            uss.mState = UserStartedState.STATE_STOPPING;
18893            updateStartedUserArrayLocked();
18894
18895            long ident = Binder.clearCallingIdentity();
18896            try {
18897                // We are going to broadcast ACTION_USER_STOPPING and then
18898                // once that is done send a final ACTION_SHUTDOWN and then
18899                // stop the user.
18900                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18901                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18902                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18903                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18904                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18905                // This is the result receiver for the final shutdown broadcast.
18906                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18907                    @Override
18908                    public void performReceive(Intent intent, int resultCode, String data,
18909                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18910                        finishUserStop(uss);
18911                    }
18912                };
18913                // This is the result receiver for the initial stopping broadcast.
18914                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18915                    @Override
18916                    public void performReceive(Intent intent, int resultCode, String data,
18917                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18918                        // On to the next.
18919                        synchronized (ActivityManagerService.this) {
18920                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18921                                // Whoops, we are being started back up.  Abort, abort!
18922                                return;
18923                            }
18924                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18925                        }
18926                        mBatteryStatsService.noteEvent(
18927                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18928                                Integer.toString(userId), userId);
18929                        mSystemServiceManager.stopUser(userId);
18930                        broadcastIntentLocked(null, null, shutdownIntent,
18931                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18932                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18933                    }
18934                };
18935                // Kick things off.
18936                broadcastIntentLocked(null, null, stoppingIntent,
18937                        null, stoppingReceiver, 0, null, null,
18938                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18939                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18940            } finally {
18941                Binder.restoreCallingIdentity(ident);
18942            }
18943        }
18944
18945        return ActivityManager.USER_OP_SUCCESS;
18946    }
18947
18948    void finishUserStop(UserStartedState uss) {
18949        final int userId = uss.mHandle.getIdentifier();
18950        boolean stopped;
18951        ArrayList<IStopUserCallback> callbacks;
18952        synchronized (this) {
18953            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18954            if (mStartedUsers.get(userId) != uss) {
18955                stopped = false;
18956            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18957                stopped = false;
18958            } else {
18959                stopped = true;
18960                // User can no longer run.
18961                mStartedUsers.remove(userId);
18962                mUserLru.remove(Integer.valueOf(userId));
18963                updateStartedUserArrayLocked();
18964
18965                // Clean up all state and processes associated with the user.
18966                // Kill all the processes for the user.
18967                forceStopUserLocked(userId, "finish user");
18968            }
18969
18970            // Explicitly remove the old information in mRecentTasks.
18971            removeRecentTasksForUserLocked(userId);
18972        }
18973
18974        for (int i=0; i<callbacks.size(); i++) {
18975            try {
18976                if (stopped) callbacks.get(i).userStopped(userId);
18977                else callbacks.get(i).userStopAborted(userId);
18978            } catch (RemoteException e) {
18979            }
18980        }
18981
18982        if (stopped) {
18983            mSystemServiceManager.cleanupUser(userId);
18984            synchronized (this) {
18985                mStackSupervisor.removeUserLocked(userId);
18986            }
18987        }
18988    }
18989
18990    @Override
18991    public UserInfo getCurrentUser() {
18992        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18993                != PackageManager.PERMISSION_GRANTED) && (
18994                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18995                != PackageManager.PERMISSION_GRANTED)) {
18996            String msg = "Permission Denial: getCurrentUser() 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            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19005            return getUserManagerLocked().getUserInfo(userId);
19006        }
19007    }
19008
19009    int getCurrentUserIdLocked() {
19010        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19011    }
19012
19013    @Override
19014    public boolean isUserRunning(int userId, boolean orStopped) {
19015        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19016                != PackageManager.PERMISSION_GRANTED) {
19017            String msg = "Permission Denial: isUserRunning() from pid="
19018                    + Binder.getCallingPid()
19019                    + ", uid=" + Binder.getCallingUid()
19020                    + " requires " + INTERACT_ACROSS_USERS;
19021            Slog.w(TAG, msg);
19022            throw new SecurityException(msg);
19023        }
19024        synchronized (this) {
19025            return isUserRunningLocked(userId, orStopped);
19026        }
19027    }
19028
19029    boolean isUserRunningLocked(int userId, boolean orStopped) {
19030        UserStartedState state = mStartedUsers.get(userId);
19031        if (state == null) {
19032            return false;
19033        }
19034        if (orStopped) {
19035            return true;
19036        }
19037        return state.mState != UserStartedState.STATE_STOPPING
19038                && state.mState != UserStartedState.STATE_SHUTDOWN;
19039    }
19040
19041    @Override
19042    public int[] getRunningUserIds() {
19043        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19044                != PackageManager.PERMISSION_GRANTED) {
19045            String msg = "Permission Denial: isUserRunning() from pid="
19046                    + Binder.getCallingPid()
19047                    + ", uid=" + Binder.getCallingUid()
19048                    + " requires " + INTERACT_ACROSS_USERS;
19049            Slog.w(TAG, msg);
19050            throw new SecurityException(msg);
19051        }
19052        synchronized (this) {
19053            return mStartedUserArray;
19054        }
19055    }
19056
19057    private void updateStartedUserArrayLocked() {
19058        int num = 0;
19059        for (int i=0; i<mStartedUsers.size();  i++) {
19060            UserStartedState uss = mStartedUsers.valueAt(i);
19061            // This list does not include stopping users.
19062            if (uss.mState != UserStartedState.STATE_STOPPING
19063                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19064                num++;
19065            }
19066        }
19067        mStartedUserArray = new int[num];
19068        num = 0;
19069        for (int i=0; i<mStartedUsers.size();  i++) {
19070            UserStartedState uss = mStartedUsers.valueAt(i);
19071            if (uss.mState != UserStartedState.STATE_STOPPING
19072                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19073                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19074                num++;
19075            }
19076        }
19077    }
19078
19079    @Override
19080    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19081        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19082                != PackageManager.PERMISSION_GRANTED) {
19083            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19084                    + Binder.getCallingPid()
19085                    + ", uid=" + Binder.getCallingUid()
19086                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19087            Slog.w(TAG, msg);
19088            throw new SecurityException(msg);
19089        }
19090
19091        mUserSwitchObservers.register(observer);
19092    }
19093
19094    @Override
19095    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19096        mUserSwitchObservers.unregister(observer);
19097    }
19098
19099    private boolean userExists(int userId) {
19100        if (userId == 0) {
19101            return true;
19102        }
19103        UserManagerService ums = getUserManagerLocked();
19104        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19105    }
19106
19107    int[] getUsersLocked() {
19108        UserManagerService ums = getUserManagerLocked();
19109        return ums != null ? ums.getUserIds() : new int[] { 0 };
19110    }
19111
19112    UserManagerService getUserManagerLocked() {
19113        if (mUserManager == null) {
19114            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19115            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19116        }
19117        return mUserManager;
19118    }
19119
19120    private int applyUserId(int uid, int userId) {
19121        return UserHandle.getUid(userId, uid);
19122    }
19123
19124    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19125        if (info == null) return null;
19126        ApplicationInfo newInfo = new ApplicationInfo(info);
19127        newInfo.uid = applyUserId(info.uid, userId);
19128        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19129                + info.packageName;
19130        return newInfo;
19131    }
19132
19133    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19134        if (aInfo == null
19135                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19136            return aInfo;
19137        }
19138
19139        ActivityInfo info = new ActivityInfo(aInfo);
19140        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19141        return info;
19142    }
19143
19144    private final class LocalService extends ActivityManagerInternal {
19145        @Override
19146        public void goingToSleep() {
19147            ActivityManagerService.this.goingToSleep();
19148        }
19149
19150        @Override
19151        public void wakingUp() {
19152            ActivityManagerService.this.wakingUp();
19153        }
19154
19155        @Override
19156        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19157                String processName, String abiOverride, int uid, Runnable crashHandler) {
19158            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19159                    processName, abiOverride, uid, crashHandler);
19160        }
19161    }
19162
19163    /**
19164     * An implementation of IAppTask, that allows an app to manage its own tasks via
19165     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19166     * only the process that calls getAppTasks() can call the AppTask methods.
19167     */
19168    class AppTaskImpl extends IAppTask.Stub {
19169        private int mTaskId;
19170        private int mCallingUid;
19171
19172        public AppTaskImpl(int taskId, int callingUid) {
19173            mTaskId = taskId;
19174            mCallingUid = callingUid;
19175        }
19176
19177        private void checkCaller() {
19178            if (mCallingUid != Binder.getCallingUid()) {
19179                throw new SecurityException("Caller " + mCallingUid
19180                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19181            }
19182        }
19183
19184        @Override
19185        public void finishAndRemoveTask() {
19186            checkCaller();
19187
19188            synchronized (ActivityManagerService.this) {
19189                long origId = Binder.clearCallingIdentity();
19190                try {
19191                    if (!removeTaskByIdLocked(mTaskId, false)) {
19192                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19193                    }
19194                } finally {
19195                    Binder.restoreCallingIdentity(origId);
19196                }
19197            }
19198        }
19199
19200        @Override
19201        public ActivityManager.RecentTaskInfo getTaskInfo() {
19202            checkCaller();
19203
19204            synchronized (ActivityManagerService.this) {
19205                long origId = Binder.clearCallingIdentity();
19206                try {
19207                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19208                    if (tr == null) {
19209                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19210                    }
19211                    return createRecentTaskInfoFromTaskRecord(tr);
19212                } finally {
19213                    Binder.restoreCallingIdentity(origId);
19214                }
19215            }
19216        }
19217
19218        @Override
19219        public void moveToFront() {
19220            checkCaller();
19221
19222            final TaskRecord tr;
19223            synchronized (ActivityManagerService.this) {
19224                tr = recentTaskForIdLocked(mTaskId);
19225                if (tr == null) {
19226                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19227                }
19228                if (tr.getRootActivity() != null) {
19229                    moveTaskToFrontLocked(tr.taskId, 0, null);
19230                    return;
19231                }
19232            }
19233
19234            startActivityFromRecentsInner(tr.taskId, null);
19235        }
19236
19237        @Override
19238        public int startActivity(IBinder whoThread, String callingPackage,
19239                Intent intent, String resolvedType, Bundle options) {
19240            checkCaller();
19241
19242            int callingUser = UserHandle.getCallingUserId();
19243            TaskRecord tr;
19244            IApplicationThread appThread;
19245            synchronized (ActivityManagerService.this) {
19246                tr = recentTaskForIdLocked(mTaskId);
19247                if (tr == null) {
19248                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19249                }
19250                appThread = ApplicationThreadNative.asInterface(whoThread);
19251                if (appThread == null) {
19252                    throw new IllegalArgumentException("Bad app thread " + appThread);
19253                }
19254            }
19255            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19256                    resolvedType, null, null, null, null, 0, 0, null, null,
19257                    null, options, callingUser, null, tr);
19258        }
19259
19260        @Override
19261        public void setExcludeFromRecents(boolean exclude) {
19262            checkCaller();
19263
19264            synchronized (ActivityManagerService.this) {
19265                long origId = Binder.clearCallingIdentity();
19266                try {
19267                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19268                    if (tr == null) {
19269                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19270                    }
19271                    Intent intent = tr.getBaseIntent();
19272                    if (exclude) {
19273                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19274                    } else {
19275                        intent.setFlags(intent.getFlags()
19276                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19277                    }
19278                } finally {
19279                    Binder.restoreCallingIdentity(origId);
19280                }
19281            }
19282        }
19283    }
19284}
19285