ActivityManagerService.java revision 83b6ef01a07d2e7f06dfee7fd698b27bd62ca9a0
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            if (rootR == null) {
4288                Slog.w(TAG, "Finishing task with all activities already finished");
4289            }
4290            // Do not allow task to finish in Lock Task mode.
4291            if (tr == mStackSupervisor.mLockTaskModeTask) {
4292                if (rootR == r) {
4293                    Slog.i(TAG, "Not finishing task in lock task mode");
4294                    mStackSupervisor.showLockTaskToast();
4295                    return false;
4296                }
4297            }
4298            if (mController != null) {
4299                // Find the first activity that is not finishing.
4300                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4301                if (next != null) {
4302                    // ask watcher if this is allowed
4303                    boolean resumeOK = true;
4304                    try {
4305                        resumeOK = mController.activityResuming(next.packageName);
4306                    } catch (RemoteException e) {
4307                        mController = null;
4308                        Watchdog.getInstance().setActivityController(null);
4309                    }
4310
4311                    if (!resumeOK) {
4312                        Slog.i(TAG, "Not finishing activity because controller resumed");
4313                        return false;
4314                    }
4315                }
4316            }
4317            final long origId = Binder.clearCallingIdentity();
4318            try {
4319                boolean res;
4320                if (finishTask && r == rootR) {
4321                    // If requested, remove the task that is associated to this activity only if it
4322                    // was the root activity in the task. The result code and data is ignored
4323                    // because we don't support returning them across task boundaries.
4324                    res = removeTaskByIdLocked(tr.taskId, false);
4325                    if (!res) {
4326                        Slog.i(TAG, "Removing task failed to finish activity");
4327                    }
4328                } else {
4329                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4330                            resultData, "app-request", true);
4331                    if (!res) {
4332                        Slog.i(TAG, "Failed to finish by app-request");
4333                    }
4334                }
4335                return res;
4336            } finally {
4337                Binder.restoreCallingIdentity(origId);
4338            }
4339        }
4340    }
4341
4342    @Override
4343    public final void finishHeavyWeightApp() {
4344        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4345                != PackageManager.PERMISSION_GRANTED) {
4346            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4347                    + Binder.getCallingPid()
4348                    + ", uid=" + Binder.getCallingUid()
4349                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4350            Slog.w(TAG, msg);
4351            throw new SecurityException(msg);
4352        }
4353
4354        synchronized(this) {
4355            if (mHeavyWeightProcess == null) {
4356                return;
4357            }
4358
4359            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4360                    mHeavyWeightProcess.activities);
4361            for (int i=0; i<activities.size(); i++) {
4362                ActivityRecord r = activities.get(i);
4363                if (!r.finishing) {
4364                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4365                            null, "finish-heavy", true);
4366                }
4367            }
4368
4369            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4370                    mHeavyWeightProcess.userId, 0));
4371            mHeavyWeightProcess = null;
4372        }
4373    }
4374
4375    @Override
4376    public void crashApplication(int uid, int initialPid, String packageName,
4377            String message) {
4378        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4379                != PackageManager.PERMISSION_GRANTED) {
4380            String msg = "Permission Denial: crashApplication() from pid="
4381                    + Binder.getCallingPid()
4382                    + ", uid=" + Binder.getCallingUid()
4383                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4384            Slog.w(TAG, msg);
4385            throw new SecurityException(msg);
4386        }
4387
4388        synchronized(this) {
4389            ProcessRecord proc = null;
4390
4391            // Figure out which process to kill.  We don't trust that initialPid
4392            // still has any relation to current pids, so must scan through the
4393            // list.
4394            synchronized (mPidsSelfLocked) {
4395                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4396                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4397                    if (p.uid != uid) {
4398                        continue;
4399                    }
4400                    if (p.pid == initialPid) {
4401                        proc = p;
4402                        break;
4403                    }
4404                    if (p.pkgList.containsKey(packageName)) {
4405                        proc = p;
4406                    }
4407                }
4408            }
4409
4410            if (proc == null) {
4411                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4412                        + " initialPid=" + initialPid
4413                        + " packageName=" + packageName);
4414                return;
4415            }
4416
4417            if (proc.thread != null) {
4418                if (proc.pid == Process.myPid()) {
4419                    Log.w(TAG, "crashApplication: trying to crash self!");
4420                    return;
4421                }
4422                long ident = Binder.clearCallingIdentity();
4423                try {
4424                    proc.thread.scheduleCrash(message);
4425                } catch (RemoteException e) {
4426                }
4427                Binder.restoreCallingIdentity(ident);
4428            }
4429        }
4430    }
4431
4432    @Override
4433    public final void finishSubActivity(IBinder token, String resultWho,
4434            int requestCode) {
4435        synchronized(this) {
4436            final long origId = Binder.clearCallingIdentity();
4437            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4438            if (r != null) {
4439                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4440            }
4441            Binder.restoreCallingIdentity(origId);
4442        }
4443    }
4444
4445    @Override
4446    public boolean finishActivityAffinity(IBinder token) {
4447        synchronized(this) {
4448            final long origId = Binder.clearCallingIdentity();
4449            try {
4450                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4451
4452                ActivityRecord rootR = r.task.getRootActivity();
4453                // Do not allow task to finish in Lock Task mode.
4454                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4455                    if (rootR == r) {
4456                        mStackSupervisor.showLockTaskToast();
4457                        return false;
4458                    }
4459                }
4460                boolean res = false;
4461                if (r != null) {
4462                    res = r.task.stack.finishActivityAffinityLocked(r);
4463                }
4464                return res;
4465            } finally {
4466                Binder.restoreCallingIdentity(origId);
4467            }
4468        }
4469    }
4470
4471    @Override
4472    public void finishVoiceTask(IVoiceInteractionSession session) {
4473        synchronized(this) {
4474            final long origId = Binder.clearCallingIdentity();
4475            try {
4476                mStackSupervisor.finishVoiceTask(session);
4477            } finally {
4478                Binder.restoreCallingIdentity(origId);
4479            }
4480        }
4481
4482    }
4483
4484    @Override
4485    public boolean releaseActivityInstance(IBinder token) {
4486        synchronized(this) {
4487            final long origId = Binder.clearCallingIdentity();
4488            try {
4489                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4490                if (r.task == null || r.task.stack == null) {
4491                    return false;
4492                }
4493                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4494            } finally {
4495                Binder.restoreCallingIdentity(origId);
4496            }
4497        }
4498    }
4499
4500    @Override
4501    public void releaseSomeActivities(IApplicationThread appInt) {
4502        synchronized(this) {
4503            final long origId = Binder.clearCallingIdentity();
4504            try {
4505                ProcessRecord app = getRecordForAppLocked(appInt);
4506                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4507            } finally {
4508                Binder.restoreCallingIdentity(origId);
4509            }
4510        }
4511    }
4512
4513    @Override
4514    public boolean willActivityBeVisible(IBinder token) {
4515        synchronized(this) {
4516            ActivityStack stack = ActivityRecord.getStackLocked(token);
4517            if (stack != null) {
4518                return stack.willActivityBeVisibleLocked(token);
4519            }
4520            return false;
4521        }
4522    }
4523
4524    @Override
4525    public void overridePendingTransition(IBinder token, String packageName,
4526            int enterAnim, int exitAnim) {
4527        synchronized(this) {
4528            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4529            if (self == null) {
4530                return;
4531            }
4532
4533            final long origId = Binder.clearCallingIdentity();
4534
4535            if (self.state == ActivityState.RESUMED
4536                    || self.state == ActivityState.PAUSING) {
4537                mWindowManager.overridePendingAppTransition(packageName,
4538                        enterAnim, exitAnim, null);
4539            }
4540
4541            Binder.restoreCallingIdentity(origId);
4542        }
4543    }
4544
4545    /**
4546     * Main function for removing an existing process from the activity manager
4547     * as a result of that process going away.  Clears out all connections
4548     * to the process.
4549     */
4550    private final void handleAppDiedLocked(ProcessRecord app,
4551            boolean restarting, boolean allowRestart) {
4552        int pid = app.pid;
4553        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4554        if (!kept && !restarting) {
4555            removeLruProcessLocked(app);
4556            if (pid > 0) {
4557                ProcessList.remove(pid);
4558            }
4559        }
4560
4561        if (mProfileProc == app) {
4562            clearProfilerLocked();
4563        }
4564
4565        // Remove this application's activities from active lists.
4566        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4567
4568        app.activities.clear();
4569
4570        if (app.instrumentationClass != null) {
4571            Slog.w(TAG, "Crash of app " + app.processName
4572                  + " running instrumentation " + app.instrumentationClass);
4573            Bundle info = new Bundle();
4574            info.putString("shortMsg", "Process crashed.");
4575            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4576        }
4577
4578        if (!restarting) {
4579            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4580                // If there was nothing to resume, and we are not already
4581                // restarting this process, but there is a visible activity that
4582                // is hosted by the process...  then make sure all visible
4583                // activities are running, taking care of restarting this
4584                // process.
4585                if (hasVisibleActivities) {
4586                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4587                }
4588            }
4589        }
4590    }
4591
4592    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4593        IBinder threadBinder = thread.asBinder();
4594        // Find the application record.
4595        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4596            ProcessRecord rec = mLruProcesses.get(i);
4597            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4598                return i;
4599            }
4600        }
4601        return -1;
4602    }
4603
4604    final ProcessRecord getRecordForAppLocked(
4605            IApplicationThread thread) {
4606        if (thread == null) {
4607            return null;
4608        }
4609
4610        int appIndex = getLRURecordIndexForAppLocked(thread);
4611        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4612    }
4613
4614    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4615        // If there are no longer any background processes running,
4616        // and the app that died was not running instrumentation,
4617        // then tell everyone we are now low on memory.
4618        boolean haveBg = false;
4619        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4620            ProcessRecord rec = mLruProcesses.get(i);
4621            if (rec.thread != null
4622                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4623                haveBg = true;
4624                break;
4625            }
4626        }
4627
4628        if (!haveBg) {
4629            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4630            if (doReport) {
4631                long now = SystemClock.uptimeMillis();
4632                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4633                    doReport = false;
4634                } else {
4635                    mLastMemUsageReportTime = now;
4636                }
4637            }
4638            final ArrayList<ProcessMemInfo> memInfos
4639                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4640            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4641            long now = SystemClock.uptimeMillis();
4642            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4643                ProcessRecord rec = mLruProcesses.get(i);
4644                if (rec == dyingProc || rec.thread == null) {
4645                    continue;
4646                }
4647                if (doReport) {
4648                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4649                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4650                }
4651                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4652                    // The low memory report is overriding any current
4653                    // state for a GC request.  Make sure to do
4654                    // heavy/important/visible/foreground processes first.
4655                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4656                        rec.lastRequestedGc = 0;
4657                    } else {
4658                        rec.lastRequestedGc = rec.lastLowMemory;
4659                    }
4660                    rec.reportLowMemory = true;
4661                    rec.lastLowMemory = now;
4662                    mProcessesToGc.remove(rec);
4663                    addProcessToGcListLocked(rec);
4664                }
4665            }
4666            if (doReport) {
4667                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4668                mHandler.sendMessage(msg);
4669            }
4670            scheduleAppGcsLocked();
4671        }
4672    }
4673
4674    final void appDiedLocked(ProcessRecord app) {
4675       appDiedLocked(app, app.pid, app.thread);
4676    }
4677
4678    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4679        // First check if this ProcessRecord is actually active for the pid.
4680        synchronized (mPidsSelfLocked) {
4681            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4682            if (curProc != app) {
4683                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4684                return;
4685            }
4686        }
4687
4688        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4689        synchronized (stats) {
4690            stats.noteProcessDiedLocked(app.info.uid, pid);
4691        }
4692
4693        Process.killProcessQuiet(pid);
4694        Process.killProcessGroup(app.info.uid, pid);
4695        app.killed = true;
4696
4697        // Clean up already done if the process has been re-started.
4698        if (app.pid == pid && app.thread != null &&
4699                app.thread.asBinder() == thread.asBinder()) {
4700            boolean doLowMem = app.instrumentationClass == null;
4701            boolean doOomAdj = doLowMem;
4702            if (!app.killedByAm) {
4703                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4704                        + ") has died");
4705                mAllowLowerMemLevel = true;
4706            } else {
4707                // Note that we always want to do oom adj to update our state with the
4708                // new number of procs.
4709                mAllowLowerMemLevel = false;
4710                doLowMem = false;
4711            }
4712            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4713            if (DEBUG_CLEANUP) Slog.v(
4714                TAG, "Dying app: " + app + ", pid: " + pid
4715                + ", thread: " + thread.asBinder());
4716            handleAppDiedLocked(app, false, true);
4717
4718            if (doOomAdj) {
4719                updateOomAdjLocked();
4720            }
4721            if (doLowMem) {
4722                doLowMemReportIfNeededLocked(app);
4723            }
4724        } else if (app.pid != pid) {
4725            // A new process has already been started.
4726            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4727                    + ") has died and restarted (pid " + app.pid + ").");
4728            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4729        } else if (DEBUG_PROCESSES) {
4730            Slog.d(TAG, "Received spurious death notification for thread "
4731                    + thread.asBinder());
4732        }
4733    }
4734
4735    /**
4736     * If a stack trace dump file is configured, dump process stack traces.
4737     * @param clearTraces causes the dump file to be erased prior to the new
4738     *    traces being written, if true; when false, the new traces will be
4739     *    appended to any existing file content.
4740     * @param firstPids of dalvik VM processes to dump stack traces for first
4741     * @param lastPids of dalvik VM processes to dump stack traces for last
4742     * @param nativeProcs optional list of native process names to dump stack crawls
4743     * @return file containing stack traces, or null if no dump file is configured
4744     */
4745    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4746            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4747        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4748        if (tracesPath == null || tracesPath.length() == 0) {
4749            return null;
4750        }
4751
4752        File tracesFile = new File(tracesPath);
4753        try {
4754            File tracesDir = tracesFile.getParentFile();
4755            if (!tracesDir.exists()) {
4756                tracesDir.mkdirs();
4757                if (!SELinux.restorecon(tracesDir)) {
4758                    return null;
4759                }
4760            }
4761            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4762
4763            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4764            tracesFile.createNewFile();
4765            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4766        } catch (IOException e) {
4767            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4768            return null;
4769        }
4770
4771        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4772        return tracesFile;
4773    }
4774
4775    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4776            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4777        // Use a FileObserver to detect when traces finish writing.
4778        // The order of traces is considered important to maintain for legibility.
4779        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4780            @Override
4781            public synchronized void onEvent(int event, String path) { notify(); }
4782        };
4783
4784        try {
4785            observer.startWatching();
4786
4787            // First collect all of the stacks of the most important pids.
4788            if (firstPids != null) {
4789                try {
4790                    int num = firstPids.size();
4791                    for (int i = 0; i < num; i++) {
4792                        synchronized (observer) {
4793                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4794                            observer.wait(200);  // Wait for write-close, give up after 200msec
4795                        }
4796                    }
4797                } catch (InterruptedException e) {
4798                    Slog.wtf(TAG, e);
4799                }
4800            }
4801
4802            // Next collect the stacks of the native pids
4803            if (nativeProcs != null) {
4804                int[] pids = Process.getPidsForCommands(nativeProcs);
4805                if (pids != null) {
4806                    for (int pid : pids) {
4807                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4808                    }
4809                }
4810            }
4811
4812            // Lastly, measure CPU usage.
4813            if (processCpuTracker != null) {
4814                processCpuTracker.init();
4815                System.gc();
4816                processCpuTracker.update();
4817                try {
4818                    synchronized (processCpuTracker) {
4819                        processCpuTracker.wait(500); // measure over 1/2 second.
4820                    }
4821                } catch (InterruptedException e) {
4822                }
4823                processCpuTracker.update();
4824
4825                // We'll take the stack crawls of just the top apps using CPU.
4826                final int N = processCpuTracker.countWorkingStats();
4827                int numProcs = 0;
4828                for (int i=0; i<N && numProcs<5; i++) {
4829                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4830                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4831                        numProcs++;
4832                        try {
4833                            synchronized (observer) {
4834                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4835                                observer.wait(200);  // Wait for write-close, give up after 200msec
4836                            }
4837                        } catch (InterruptedException e) {
4838                            Slog.wtf(TAG, e);
4839                        }
4840
4841                    }
4842                }
4843            }
4844        } finally {
4845            observer.stopWatching();
4846        }
4847    }
4848
4849    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4850        if (true || IS_USER_BUILD) {
4851            return;
4852        }
4853        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4854        if (tracesPath == null || tracesPath.length() == 0) {
4855            return;
4856        }
4857
4858        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4859        StrictMode.allowThreadDiskWrites();
4860        try {
4861            final File tracesFile = new File(tracesPath);
4862            final File tracesDir = tracesFile.getParentFile();
4863            final File tracesTmp = new File(tracesDir, "__tmp__");
4864            try {
4865                if (!tracesDir.exists()) {
4866                    tracesDir.mkdirs();
4867                    if (!SELinux.restorecon(tracesDir.getPath())) {
4868                        return;
4869                    }
4870                }
4871                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4872
4873                if (tracesFile.exists()) {
4874                    tracesTmp.delete();
4875                    tracesFile.renameTo(tracesTmp);
4876                }
4877                StringBuilder sb = new StringBuilder();
4878                Time tobj = new Time();
4879                tobj.set(System.currentTimeMillis());
4880                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4881                sb.append(": ");
4882                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4883                sb.append(" since ");
4884                sb.append(msg);
4885                FileOutputStream fos = new FileOutputStream(tracesFile);
4886                fos.write(sb.toString().getBytes());
4887                if (app == null) {
4888                    fos.write("\n*** No application process!".getBytes());
4889                }
4890                fos.close();
4891                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4892            } catch (IOException e) {
4893                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4894                return;
4895            }
4896
4897            if (app != null) {
4898                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4899                firstPids.add(app.pid);
4900                dumpStackTraces(tracesPath, firstPids, null, null, null);
4901            }
4902
4903            File lastTracesFile = null;
4904            File curTracesFile = null;
4905            for (int i=9; i>=0; i--) {
4906                String name = String.format(Locale.US, "slow%02d.txt", i);
4907                curTracesFile = new File(tracesDir, name);
4908                if (curTracesFile.exists()) {
4909                    if (lastTracesFile != null) {
4910                        curTracesFile.renameTo(lastTracesFile);
4911                    } else {
4912                        curTracesFile.delete();
4913                    }
4914                }
4915                lastTracesFile = curTracesFile;
4916            }
4917            tracesFile.renameTo(curTracesFile);
4918            if (tracesTmp.exists()) {
4919                tracesTmp.renameTo(tracesFile);
4920            }
4921        } finally {
4922            StrictMode.setThreadPolicy(oldPolicy);
4923        }
4924    }
4925
4926    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4927            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4928        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4929        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4930
4931        if (mController != null) {
4932            try {
4933                // 0 == continue, -1 = kill process immediately
4934                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4935                if (res < 0 && app.pid != MY_PID) {
4936                    app.kill("anr", true);
4937                }
4938            } catch (RemoteException e) {
4939                mController = null;
4940                Watchdog.getInstance().setActivityController(null);
4941            }
4942        }
4943
4944        long anrTime = SystemClock.uptimeMillis();
4945        if (MONITOR_CPU_USAGE) {
4946            updateCpuStatsNow();
4947        }
4948
4949        synchronized (this) {
4950            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4951            if (mShuttingDown) {
4952                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4953                return;
4954            } else if (app.notResponding) {
4955                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4956                return;
4957            } else if (app.crashing) {
4958                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4959                return;
4960            }
4961
4962            // In case we come through here for the same app before completing
4963            // this one, mark as anring now so we will bail out.
4964            app.notResponding = true;
4965
4966            // Log the ANR to the event log.
4967            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4968                    app.processName, app.info.flags, annotation);
4969
4970            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4971            firstPids.add(app.pid);
4972
4973            int parentPid = app.pid;
4974            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4975            if (parentPid != app.pid) firstPids.add(parentPid);
4976
4977            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4978
4979            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4980                ProcessRecord r = mLruProcesses.get(i);
4981                if (r != null && r.thread != null) {
4982                    int pid = r.pid;
4983                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4984                        if (r.persistent) {
4985                            firstPids.add(pid);
4986                        } else {
4987                            lastPids.put(pid, Boolean.TRUE);
4988                        }
4989                    }
4990                }
4991            }
4992        }
4993
4994        // Log the ANR to the main log.
4995        StringBuilder info = new StringBuilder();
4996        info.setLength(0);
4997        info.append("ANR in ").append(app.processName);
4998        if (activity != null && activity.shortComponentName != null) {
4999            info.append(" (").append(activity.shortComponentName).append(")");
5000        }
5001        info.append("\n");
5002        info.append("PID: ").append(app.pid).append("\n");
5003        if (annotation != null) {
5004            info.append("Reason: ").append(annotation).append("\n");
5005        }
5006        if (parent != null && parent != activity) {
5007            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5008        }
5009
5010        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5011
5012        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5013                NATIVE_STACKS_OF_INTEREST);
5014
5015        String cpuInfo = null;
5016        if (MONITOR_CPU_USAGE) {
5017            updateCpuStatsNow();
5018            synchronized (mProcessCpuTracker) {
5019                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5020            }
5021            info.append(processCpuTracker.printCurrentLoad());
5022            info.append(cpuInfo);
5023        }
5024
5025        info.append(processCpuTracker.printCurrentState(anrTime));
5026
5027        Slog.e(TAG, info.toString());
5028        if (tracesFile == null) {
5029            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5030            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5031        }
5032
5033        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5034                cpuInfo, tracesFile, null);
5035
5036        if (mController != null) {
5037            try {
5038                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5039                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5040                if (res != 0) {
5041                    if (res < 0 && app.pid != MY_PID) {
5042                        app.kill("anr", true);
5043                    } else {
5044                        synchronized (this) {
5045                            mServices.scheduleServiceTimeoutLocked(app);
5046                        }
5047                    }
5048                    return;
5049                }
5050            } catch (RemoteException e) {
5051                mController = null;
5052                Watchdog.getInstance().setActivityController(null);
5053            }
5054        }
5055
5056        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5057        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5058                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5059
5060        synchronized (this) {
5061            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5062                app.kill("bg anr", true);
5063                return;
5064            }
5065
5066            // Set the app's notResponding state, and look up the errorReportReceiver
5067            makeAppNotRespondingLocked(app,
5068                    activity != null ? activity.shortComponentName : null,
5069                    annotation != null ? "ANR " + annotation : "ANR",
5070                    info.toString());
5071
5072            // Bring up the infamous App Not Responding dialog
5073            Message msg = Message.obtain();
5074            HashMap<String, Object> map = new HashMap<String, Object>();
5075            msg.what = SHOW_NOT_RESPONDING_MSG;
5076            msg.obj = map;
5077            msg.arg1 = aboveSystem ? 1 : 0;
5078            map.put("app", app);
5079            if (activity != null) {
5080                map.put("activity", activity);
5081            }
5082
5083            mHandler.sendMessage(msg);
5084        }
5085    }
5086
5087    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5088        if (!mLaunchWarningShown) {
5089            mLaunchWarningShown = true;
5090            mHandler.post(new Runnable() {
5091                @Override
5092                public void run() {
5093                    synchronized (ActivityManagerService.this) {
5094                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5095                        d.show();
5096                        mHandler.postDelayed(new Runnable() {
5097                            @Override
5098                            public void run() {
5099                                synchronized (ActivityManagerService.this) {
5100                                    d.dismiss();
5101                                    mLaunchWarningShown = false;
5102                                }
5103                            }
5104                        }, 4000);
5105                    }
5106                }
5107            });
5108        }
5109    }
5110
5111    @Override
5112    public boolean clearApplicationUserData(final String packageName,
5113            final IPackageDataObserver observer, int userId) {
5114        enforceNotIsolatedCaller("clearApplicationUserData");
5115        int uid = Binder.getCallingUid();
5116        int pid = Binder.getCallingPid();
5117        userId = handleIncomingUser(pid, uid,
5118                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5119        long callingId = Binder.clearCallingIdentity();
5120        try {
5121            IPackageManager pm = AppGlobals.getPackageManager();
5122            int pkgUid = -1;
5123            synchronized(this) {
5124                try {
5125                    pkgUid = pm.getPackageUid(packageName, userId);
5126                } catch (RemoteException e) {
5127                }
5128                if (pkgUid == -1) {
5129                    Slog.w(TAG, "Invalid packageName: " + packageName);
5130                    if (observer != null) {
5131                        try {
5132                            observer.onRemoveCompleted(packageName, false);
5133                        } catch (RemoteException e) {
5134                            Slog.i(TAG, "Observer no longer exists.");
5135                        }
5136                    }
5137                    return false;
5138                }
5139                if (uid == pkgUid || checkComponentPermission(
5140                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5141                        pid, uid, -1, true)
5142                        == PackageManager.PERMISSION_GRANTED) {
5143                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5144                } else {
5145                    throw new SecurityException("PID " + pid + " does not have permission "
5146                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5147                                    + " of package " + packageName);
5148                }
5149
5150                // Remove all tasks match the cleared application package and user
5151                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5152                    final TaskRecord tr = mRecentTasks.get(i);
5153                    final String taskPackageName =
5154                            tr.getBaseIntent().getComponent().getPackageName();
5155                    if (tr.userId != userId) continue;
5156                    if (!taskPackageName.equals(packageName)) continue;
5157                    removeTaskByIdLocked(tr.taskId, false);
5158                }
5159            }
5160
5161            try {
5162                // Clear application user data
5163                pm.clearApplicationUserData(packageName, observer, userId);
5164
5165                synchronized(this) {
5166                    // Remove all permissions granted from/to this package
5167                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5168                }
5169
5170                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5171                        Uri.fromParts("package", packageName, null));
5172                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5173                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5174                        null, null, 0, null, null, null, false, false, userId);
5175            } catch (RemoteException e) {
5176            }
5177        } finally {
5178            Binder.restoreCallingIdentity(callingId);
5179        }
5180        return true;
5181    }
5182
5183    @Override
5184    public void killBackgroundProcesses(final String packageName, int userId) {
5185        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5186                != PackageManager.PERMISSION_GRANTED &&
5187                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5188                        != PackageManager.PERMISSION_GRANTED) {
5189            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5190                    + Binder.getCallingPid()
5191                    + ", uid=" + Binder.getCallingUid()
5192                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5193            Slog.w(TAG, msg);
5194            throw new SecurityException(msg);
5195        }
5196
5197        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5198                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5199        long callingId = Binder.clearCallingIdentity();
5200        try {
5201            IPackageManager pm = AppGlobals.getPackageManager();
5202            synchronized(this) {
5203                int appId = -1;
5204                try {
5205                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5206                } catch (RemoteException e) {
5207                }
5208                if (appId == -1) {
5209                    Slog.w(TAG, "Invalid packageName: " + packageName);
5210                    return;
5211                }
5212                killPackageProcessesLocked(packageName, appId, userId,
5213                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5214            }
5215        } finally {
5216            Binder.restoreCallingIdentity(callingId);
5217        }
5218    }
5219
5220    @Override
5221    public void killAllBackgroundProcesses() {
5222        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5223                != PackageManager.PERMISSION_GRANTED) {
5224            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5225                    + Binder.getCallingPid()
5226                    + ", uid=" + Binder.getCallingUid()
5227                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5228            Slog.w(TAG, msg);
5229            throw new SecurityException(msg);
5230        }
5231
5232        long callingId = Binder.clearCallingIdentity();
5233        try {
5234            synchronized(this) {
5235                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5236                final int NP = mProcessNames.getMap().size();
5237                for (int ip=0; ip<NP; ip++) {
5238                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5239                    final int NA = apps.size();
5240                    for (int ia=0; ia<NA; ia++) {
5241                        ProcessRecord app = apps.valueAt(ia);
5242                        if (app.persistent) {
5243                            // we don't kill persistent processes
5244                            continue;
5245                        }
5246                        if (app.removed) {
5247                            procs.add(app);
5248                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5249                            app.removed = true;
5250                            procs.add(app);
5251                        }
5252                    }
5253                }
5254
5255                int N = procs.size();
5256                for (int i=0; i<N; i++) {
5257                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5258                }
5259                mAllowLowerMemLevel = true;
5260                updateOomAdjLocked();
5261                doLowMemReportIfNeededLocked(null);
5262            }
5263        } finally {
5264            Binder.restoreCallingIdentity(callingId);
5265        }
5266    }
5267
5268    @Override
5269    public void forceStopPackage(final String packageName, int userId) {
5270        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5271                != PackageManager.PERMISSION_GRANTED) {
5272            String msg = "Permission Denial: forceStopPackage() from pid="
5273                    + Binder.getCallingPid()
5274                    + ", uid=" + Binder.getCallingUid()
5275                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5276            Slog.w(TAG, msg);
5277            throw new SecurityException(msg);
5278        }
5279        final int callingPid = Binder.getCallingPid();
5280        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5281                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5282        long callingId = Binder.clearCallingIdentity();
5283        try {
5284            IPackageManager pm = AppGlobals.getPackageManager();
5285            synchronized(this) {
5286                int[] users = userId == UserHandle.USER_ALL
5287                        ? getUsersLocked() : new int[] { userId };
5288                for (int user : users) {
5289                    int pkgUid = -1;
5290                    try {
5291                        pkgUid = pm.getPackageUid(packageName, user);
5292                    } catch (RemoteException e) {
5293                    }
5294                    if (pkgUid == -1) {
5295                        Slog.w(TAG, "Invalid packageName: " + packageName);
5296                        continue;
5297                    }
5298                    try {
5299                        pm.setPackageStoppedState(packageName, true, user);
5300                    } catch (RemoteException e) {
5301                    } catch (IllegalArgumentException e) {
5302                        Slog.w(TAG, "Failed trying to unstop package "
5303                                + packageName + ": " + e);
5304                    }
5305                    if (isUserRunningLocked(user, false)) {
5306                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5307                    }
5308                }
5309            }
5310        } finally {
5311            Binder.restoreCallingIdentity(callingId);
5312        }
5313    }
5314
5315    @Override
5316    public void addPackageDependency(String packageName) {
5317        synchronized (this) {
5318            int callingPid = Binder.getCallingPid();
5319            if (callingPid == Process.myPid()) {
5320                //  Yeah, um, no.
5321                Slog.w(TAG, "Can't addPackageDependency on system process");
5322                return;
5323            }
5324            ProcessRecord proc;
5325            synchronized (mPidsSelfLocked) {
5326                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5327            }
5328            if (proc != null) {
5329                if (proc.pkgDeps == null) {
5330                    proc.pkgDeps = new ArraySet<String>(1);
5331                }
5332                proc.pkgDeps.add(packageName);
5333            }
5334        }
5335    }
5336
5337    /*
5338     * The pkg name and app id have to be specified.
5339     */
5340    @Override
5341    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5342        if (pkg == null) {
5343            return;
5344        }
5345        // Make sure the uid is valid.
5346        if (appid < 0) {
5347            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5348            return;
5349        }
5350        int callerUid = Binder.getCallingUid();
5351        // Only the system server can kill an application
5352        if (callerUid == Process.SYSTEM_UID) {
5353            // Post an aysnc message to kill the application
5354            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5355            msg.arg1 = appid;
5356            msg.arg2 = 0;
5357            Bundle bundle = new Bundle();
5358            bundle.putString("pkg", pkg);
5359            bundle.putString("reason", reason);
5360            msg.obj = bundle;
5361            mHandler.sendMessage(msg);
5362        } else {
5363            throw new SecurityException(callerUid + " cannot kill pkg: " +
5364                    pkg);
5365        }
5366    }
5367
5368    @Override
5369    public void closeSystemDialogs(String reason) {
5370        enforceNotIsolatedCaller("closeSystemDialogs");
5371
5372        final int pid = Binder.getCallingPid();
5373        final int uid = Binder.getCallingUid();
5374        final long origId = Binder.clearCallingIdentity();
5375        try {
5376            synchronized (this) {
5377                // Only allow this from foreground processes, so that background
5378                // applications can't abuse it to prevent system UI from being shown.
5379                if (uid >= Process.FIRST_APPLICATION_UID) {
5380                    ProcessRecord proc;
5381                    synchronized (mPidsSelfLocked) {
5382                        proc = mPidsSelfLocked.get(pid);
5383                    }
5384                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5385                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5386                                + " from background process " + proc);
5387                        return;
5388                    }
5389                }
5390                closeSystemDialogsLocked(reason);
5391            }
5392        } finally {
5393            Binder.restoreCallingIdentity(origId);
5394        }
5395    }
5396
5397    void closeSystemDialogsLocked(String reason) {
5398        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5399        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5400                | Intent.FLAG_RECEIVER_FOREGROUND);
5401        if (reason != null) {
5402            intent.putExtra("reason", reason);
5403        }
5404        mWindowManager.closeSystemDialogs(reason);
5405
5406        mStackSupervisor.closeSystemDialogsLocked();
5407
5408        broadcastIntentLocked(null, null, intent, null,
5409                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5410                Process.SYSTEM_UID, UserHandle.USER_ALL);
5411    }
5412
5413    @Override
5414    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5415        enforceNotIsolatedCaller("getProcessMemoryInfo");
5416        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5417        for (int i=pids.length-1; i>=0; i--) {
5418            ProcessRecord proc;
5419            int oomAdj;
5420            synchronized (this) {
5421                synchronized (mPidsSelfLocked) {
5422                    proc = mPidsSelfLocked.get(pids[i]);
5423                    oomAdj = proc != null ? proc.setAdj : 0;
5424                }
5425            }
5426            infos[i] = new Debug.MemoryInfo();
5427            Debug.getMemoryInfo(pids[i], infos[i]);
5428            if (proc != null) {
5429                synchronized (this) {
5430                    if (proc.thread != null && proc.setAdj == oomAdj) {
5431                        // Record this for posterity if the process has been stable.
5432                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5433                                infos[i].getTotalUss(), false, proc.pkgList);
5434                    }
5435                }
5436            }
5437        }
5438        return infos;
5439    }
5440
5441    @Override
5442    public long[] getProcessPss(int[] pids) {
5443        enforceNotIsolatedCaller("getProcessPss");
5444        long[] pss = new long[pids.length];
5445        for (int i=pids.length-1; i>=0; i--) {
5446            ProcessRecord proc;
5447            int oomAdj;
5448            synchronized (this) {
5449                synchronized (mPidsSelfLocked) {
5450                    proc = mPidsSelfLocked.get(pids[i]);
5451                    oomAdj = proc != null ? proc.setAdj : 0;
5452                }
5453            }
5454            long[] tmpUss = new long[1];
5455            pss[i] = Debug.getPss(pids[i], tmpUss);
5456            if (proc != null) {
5457                synchronized (this) {
5458                    if (proc.thread != null && proc.setAdj == oomAdj) {
5459                        // Record this for posterity if the process has been stable.
5460                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5461                    }
5462                }
5463            }
5464        }
5465        return pss;
5466    }
5467
5468    @Override
5469    public void killApplicationProcess(String processName, int uid) {
5470        if (processName == null) {
5471            return;
5472        }
5473
5474        int callerUid = Binder.getCallingUid();
5475        // Only the system server can kill an application
5476        if (callerUid == Process.SYSTEM_UID) {
5477            synchronized (this) {
5478                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5479                if (app != null && app.thread != null) {
5480                    try {
5481                        app.thread.scheduleSuicide();
5482                    } catch (RemoteException e) {
5483                        // If the other end already died, then our work here is done.
5484                    }
5485                } else {
5486                    Slog.w(TAG, "Process/uid not found attempting kill of "
5487                            + processName + " / " + uid);
5488                }
5489            }
5490        } else {
5491            throw new SecurityException(callerUid + " cannot kill app process: " +
5492                    processName);
5493        }
5494    }
5495
5496    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5497        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5498                false, true, false, false, UserHandle.getUserId(uid), reason);
5499        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5500                Uri.fromParts("package", packageName, null));
5501        if (!mProcessesReady) {
5502            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5503                    | Intent.FLAG_RECEIVER_FOREGROUND);
5504        }
5505        intent.putExtra(Intent.EXTRA_UID, uid);
5506        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5507        broadcastIntentLocked(null, null, intent,
5508                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5509                false, false,
5510                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5511    }
5512
5513    private void forceStopUserLocked(int userId, String reason) {
5514        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5515        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5516        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5517                | Intent.FLAG_RECEIVER_FOREGROUND);
5518        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5519        broadcastIntentLocked(null, null, intent,
5520                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5521                false, false,
5522                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5523    }
5524
5525    private final boolean killPackageProcessesLocked(String packageName, int appId,
5526            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5527            boolean doit, boolean evenPersistent, String reason) {
5528        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5529
5530        // Remove all processes this package may have touched: all with the
5531        // same UID (except for the system or root user), and all whose name
5532        // matches the package name.
5533        final int NP = mProcessNames.getMap().size();
5534        for (int ip=0; ip<NP; ip++) {
5535            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5536            final int NA = apps.size();
5537            for (int ia=0; ia<NA; ia++) {
5538                ProcessRecord app = apps.valueAt(ia);
5539                if (app.persistent && !evenPersistent) {
5540                    // we don't kill persistent processes
5541                    continue;
5542                }
5543                if (app.removed) {
5544                    if (doit) {
5545                        procs.add(app);
5546                    }
5547                    continue;
5548                }
5549
5550                // Skip process if it doesn't meet our oom adj requirement.
5551                if (app.setAdj < minOomAdj) {
5552                    continue;
5553                }
5554
5555                // If no package is specified, we call all processes under the
5556                // give user id.
5557                if (packageName == null) {
5558                    if (app.userId != userId) {
5559                        continue;
5560                    }
5561                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5562                        continue;
5563                    }
5564                // Package has been specified, we want to hit all processes
5565                // that match it.  We need to qualify this by the processes
5566                // that are running under the specified app and user ID.
5567                } else {
5568                    final boolean isDep = app.pkgDeps != null
5569                            && app.pkgDeps.contains(packageName);
5570                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5571                        continue;
5572                    }
5573                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5574                        continue;
5575                    }
5576                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5577                        continue;
5578                    }
5579                }
5580
5581                // Process has passed all conditions, kill it!
5582                if (!doit) {
5583                    return true;
5584                }
5585                app.removed = true;
5586                procs.add(app);
5587            }
5588        }
5589
5590        int N = procs.size();
5591        for (int i=0; i<N; i++) {
5592            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5593        }
5594        updateOomAdjLocked();
5595        return N > 0;
5596    }
5597
5598    private final boolean forceStopPackageLocked(String name, int appId,
5599            boolean callerWillRestart, boolean purgeCache, boolean doit,
5600            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5601        int i;
5602        int N;
5603
5604        if (userId == UserHandle.USER_ALL && name == null) {
5605            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5606        }
5607
5608        if (appId < 0 && name != null) {
5609            try {
5610                appId = UserHandle.getAppId(
5611                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5612            } catch (RemoteException e) {
5613            }
5614        }
5615
5616        if (doit) {
5617            if (name != null) {
5618                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5619                        + " user=" + userId + ": " + reason);
5620            } else {
5621                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5622            }
5623
5624            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5625            for (int ip=pmap.size()-1; ip>=0; ip--) {
5626                SparseArray<Long> ba = pmap.valueAt(ip);
5627                for (i=ba.size()-1; i>=0; i--) {
5628                    boolean remove = false;
5629                    final int entUid = ba.keyAt(i);
5630                    if (name != null) {
5631                        if (userId == UserHandle.USER_ALL) {
5632                            if (UserHandle.getAppId(entUid) == appId) {
5633                                remove = true;
5634                            }
5635                        } else {
5636                            if (entUid == UserHandle.getUid(userId, appId)) {
5637                                remove = true;
5638                            }
5639                        }
5640                    } else if (UserHandle.getUserId(entUid) == userId) {
5641                        remove = true;
5642                    }
5643                    if (remove) {
5644                        ba.removeAt(i);
5645                    }
5646                }
5647                if (ba.size() == 0) {
5648                    pmap.removeAt(ip);
5649                }
5650            }
5651        }
5652
5653        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5654                -100, callerWillRestart, true, doit, evenPersistent,
5655                name == null ? ("stop user " + userId) : ("stop " + name));
5656
5657        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5658            if (!doit) {
5659                return true;
5660            }
5661            didSomething = true;
5662        }
5663
5664        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5665            if (!doit) {
5666                return true;
5667            }
5668            didSomething = true;
5669        }
5670
5671        if (name == null) {
5672            // Remove all sticky broadcasts from this user.
5673            mStickyBroadcasts.remove(userId);
5674        }
5675
5676        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5677        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5678                userId, providers)) {
5679            if (!doit) {
5680                return true;
5681            }
5682            didSomething = true;
5683        }
5684        N = providers.size();
5685        for (i=0; i<N; i++) {
5686            removeDyingProviderLocked(null, providers.get(i), true);
5687        }
5688
5689        // Remove transient permissions granted from/to this package/user
5690        removeUriPermissionsForPackageLocked(name, userId, false);
5691
5692        if (name == null || uninstalling) {
5693            // Remove pending intents.  For now we only do this when force
5694            // stopping users, because we have some problems when doing this
5695            // for packages -- app widgets are not currently cleaned up for
5696            // such packages, so they can be left with bad pending intents.
5697            if (mIntentSenderRecords.size() > 0) {
5698                Iterator<WeakReference<PendingIntentRecord>> it
5699                        = mIntentSenderRecords.values().iterator();
5700                while (it.hasNext()) {
5701                    WeakReference<PendingIntentRecord> wpir = it.next();
5702                    if (wpir == null) {
5703                        it.remove();
5704                        continue;
5705                    }
5706                    PendingIntentRecord pir = wpir.get();
5707                    if (pir == null) {
5708                        it.remove();
5709                        continue;
5710                    }
5711                    if (name == null) {
5712                        // Stopping user, remove all objects for the user.
5713                        if (pir.key.userId != userId) {
5714                            // Not the same user, skip it.
5715                            continue;
5716                        }
5717                    } else {
5718                        if (UserHandle.getAppId(pir.uid) != appId) {
5719                            // Different app id, skip it.
5720                            continue;
5721                        }
5722                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5723                            // Different user, skip it.
5724                            continue;
5725                        }
5726                        if (!pir.key.packageName.equals(name)) {
5727                            // Different package, skip it.
5728                            continue;
5729                        }
5730                    }
5731                    if (!doit) {
5732                        return true;
5733                    }
5734                    didSomething = true;
5735                    it.remove();
5736                    pir.canceled = true;
5737                    if (pir.key.activity != null) {
5738                        pir.key.activity.pendingResults.remove(pir.ref);
5739                    }
5740                }
5741            }
5742        }
5743
5744        if (doit) {
5745            if (purgeCache && name != null) {
5746                AttributeCache ac = AttributeCache.instance();
5747                if (ac != null) {
5748                    ac.removePackage(name);
5749                }
5750            }
5751            if (mBooted) {
5752                mStackSupervisor.resumeTopActivitiesLocked();
5753                mStackSupervisor.scheduleIdleLocked();
5754            }
5755        }
5756
5757        return didSomething;
5758    }
5759
5760    private final boolean removeProcessLocked(ProcessRecord app,
5761            boolean callerWillRestart, boolean allowRestart, String reason) {
5762        final String name = app.processName;
5763        final int uid = app.uid;
5764        if (DEBUG_PROCESSES) Slog.d(
5765            TAG, "Force removing proc " + app.toShortString() + " (" + name
5766            + "/" + uid + ")");
5767
5768        mProcessNames.remove(name, uid);
5769        mIsolatedProcesses.remove(app.uid);
5770        if (mHeavyWeightProcess == app) {
5771            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5772                    mHeavyWeightProcess.userId, 0));
5773            mHeavyWeightProcess = null;
5774        }
5775        boolean needRestart = false;
5776        if (app.pid > 0 && app.pid != MY_PID) {
5777            int pid = app.pid;
5778            synchronized (mPidsSelfLocked) {
5779                mPidsSelfLocked.remove(pid);
5780                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5781            }
5782            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5783            if (app.isolated) {
5784                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5785            }
5786            app.kill(reason, true);
5787            handleAppDiedLocked(app, true, allowRestart);
5788            removeLruProcessLocked(app);
5789
5790            if (app.persistent && !app.isolated) {
5791                if (!callerWillRestart) {
5792                    addAppLocked(app.info, false, null /* ABI override */);
5793                } else {
5794                    needRestart = true;
5795                }
5796            }
5797        } else {
5798            mRemovedProcesses.add(app);
5799        }
5800
5801        return needRestart;
5802    }
5803
5804    private final void processStartTimedOutLocked(ProcessRecord app) {
5805        final int pid = app.pid;
5806        boolean gone = false;
5807        synchronized (mPidsSelfLocked) {
5808            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5809            if (knownApp != null && knownApp.thread == null) {
5810                mPidsSelfLocked.remove(pid);
5811                gone = true;
5812            }
5813        }
5814
5815        if (gone) {
5816            Slog.w(TAG, "Process " + app + " failed to attach");
5817            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5818                    pid, app.uid, app.processName);
5819            mProcessNames.remove(app.processName, app.uid);
5820            mIsolatedProcesses.remove(app.uid);
5821            if (mHeavyWeightProcess == app) {
5822                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5823                        mHeavyWeightProcess.userId, 0));
5824                mHeavyWeightProcess = null;
5825            }
5826            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5827            if (app.isolated) {
5828                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5829            }
5830            // Take care of any launching providers waiting for this process.
5831            checkAppInLaunchingProvidersLocked(app, true);
5832            // Take care of any services that are waiting for the process.
5833            mServices.processStartTimedOutLocked(app);
5834            app.kill("start timeout", true);
5835            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5836                Slog.w(TAG, "Unattached app died before backup, skipping");
5837                try {
5838                    IBackupManager bm = IBackupManager.Stub.asInterface(
5839                            ServiceManager.getService(Context.BACKUP_SERVICE));
5840                    bm.agentDisconnected(app.info.packageName);
5841                } catch (RemoteException e) {
5842                    // Can't happen; the backup manager is local
5843                }
5844            }
5845            if (isPendingBroadcastProcessLocked(pid)) {
5846                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5847                skipPendingBroadcastLocked(pid);
5848            }
5849        } else {
5850            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5851        }
5852    }
5853
5854    private final boolean attachApplicationLocked(IApplicationThread thread,
5855            int pid) {
5856
5857        // Find the application record that is being attached...  either via
5858        // the pid if we are running in multiple processes, or just pull the
5859        // next app record if we are emulating process with anonymous threads.
5860        ProcessRecord app;
5861        if (pid != MY_PID && pid >= 0) {
5862            synchronized (mPidsSelfLocked) {
5863                app = mPidsSelfLocked.get(pid);
5864            }
5865        } else {
5866            app = null;
5867        }
5868
5869        if (app == null) {
5870            Slog.w(TAG, "No pending application record for pid " + pid
5871                    + " (IApplicationThread " + thread + "); dropping process");
5872            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5873            if (pid > 0 && pid != MY_PID) {
5874                Process.killProcessQuiet(pid);
5875                //TODO: Process.killProcessGroup(app.info.uid, pid);
5876            } else {
5877                try {
5878                    thread.scheduleExit();
5879                } catch (Exception e) {
5880                    // Ignore exceptions.
5881                }
5882            }
5883            return false;
5884        }
5885
5886        // If this application record is still attached to a previous
5887        // process, clean it up now.
5888        if (app.thread != null) {
5889            handleAppDiedLocked(app, true, true);
5890        }
5891
5892        // Tell the process all about itself.
5893
5894        if (localLOGV) Slog.v(
5895                TAG, "Binding process pid " + pid + " to record " + app);
5896
5897        final String processName = app.processName;
5898        try {
5899            AppDeathRecipient adr = new AppDeathRecipient(
5900                    app, pid, thread);
5901            thread.asBinder().linkToDeath(adr, 0);
5902            app.deathRecipient = adr;
5903        } catch (RemoteException e) {
5904            app.resetPackageList(mProcessStats);
5905            startProcessLocked(app, "link fail", processName);
5906            return false;
5907        }
5908
5909        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5910
5911        app.makeActive(thread, mProcessStats);
5912        app.curAdj = app.setAdj = -100;
5913        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5914        app.forcingToForeground = null;
5915        updateProcessForegroundLocked(app, false, false);
5916        app.hasShownUi = false;
5917        app.debugging = false;
5918        app.cached = false;
5919
5920        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5921
5922        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5923        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5924
5925        if (!normalMode) {
5926            Slog.i(TAG, "Launching preboot mode app: " + app);
5927        }
5928
5929        if (localLOGV) Slog.v(
5930            TAG, "New app record " + app
5931            + " thread=" + thread.asBinder() + " pid=" + pid);
5932        try {
5933            int testMode = IApplicationThread.DEBUG_OFF;
5934            if (mDebugApp != null && mDebugApp.equals(processName)) {
5935                testMode = mWaitForDebugger
5936                    ? IApplicationThread.DEBUG_WAIT
5937                    : IApplicationThread.DEBUG_ON;
5938                app.debugging = true;
5939                if (mDebugTransient) {
5940                    mDebugApp = mOrigDebugApp;
5941                    mWaitForDebugger = mOrigWaitForDebugger;
5942                }
5943            }
5944            String profileFile = app.instrumentationProfileFile;
5945            ParcelFileDescriptor profileFd = null;
5946            int samplingInterval = 0;
5947            boolean profileAutoStop = false;
5948            if (mProfileApp != null && mProfileApp.equals(processName)) {
5949                mProfileProc = app;
5950                profileFile = mProfileFile;
5951                profileFd = mProfileFd;
5952                samplingInterval = mSamplingInterval;
5953                profileAutoStop = mAutoStopProfiler;
5954            }
5955            boolean enableOpenGlTrace = false;
5956            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5957                enableOpenGlTrace = true;
5958                mOpenGlTraceApp = null;
5959            }
5960
5961            // If the app is being launched for restore or full backup, set it up specially
5962            boolean isRestrictedBackupMode = false;
5963            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5964                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5965                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5966                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5967            }
5968
5969            ensurePackageDexOpt(app.instrumentationInfo != null
5970                    ? app.instrumentationInfo.packageName
5971                    : app.info.packageName);
5972            if (app.instrumentationClass != null) {
5973                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5974            }
5975            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5976                    + processName + " with config " + mConfiguration);
5977            ApplicationInfo appInfo = app.instrumentationInfo != null
5978                    ? app.instrumentationInfo : app.info;
5979            app.compat = compatibilityInfoForPackageLocked(appInfo);
5980            if (profileFd != null) {
5981                profileFd = profileFd.dup();
5982            }
5983            ProfilerInfo profilerInfo = profileFile == null ? null
5984                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5985            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5986                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5987                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5988                    isRestrictedBackupMode || !normalMode, app.persistent,
5989                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5990                    mCoreSettingsObserver.getCoreSettingsLocked());
5991            updateLruProcessLocked(app, false, null);
5992            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5993        } catch (Exception e) {
5994            // todo: Yikes!  What should we do?  For now we will try to
5995            // start another process, but that could easily get us in
5996            // an infinite loop of restarting processes...
5997            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5998
5999            app.resetPackageList(mProcessStats);
6000            app.unlinkDeathRecipient();
6001            startProcessLocked(app, "bind fail", processName);
6002            return false;
6003        }
6004
6005        // Remove this record from the list of starting applications.
6006        mPersistentStartingProcesses.remove(app);
6007        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6008                "Attach application locked removing on hold: " + app);
6009        mProcessesOnHold.remove(app);
6010
6011        boolean badApp = false;
6012        boolean didSomething = false;
6013
6014        // See if the top visible activity is waiting to run in this process...
6015        if (normalMode) {
6016            try {
6017                if (mStackSupervisor.attachApplicationLocked(app)) {
6018                    didSomething = true;
6019                }
6020            } catch (Exception e) {
6021                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6022                badApp = true;
6023            }
6024        }
6025
6026        // Find any services that should be running in this process...
6027        if (!badApp) {
6028            try {
6029                didSomething |= mServices.attachApplicationLocked(app, processName);
6030            } catch (Exception e) {
6031                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6032                badApp = true;
6033            }
6034        }
6035
6036        // Check if a next-broadcast receiver is in this process...
6037        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6038            try {
6039                didSomething |= sendPendingBroadcastsLocked(app);
6040            } catch (Exception e) {
6041                // If the app died trying to launch the receiver we declare it 'bad'
6042                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6043                badApp = true;
6044            }
6045        }
6046
6047        // Check whether the next backup agent is in this process...
6048        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6049            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6050            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6051            try {
6052                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6053                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6054                        mBackupTarget.backupMode);
6055            } catch (Exception e) {
6056                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6057                badApp = true;
6058            }
6059        }
6060
6061        if (badApp) {
6062            app.kill("error during init", true);
6063            handleAppDiedLocked(app, false, true);
6064            return false;
6065        }
6066
6067        if (!didSomething) {
6068            updateOomAdjLocked();
6069        }
6070
6071        return true;
6072    }
6073
6074    @Override
6075    public final void attachApplication(IApplicationThread thread) {
6076        synchronized (this) {
6077            int callingPid = Binder.getCallingPid();
6078            final long origId = Binder.clearCallingIdentity();
6079            attachApplicationLocked(thread, callingPid);
6080            Binder.restoreCallingIdentity(origId);
6081        }
6082    }
6083
6084    @Override
6085    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6086        final long origId = Binder.clearCallingIdentity();
6087        synchronized (this) {
6088            ActivityStack stack = ActivityRecord.getStackLocked(token);
6089            if (stack != null) {
6090                ActivityRecord r =
6091                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6092                if (stopProfiling) {
6093                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6094                        try {
6095                            mProfileFd.close();
6096                        } catch (IOException e) {
6097                        }
6098                        clearProfilerLocked();
6099                    }
6100                }
6101            }
6102        }
6103        Binder.restoreCallingIdentity(origId);
6104    }
6105
6106    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6107        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6108                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6109    }
6110
6111    void enableScreenAfterBoot() {
6112        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6113                SystemClock.uptimeMillis());
6114        mWindowManager.enableScreenAfterBoot();
6115
6116        synchronized (this) {
6117            updateEventDispatchingLocked();
6118        }
6119    }
6120
6121    @Override
6122    public void showBootMessage(final CharSequence msg, final boolean always) {
6123        enforceNotIsolatedCaller("showBootMessage");
6124        mWindowManager.showBootMessage(msg, always);
6125    }
6126
6127    @Override
6128    public void keyguardWaitingForActivityDrawn() {
6129        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6130        final long token = Binder.clearCallingIdentity();
6131        try {
6132            synchronized (this) {
6133                if (DEBUG_LOCKSCREEN) logLockScreen("");
6134                mWindowManager.keyguardWaitingForActivityDrawn();
6135                if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6136                    mLockScreenShown = LOCK_SCREEN_LEAVING;
6137                }
6138            }
6139        } finally {
6140            Binder.restoreCallingIdentity(token);
6141        }
6142    }
6143
6144    final void finishBooting() {
6145        synchronized (this) {
6146            if (!mBootAnimationComplete) {
6147                mCallFinishBooting = true;
6148                return;
6149            }
6150            mCallFinishBooting = false;
6151        }
6152
6153        // Register receivers to handle package update events
6154        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6155
6156        // Let system services know.
6157        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6158
6159        synchronized (this) {
6160            // Ensure that any processes we had put on hold are now started
6161            // up.
6162            final int NP = mProcessesOnHold.size();
6163            if (NP > 0) {
6164                ArrayList<ProcessRecord> procs =
6165                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6166                for (int ip=0; ip<NP; ip++) {
6167                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6168                            + procs.get(ip));
6169                    startProcessLocked(procs.get(ip), "on-hold", null);
6170                }
6171            }
6172
6173            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6174                // Start looking for apps that are abusing wake locks.
6175                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6176                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6177                // Tell anyone interested that we are done booting!
6178                SystemProperties.set("sys.boot_completed", "1");
6179
6180                // And trigger dev.bootcomplete if we are not showing encryption progress
6181                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6182                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6183                    SystemProperties.set("dev.bootcomplete", "1");
6184                }
6185                for (int i=0; i<mStartedUsers.size(); i++) {
6186                    UserStartedState uss = mStartedUsers.valueAt(i);
6187                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6188                        uss.mState = UserStartedState.STATE_RUNNING;
6189                        final int userId = mStartedUsers.keyAt(i);
6190                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6191                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6192                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6193                        broadcastIntentLocked(null, null, intent, null,
6194                                new IIntentReceiver.Stub() {
6195                                    @Override
6196                                    public void performReceive(Intent intent, int resultCode,
6197                                            String data, Bundle extras, boolean ordered,
6198                                            boolean sticky, int sendingUser) {
6199                                        synchronized (ActivityManagerService.this) {
6200                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6201                                                    true, false);
6202                                        }
6203                                    }
6204                                },
6205                                0, null, null,
6206                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6207                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6208                                userId);
6209                    }
6210                }
6211                scheduleStartProfilesLocked();
6212            }
6213        }
6214    }
6215
6216    @Override
6217    public void bootAnimationComplete() {
6218        final boolean callFinishBooting;
6219        synchronized (this) {
6220            callFinishBooting = mCallFinishBooting;
6221            mBootAnimationComplete = true;
6222        }
6223        if (callFinishBooting) {
6224            finishBooting();
6225        }
6226    }
6227
6228    final void ensureBootCompleted() {
6229        boolean booting;
6230        boolean enableScreen;
6231        synchronized (this) {
6232            booting = mBooting;
6233            mBooting = false;
6234            enableScreen = !mBooted;
6235            mBooted = true;
6236        }
6237
6238        if (booting) {
6239            finishBooting();
6240        }
6241
6242        if (enableScreen) {
6243            enableScreenAfterBoot();
6244        }
6245    }
6246
6247    @Override
6248    public final void activityResumed(IBinder token) {
6249        final long origId = Binder.clearCallingIdentity();
6250        synchronized(this) {
6251            ActivityStack stack = ActivityRecord.getStackLocked(token);
6252            if (stack != null) {
6253                ActivityRecord.activityResumedLocked(token);
6254            }
6255        }
6256        Binder.restoreCallingIdentity(origId);
6257    }
6258
6259    @Override
6260    public final void activityPaused(IBinder token) {
6261        final long origId = Binder.clearCallingIdentity();
6262        synchronized(this) {
6263            ActivityStack stack = ActivityRecord.getStackLocked(token);
6264            if (stack != null) {
6265                stack.activityPausedLocked(token, false);
6266            }
6267        }
6268        Binder.restoreCallingIdentity(origId);
6269    }
6270
6271    @Override
6272    public final void activityStopped(IBinder token, Bundle icicle,
6273            PersistableBundle persistentState, CharSequence description) {
6274        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6275
6276        // Refuse possible leaked file descriptors
6277        if (icicle != null && icicle.hasFileDescriptors()) {
6278            throw new IllegalArgumentException("File descriptors passed in Bundle");
6279        }
6280
6281        final long origId = Binder.clearCallingIdentity();
6282
6283        synchronized (this) {
6284            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6285            if (r != null) {
6286                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6287            }
6288        }
6289
6290        trimApplications();
6291
6292        Binder.restoreCallingIdentity(origId);
6293    }
6294
6295    @Override
6296    public final void activityDestroyed(IBinder token) {
6297        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6298        synchronized (this) {
6299            ActivityStack stack = ActivityRecord.getStackLocked(token);
6300            if (stack != null) {
6301                stack.activityDestroyedLocked(token);
6302            }
6303        }
6304    }
6305
6306    @Override
6307    public final void backgroundResourcesReleased(IBinder token) {
6308        final long origId = Binder.clearCallingIdentity();
6309        try {
6310            synchronized (this) {
6311                ActivityStack stack = ActivityRecord.getStackLocked(token);
6312                if (stack != null) {
6313                    stack.backgroundResourcesReleased(token);
6314                }
6315            }
6316        } finally {
6317            Binder.restoreCallingIdentity(origId);
6318        }
6319    }
6320
6321    @Override
6322    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6323        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6324    }
6325
6326    @Override
6327    public final void notifyEnterAnimationComplete(IBinder token) {
6328        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6329    }
6330
6331    @Override
6332    public String getCallingPackage(IBinder token) {
6333        synchronized (this) {
6334            ActivityRecord r = getCallingRecordLocked(token);
6335            return r != null ? r.info.packageName : null;
6336        }
6337    }
6338
6339    @Override
6340    public ComponentName getCallingActivity(IBinder token) {
6341        synchronized (this) {
6342            ActivityRecord r = getCallingRecordLocked(token);
6343            return r != null ? r.intent.getComponent() : null;
6344        }
6345    }
6346
6347    private ActivityRecord getCallingRecordLocked(IBinder token) {
6348        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6349        if (r == null) {
6350            return null;
6351        }
6352        return r.resultTo;
6353    }
6354
6355    @Override
6356    public ComponentName getActivityClassForToken(IBinder token) {
6357        synchronized(this) {
6358            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6359            if (r == null) {
6360                return null;
6361            }
6362            return r.intent.getComponent();
6363        }
6364    }
6365
6366    @Override
6367    public String getPackageForToken(IBinder token) {
6368        synchronized(this) {
6369            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6370            if (r == null) {
6371                return null;
6372            }
6373            return r.packageName;
6374        }
6375    }
6376
6377    @Override
6378    public IIntentSender getIntentSender(int type,
6379            String packageName, IBinder token, String resultWho,
6380            int requestCode, Intent[] intents, String[] resolvedTypes,
6381            int flags, Bundle options, int userId) {
6382        enforceNotIsolatedCaller("getIntentSender");
6383        // Refuse possible leaked file descriptors
6384        if (intents != null) {
6385            if (intents.length < 1) {
6386                throw new IllegalArgumentException("Intents array length must be >= 1");
6387            }
6388            for (int i=0; i<intents.length; i++) {
6389                Intent intent = intents[i];
6390                if (intent != null) {
6391                    if (intent.hasFileDescriptors()) {
6392                        throw new IllegalArgumentException("File descriptors passed in Intent");
6393                    }
6394                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6395                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6396                        throw new IllegalArgumentException(
6397                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6398                    }
6399                    intents[i] = new Intent(intent);
6400                }
6401            }
6402            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6403                throw new IllegalArgumentException(
6404                        "Intent array length does not match resolvedTypes length");
6405            }
6406        }
6407        if (options != null) {
6408            if (options.hasFileDescriptors()) {
6409                throw new IllegalArgumentException("File descriptors passed in options");
6410            }
6411        }
6412
6413        synchronized(this) {
6414            int callingUid = Binder.getCallingUid();
6415            int origUserId = userId;
6416            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6417                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6418                    ALLOW_NON_FULL, "getIntentSender", null);
6419            if (origUserId == UserHandle.USER_CURRENT) {
6420                // We don't want to evaluate this until the pending intent is
6421                // actually executed.  However, we do want to always do the
6422                // security checking for it above.
6423                userId = UserHandle.USER_CURRENT;
6424            }
6425            try {
6426                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6427                    int uid = AppGlobals.getPackageManager()
6428                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6429                    if (!UserHandle.isSameApp(callingUid, uid)) {
6430                        String msg = "Permission Denial: getIntentSender() from pid="
6431                            + Binder.getCallingPid()
6432                            + ", uid=" + Binder.getCallingUid()
6433                            + ", (need uid=" + uid + ")"
6434                            + " is not allowed to send as package " + packageName;
6435                        Slog.w(TAG, msg);
6436                        throw new SecurityException(msg);
6437                    }
6438                }
6439
6440                return getIntentSenderLocked(type, packageName, callingUid, userId,
6441                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6442
6443            } catch (RemoteException e) {
6444                throw new SecurityException(e);
6445            }
6446        }
6447    }
6448
6449    IIntentSender getIntentSenderLocked(int type, String packageName,
6450            int callingUid, int userId, IBinder token, String resultWho,
6451            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6452            Bundle options) {
6453        if (DEBUG_MU)
6454            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6455        ActivityRecord activity = null;
6456        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6457            activity = ActivityRecord.isInStackLocked(token);
6458            if (activity == null) {
6459                return null;
6460            }
6461            if (activity.finishing) {
6462                return null;
6463            }
6464        }
6465
6466        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6467        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6468        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6469        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6470                |PendingIntent.FLAG_UPDATE_CURRENT);
6471
6472        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6473                type, packageName, activity, resultWho,
6474                requestCode, intents, resolvedTypes, flags, options, userId);
6475        WeakReference<PendingIntentRecord> ref;
6476        ref = mIntentSenderRecords.get(key);
6477        PendingIntentRecord rec = ref != null ? ref.get() : null;
6478        if (rec != null) {
6479            if (!cancelCurrent) {
6480                if (updateCurrent) {
6481                    if (rec.key.requestIntent != null) {
6482                        rec.key.requestIntent.replaceExtras(intents != null ?
6483                                intents[intents.length - 1] : null);
6484                    }
6485                    if (intents != null) {
6486                        intents[intents.length-1] = rec.key.requestIntent;
6487                        rec.key.allIntents = intents;
6488                        rec.key.allResolvedTypes = resolvedTypes;
6489                    } else {
6490                        rec.key.allIntents = null;
6491                        rec.key.allResolvedTypes = null;
6492                    }
6493                }
6494                return rec;
6495            }
6496            rec.canceled = true;
6497            mIntentSenderRecords.remove(key);
6498        }
6499        if (noCreate) {
6500            return rec;
6501        }
6502        rec = new PendingIntentRecord(this, key, callingUid);
6503        mIntentSenderRecords.put(key, rec.ref);
6504        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6505            if (activity.pendingResults == null) {
6506                activity.pendingResults
6507                        = new HashSet<WeakReference<PendingIntentRecord>>();
6508            }
6509            activity.pendingResults.add(rec.ref);
6510        }
6511        return rec;
6512    }
6513
6514    @Override
6515    public void cancelIntentSender(IIntentSender sender) {
6516        if (!(sender instanceof PendingIntentRecord)) {
6517            return;
6518        }
6519        synchronized(this) {
6520            PendingIntentRecord rec = (PendingIntentRecord)sender;
6521            try {
6522                int uid = AppGlobals.getPackageManager()
6523                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6524                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6525                    String msg = "Permission Denial: cancelIntentSender() from pid="
6526                        + Binder.getCallingPid()
6527                        + ", uid=" + Binder.getCallingUid()
6528                        + " is not allowed to cancel packges "
6529                        + rec.key.packageName;
6530                    Slog.w(TAG, msg);
6531                    throw new SecurityException(msg);
6532                }
6533            } catch (RemoteException e) {
6534                throw new SecurityException(e);
6535            }
6536            cancelIntentSenderLocked(rec, true);
6537        }
6538    }
6539
6540    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6541        rec.canceled = true;
6542        mIntentSenderRecords.remove(rec.key);
6543        if (cleanActivity && rec.key.activity != null) {
6544            rec.key.activity.pendingResults.remove(rec.ref);
6545        }
6546    }
6547
6548    @Override
6549    public String getPackageForIntentSender(IIntentSender pendingResult) {
6550        if (!(pendingResult instanceof PendingIntentRecord)) {
6551            return null;
6552        }
6553        try {
6554            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6555            return res.key.packageName;
6556        } catch (ClassCastException e) {
6557        }
6558        return null;
6559    }
6560
6561    @Override
6562    public int getUidForIntentSender(IIntentSender sender) {
6563        if (sender instanceof PendingIntentRecord) {
6564            try {
6565                PendingIntentRecord res = (PendingIntentRecord)sender;
6566                return res.uid;
6567            } catch (ClassCastException e) {
6568            }
6569        }
6570        return -1;
6571    }
6572
6573    @Override
6574    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6575        if (!(pendingResult instanceof PendingIntentRecord)) {
6576            return false;
6577        }
6578        try {
6579            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6580            if (res.key.allIntents == null) {
6581                return false;
6582            }
6583            for (int i=0; i<res.key.allIntents.length; i++) {
6584                Intent intent = res.key.allIntents[i];
6585                if (intent.getPackage() != null && intent.getComponent() != null) {
6586                    return false;
6587                }
6588            }
6589            return true;
6590        } catch (ClassCastException e) {
6591        }
6592        return false;
6593    }
6594
6595    @Override
6596    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6597        if (!(pendingResult instanceof PendingIntentRecord)) {
6598            return false;
6599        }
6600        try {
6601            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6602            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6603                return true;
6604            }
6605            return false;
6606        } catch (ClassCastException e) {
6607        }
6608        return false;
6609    }
6610
6611    @Override
6612    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6613        if (!(pendingResult instanceof PendingIntentRecord)) {
6614            return null;
6615        }
6616        try {
6617            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6618            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6619        } catch (ClassCastException e) {
6620        }
6621        return null;
6622    }
6623
6624    @Override
6625    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6626        if (!(pendingResult instanceof PendingIntentRecord)) {
6627            return null;
6628        }
6629        try {
6630            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6631            Intent intent = res.key.requestIntent;
6632            if (intent != null) {
6633                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6634                        || res.lastTagPrefix.equals(prefix))) {
6635                    return res.lastTag;
6636                }
6637                res.lastTagPrefix = prefix;
6638                StringBuilder sb = new StringBuilder(128);
6639                if (prefix != null) {
6640                    sb.append(prefix);
6641                }
6642                if (intent.getAction() != null) {
6643                    sb.append(intent.getAction());
6644                } else if (intent.getComponent() != null) {
6645                    intent.getComponent().appendShortString(sb);
6646                } else {
6647                    sb.append("?");
6648                }
6649                return res.lastTag = sb.toString();
6650            }
6651        } catch (ClassCastException e) {
6652        }
6653        return null;
6654    }
6655
6656    @Override
6657    public void setProcessLimit(int max) {
6658        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6659                "setProcessLimit()");
6660        synchronized (this) {
6661            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6662            mProcessLimitOverride = max;
6663        }
6664        trimApplications();
6665    }
6666
6667    @Override
6668    public int getProcessLimit() {
6669        synchronized (this) {
6670            return mProcessLimitOverride;
6671        }
6672    }
6673
6674    void foregroundTokenDied(ForegroundToken token) {
6675        synchronized (ActivityManagerService.this) {
6676            synchronized (mPidsSelfLocked) {
6677                ForegroundToken cur
6678                    = mForegroundProcesses.get(token.pid);
6679                if (cur != token) {
6680                    return;
6681                }
6682                mForegroundProcesses.remove(token.pid);
6683                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6684                if (pr == null) {
6685                    return;
6686                }
6687                pr.forcingToForeground = null;
6688                updateProcessForegroundLocked(pr, false, false);
6689            }
6690            updateOomAdjLocked();
6691        }
6692    }
6693
6694    @Override
6695    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6696        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6697                "setProcessForeground()");
6698        synchronized(this) {
6699            boolean changed = false;
6700
6701            synchronized (mPidsSelfLocked) {
6702                ProcessRecord pr = mPidsSelfLocked.get(pid);
6703                if (pr == null && isForeground) {
6704                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6705                    return;
6706                }
6707                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6708                if (oldToken != null) {
6709                    oldToken.token.unlinkToDeath(oldToken, 0);
6710                    mForegroundProcesses.remove(pid);
6711                    if (pr != null) {
6712                        pr.forcingToForeground = null;
6713                    }
6714                    changed = true;
6715                }
6716                if (isForeground && token != null) {
6717                    ForegroundToken newToken = new ForegroundToken() {
6718                        @Override
6719                        public void binderDied() {
6720                            foregroundTokenDied(this);
6721                        }
6722                    };
6723                    newToken.pid = pid;
6724                    newToken.token = token;
6725                    try {
6726                        token.linkToDeath(newToken, 0);
6727                        mForegroundProcesses.put(pid, newToken);
6728                        pr.forcingToForeground = token;
6729                        changed = true;
6730                    } catch (RemoteException e) {
6731                        // If the process died while doing this, we will later
6732                        // do the cleanup with the process death link.
6733                    }
6734                }
6735            }
6736
6737            if (changed) {
6738                updateOomAdjLocked();
6739            }
6740        }
6741    }
6742
6743    // =========================================================
6744    // PERMISSIONS
6745    // =========================================================
6746
6747    static class PermissionController extends IPermissionController.Stub {
6748        ActivityManagerService mActivityManagerService;
6749        PermissionController(ActivityManagerService activityManagerService) {
6750            mActivityManagerService = activityManagerService;
6751        }
6752
6753        @Override
6754        public boolean checkPermission(String permission, int pid, int uid) {
6755            return mActivityManagerService.checkPermission(permission, pid,
6756                    uid) == PackageManager.PERMISSION_GRANTED;
6757        }
6758    }
6759
6760    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6761        @Override
6762        public int checkComponentPermission(String permission, int pid, int uid,
6763                int owningUid, boolean exported) {
6764            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6765                    owningUid, exported);
6766        }
6767
6768        @Override
6769        public Object getAMSLock() {
6770            return ActivityManagerService.this;
6771        }
6772    }
6773
6774    /**
6775     * This can be called with or without the global lock held.
6776     */
6777    int checkComponentPermission(String permission, int pid, int uid,
6778            int owningUid, boolean exported) {
6779        // We might be performing an operation on behalf of an indirect binder
6780        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6781        // client identity accordingly before proceeding.
6782        Identity tlsIdentity = sCallerIdentity.get();
6783        if (tlsIdentity != null) {
6784            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6785                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6786            uid = tlsIdentity.uid;
6787            pid = tlsIdentity.pid;
6788        }
6789
6790        if (pid == MY_PID) {
6791            return PackageManager.PERMISSION_GRANTED;
6792        }
6793
6794        return ActivityManager.checkComponentPermission(permission, uid,
6795                owningUid, exported);
6796    }
6797
6798    /**
6799     * As the only public entry point for permissions checking, this method
6800     * can enforce the semantic that requesting a check on a null global
6801     * permission is automatically denied.  (Internally a null permission
6802     * string is used when calling {@link #checkComponentPermission} in cases
6803     * when only uid-based security is needed.)
6804     *
6805     * This can be called with or without the global lock held.
6806     */
6807    @Override
6808    public int checkPermission(String permission, int pid, int uid) {
6809        if (permission == null) {
6810            return PackageManager.PERMISSION_DENIED;
6811        }
6812        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6813    }
6814
6815    /**
6816     * Binder IPC calls go through the public entry point.
6817     * This can be called with or without the global lock held.
6818     */
6819    int checkCallingPermission(String permission) {
6820        return checkPermission(permission,
6821                Binder.getCallingPid(),
6822                UserHandle.getAppId(Binder.getCallingUid()));
6823    }
6824
6825    /**
6826     * This can be called with or without the global lock held.
6827     */
6828    void enforceCallingPermission(String permission, String func) {
6829        if (checkCallingPermission(permission)
6830                == PackageManager.PERMISSION_GRANTED) {
6831            return;
6832        }
6833
6834        String msg = "Permission Denial: " + func + " from pid="
6835                + Binder.getCallingPid()
6836                + ", uid=" + Binder.getCallingUid()
6837                + " requires " + permission;
6838        Slog.w(TAG, msg);
6839        throw new SecurityException(msg);
6840    }
6841
6842    /**
6843     * Determine if UID is holding permissions required to access {@link Uri} in
6844     * the given {@link ProviderInfo}. Final permission checking is always done
6845     * in {@link ContentProvider}.
6846     */
6847    private final boolean checkHoldingPermissionsLocked(
6848            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6849        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6850                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6851        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6852            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6853                    != PERMISSION_GRANTED) {
6854                return false;
6855            }
6856        }
6857        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6858    }
6859
6860    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6861            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6862        if (pi.applicationInfo.uid == uid) {
6863            return true;
6864        } else if (!pi.exported) {
6865            return false;
6866        }
6867
6868        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6869        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6870        try {
6871            // check if target holds top-level <provider> permissions
6872            if (!readMet && pi.readPermission != null && considerUidPermissions
6873                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6874                readMet = true;
6875            }
6876            if (!writeMet && pi.writePermission != null && considerUidPermissions
6877                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6878                writeMet = true;
6879            }
6880
6881            // track if unprotected read/write is allowed; any denied
6882            // <path-permission> below removes this ability
6883            boolean allowDefaultRead = pi.readPermission == null;
6884            boolean allowDefaultWrite = pi.writePermission == null;
6885
6886            // check if target holds any <path-permission> that match uri
6887            final PathPermission[] pps = pi.pathPermissions;
6888            if (pps != null) {
6889                final String path = grantUri.uri.getPath();
6890                int i = pps.length;
6891                while (i > 0 && (!readMet || !writeMet)) {
6892                    i--;
6893                    PathPermission pp = pps[i];
6894                    if (pp.match(path)) {
6895                        if (!readMet) {
6896                            final String pprperm = pp.getReadPermission();
6897                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6898                                    + pprperm + " for " + pp.getPath()
6899                                    + ": match=" + pp.match(path)
6900                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6901                            if (pprperm != null) {
6902                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6903                                        == PERMISSION_GRANTED) {
6904                                    readMet = true;
6905                                } else {
6906                                    allowDefaultRead = false;
6907                                }
6908                            }
6909                        }
6910                        if (!writeMet) {
6911                            final String ppwperm = pp.getWritePermission();
6912                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6913                                    + ppwperm + " for " + pp.getPath()
6914                                    + ": match=" + pp.match(path)
6915                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6916                            if (ppwperm != null) {
6917                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6918                                        == PERMISSION_GRANTED) {
6919                                    writeMet = true;
6920                                } else {
6921                                    allowDefaultWrite = false;
6922                                }
6923                            }
6924                        }
6925                    }
6926                }
6927            }
6928
6929            // grant unprotected <provider> read/write, if not blocked by
6930            // <path-permission> above
6931            if (allowDefaultRead) readMet = true;
6932            if (allowDefaultWrite) writeMet = true;
6933
6934        } catch (RemoteException e) {
6935            return false;
6936        }
6937
6938        return readMet && writeMet;
6939    }
6940
6941    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6942        ProviderInfo pi = null;
6943        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6944        if (cpr != null) {
6945            pi = cpr.info;
6946        } else {
6947            try {
6948                pi = AppGlobals.getPackageManager().resolveContentProvider(
6949                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6950            } catch (RemoteException ex) {
6951            }
6952        }
6953        return pi;
6954    }
6955
6956    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6957        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6958        if (targetUris != null) {
6959            return targetUris.get(grantUri);
6960        }
6961        return null;
6962    }
6963
6964    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6965            String targetPkg, int targetUid, GrantUri grantUri) {
6966        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6967        if (targetUris == null) {
6968            targetUris = Maps.newArrayMap();
6969            mGrantedUriPermissions.put(targetUid, targetUris);
6970        }
6971
6972        UriPermission perm = targetUris.get(grantUri);
6973        if (perm == null) {
6974            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6975            targetUris.put(grantUri, perm);
6976        }
6977
6978        return perm;
6979    }
6980
6981    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6982            final int modeFlags) {
6983        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6984        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6985                : UriPermission.STRENGTH_OWNED;
6986
6987        // Root gets to do everything.
6988        if (uid == 0) {
6989            return true;
6990        }
6991
6992        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6993        if (perms == null) return false;
6994
6995        // First look for exact match
6996        final UriPermission exactPerm = perms.get(grantUri);
6997        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6998            return true;
6999        }
7000
7001        // No exact match, look for prefixes
7002        final int N = perms.size();
7003        for (int i = 0; i < N; i++) {
7004            final UriPermission perm = perms.valueAt(i);
7005            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7006                    && perm.getStrength(modeFlags) >= minStrength) {
7007                return true;
7008            }
7009        }
7010
7011        return false;
7012    }
7013
7014    /**
7015     * @param uri This uri must NOT contain an embedded userId.
7016     * @param userId The userId in which the uri is to be resolved.
7017     */
7018    @Override
7019    public int checkUriPermission(Uri uri, int pid, int uid,
7020            final int modeFlags, int userId) {
7021        enforceNotIsolatedCaller("checkUriPermission");
7022
7023        // Another redirected-binder-call permissions check as in
7024        // {@link checkComponentPermission}.
7025        Identity tlsIdentity = sCallerIdentity.get();
7026        if (tlsIdentity != null) {
7027            uid = tlsIdentity.uid;
7028            pid = tlsIdentity.pid;
7029        }
7030
7031        // Our own process gets to do everything.
7032        if (pid == MY_PID) {
7033            return PackageManager.PERMISSION_GRANTED;
7034        }
7035        synchronized (this) {
7036            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7037                    ? PackageManager.PERMISSION_GRANTED
7038                    : PackageManager.PERMISSION_DENIED;
7039        }
7040    }
7041
7042    /**
7043     * Check if the targetPkg can be granted permission to access uri by
7044     * the callingUid using the given modeFlags.  Throws a security exception
7045     * if callingUid is not allowed to do this.  Returns the uid of the target
7046     * if the URI permission grant should be performed; returns -1 if it is not
7047     * needed (for example targetPkg already has permission to access the URI).
7048     * If you already know the uid of the target, you can supply it in
7049     * lastTargetUid else set that to -1.
7050     */
7051    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7052            final int modeFlags, int lastTargetUid) {
7053        if (!Intent.isAccessUriMode(modeFlags)) {
7054            return -1;
7055        }
7056
7057        if (targetPkg != null) {
7058            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7059                    "Checking grant " + targetPkg + " permission to " + grantUri);
7060        }
7061
7062        final IPackageManager pm = AppGlobals.getPackageManager();
7063
7064        // If this is not a content: uri, we can't do anything with it.
7065        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7066            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7067                    "Can't grant URI permission for non-content URI: " + grantUri);
7068            return -1;
7069        }
7070
7071        final String authority = grantUri.uri.getAuthority();
7072        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7073        if (pi == null) {
7074            Slog.w(TAG, "No content provider found for permission check: " +
7075                    grantUri.uri.toSafeString());
7076            return -1;
7077        }
7078
7079        int targetUid = lastTargetUid;
7080        if (targetUid < 0 && targetPkg != null) {
7081            try {
7082                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7083                if (targetUid < 0) {
7084                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7085                            "Can't grant URI permission no uid for: " + targetPkg);
7086                    return -1;
7087                }
7088            } catch (RemoteException ex) {
7089                return -1;
7090            }
7091        }
7092
7093        if (targetUid >= 0) {
7094            // First...  does the target actually need this permission?
7095            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7096                // No need to grant the target this permission.
7097                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7098                        "Target " + targetPkg + " already has full permission to " + grantUri);
7099                return -1;
7100            }
7101        } else {
7102            // First...  there is no target package, so can anyone access it?
7103            boolean allowed = pi.exported;
7104            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7105                if (pi.readPermission != null) {
7106                    allowed = false;
7107                }
7108            }
7109            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7110                if (pi.writePermission != null) {
7111                    allowed = false;
7112                }
7113            }
7114            if (allowed) {
7115                return -1;
7116            }
7117        }
7118
7119        /* There is a special cross user grant if:
7120         * - The target is on another user.
7121         * - Apps on the current user can access the uri without any uid permissions.
7122         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7123         * grant uri permissions.
7124         */
7125        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7126                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7127                modeFlags, false /*without considering the uid permissions*/);
7128
7129        // Second...  is the provider allowing granting of URI permissions?
7130        if (!specialCrossUserGrant) {
7131            if (!pi.grantUriPermissions) {
7132                throw new SecurityException("Provider " + pi.packageName
7133                        + "/" + pi.name
7134                        + " does not allow granting of Uri permissions (uri "
7135                        + grantUri + ")");
7136            }
7137            if (pi.uriPermissionPatterns != null) {
7138                final int N = pi.uriPermissionPatterns.length;
7139                boolean allowed = false;
7140                for (int i=0; i<N; i++) {
7141                    if (pi.uriPermissionPatterns[i] != null
7142                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7143                        allowed = true;
7144                        break;
7145                    }
7146                }
7147                if (!allowed) {
7148                    throw new SecurityException("Provider " + pi.packageName
7149                            + "/" + pi.name
7150                            + " does not allow granting of permission to path of Uri "
7151                            + grantUri);
7152                }
7153            }
7154        }
7155
7156        // Third...  does the caller itself have permission to access
7157        // this uri?
7158        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7159            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7160                // Require they hold a strong enough Uri permission
7161                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7162                    throw new SecurityException("Uid " + callingUid
7163                            + " does not have permission to uri " + grantUri);
7164                }
7165            }
7166        }
7167        return targetUid;
7168    }
7169
7170    /**
7171     * @param uri This uri must NOT contain an embedded userId.
7172     * @param userId The userId in which the uri is to be resolved.
7173     */
7174    @Override
7175    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7176            final int modeFlags, int userId) {
7177        enforceNotIsolatedCaller("checkGrantUriPermission");
7178        synchronized(this) {
7179            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7180                    new GrantUri(userId, uri, false), modeFlags, -1);
7181        }
7182    }
7183
7184    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7185            final int modeFlags, UriPermissionOwner owner) {
7186        if (!Intent.isAccessUriMode(modeFlags)) {
7187            return;
7188        }
7189
7190        // So here we are: the caller has the assumed permission
7191        // to the uri, and the target doesn't.  Let's now give this to
7192        // the target.
7193
7194        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7195                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7196
7197        final String authority = grantUri.uri.getAuthority();
7198        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7199        if (pi == null) {
7200            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7201            return;
7202        }
7203
7204        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7205            grantUri.prefix = true;
7206        }
7207        final UriPermission perm = findOrCreateUriPermissionLocked(
7208                pi.packageName, targetPkg, targetUid, grantUri);
7209        perm.grantModes(modeFlags, owner);
7210    }
7211
7212    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7213            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7214        if (targetPkg == null) {
7215            throw new NullPointerException("targetPkg");
7216        }
7217        int targetUid;
7218        final IPackageManager pm = AppGlobals.getPackageManager();
7219        try {
7220            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7221        } catch (RemoteException ex) {
7222            return;
7223        }
7224
7225        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7226                targetUid);
7227        if (targetUid < 0) {
7228            return;
7229        }
7230
7231        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7232                owner);
7233    }
7234
7235    static class NeededUriGrants extends ArrayList<GrantUri> {
7236        final String targetPkg;
7237        final int targetUid;
7238        final int flags;
7239
7240        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7241            this.targetPkg = targetPkg;
7242            this.targetUid = targetUid;
7243            this.flags = flags;
7244        }
7245    }
7246
7247    /**
7248     * Like checkGrantUriPermissionLocked, but takes an Intent.
7249     */
7250    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7251            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7252        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7253                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7254                + " clip=" + (intent != null ? intent.getClipData() : null)
7255                + " from " + intent + "; flags=0x"
7256                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7257
7258        if (targetPkg == null) {
7259            throw new NullPointerException("targetPkg");
7260        }
7261
7262        if (intent == null) {
7263            return null;
7264        }
7265        Uri data = intent.getData();
7266        ClipData clip = intent.getClipData();
7267        if (data == null && clip == null) {
7268            return null;
7269        }
7270        // Default userId for uris in the intent (if they don't specify it themselves)
7271        int contentUserHint = intent.getContentUserHint();
7272        if (contentUserHint == UserHandle.USER_CURRENT) {
7273            contentUserHint = UserHandle.getUserId(callingUid);
7274        }
7275        final IPackageManager pm = AppGlobals.getPackageManager();
7276        int targetUid;
7277        if (needed != null) {
7278            targetUid = needed.targetUid;
7279        } else {
7280            try {
7281                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7282            } catch (RemoteException ex) {
7283                return null;
7284            }
7285            if (targetUid < 0) {
7286                if (DEBUG_URI_PERMISSION) {
7287                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7288                            + " on user " + targetUserId);
7289                }
7290                return null;
7291            }
7292        }
7293        if (data != null) {
7294            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7295            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7296                    targetUid);
7297            if (targetUid > 0) {
7298                if (needed == null) {
7299                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7300                }
7301                needed.add(grantUri);
7302            }
7303        }
7304        if (clip != null) {
7305            for (int i=0; i<clip.getItemCount(); i++) {
7306                Uri uri = clip.getItemAt(i).getUri();
7307                if (uri != null) {
7308                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7309                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7310                            targetUid);
7311                    if (targetUid > 0) {
7312                        if (needed == null) {
7313                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7314                        }
7315                        needed.add(grantUri);
7316                    }
7317                } else {
7318                    Intent clipIntent = clip.getItemAt(i).getIntent();
7319                    if (clipIntent != null) {
7320                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7321                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7322                        if (newNeeded != null) {
7323                            needed = newNeeded;
7324                        }
7325                    }
7326                }
7327            }
7328        }
7329
7330        return needed;
7331    }
7332
7333    /**
7334     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7335     */
7336    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7337            UriPermissionOwner owner) {
7338        if (needed != null) {
7339            for (int i=0; i<needed.size(); i++) {
7340                GrantUri grantUri = needed.get(i);
7341                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7342                        grantUri, needed.flags, owner);
7343            }
7344        }
7345    }
7346
7347    void grantUriPermissionFromIntentLocked(int callingUid,
7348            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7349        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7350                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7351        if (needed == null) {
7352            return;
7353        }
7354
7355        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7356    }
7357
7358    /**
7359     * @param uri This uri must NOT contain an embedded userId.
7360     * @param userId The userId in which the uri is to be resolved.
7361     */
7362    @Override
7363    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7364            final int modeFlags, int userId) {
7365        enforceNotIsolatedCaller("grantUriPermission");
7366        GrantUri grantUri = new GrantUri(userId, uri, false);
7367        synchronized(this) {
7368            final ProcessRecord r = getRecordForAppLocked(caller);
7369            if (r == null) {
7370                throw new SecurityException("Unable to find app for caller "
7371                        + caller
7372                        + " when granting permission to uri " + grantUri);
7373            }
7374            if (targetPkg == null) {
7375                throw new IllegalArgumentException("null target");
7376            }
7377            if (grantUri == null) {
7378                throw new IllegalArgumentException("null uri");
7379            }
7380
7381            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7382                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7383                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7384                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7385
7386            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7387                    UserHandle.getUserId(r.uid));
7388        }
7389    }
7390
7391    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7392        if (perm.modeFlags == 0) {
7393            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7394                    perm.targetUid);
7395            if (perms != null) {
7396                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7397                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7398
7399                perms.remove(perm.uri);
7400                if (perms.isEmpty()) {
7401                    mGrantedUriPermissions.remove(perm.targetUid);
7402                }
7403            }
7404        }
7405    }
7406
7407    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7408        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7409
7410        final IPackageManager pm = AppGlobals.getPackageManager();
7411        final String authority = grantUri.uri.getAuthority();
7412        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7413        if (pi == null) {
7414            Slog.w(TAG, "No content provider found for permission revoke: "
7415                    + grantUri.toSafeString());
7416            return;
7417        }
7418
7419        // Does the caller have this permission on the URI?
7420        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7421            // If they don't have direct access to the URI, then revoke any
7422            // ownerless URI permissions that have been granted to them.
7423            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7424            if (perms != null) {
7425                boolean persistChanged = false;
7426                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7427                    final UriPermission perm = it.next();
7428                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7429                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7430                        if (DEBUG_URI_PERMISSION)
7431                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7432                                    " permission to " + perm.uri);
7433                        persistChanged |= perm.revokeModes(
7434                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7435                        if (perm.modeFlags == 0) {
7436                            it.remove();
7437                        }
7438                    }
7439                }
7440                if (perms.isEmpty()) {
7441                    mGrantedUriPermissions.remove(callingUid);
7442                }
7443                if (persistChanged) {
7444                    schedulePersistUriGrants();
7445                }
7446            }
7447            return;
7448        }
7449
7450        boolean persistChanged = false;
7451
7452        // Go through all of the permissions and remove any that match.
7453        int N = mGrantedUriPermissions.size();
7454        for (int i = 0; i < N; i++) {
7455            final int targetUid = mGrantedUriPermissions.keyAt(i);
7456            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7457
7458            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7459                final UriPermission perm = it.next();
7460                if (perm.uri.sourceUserId == grantUri.sourceUserId
7461                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7462                    if (DEBUG_URI_PERMISSION)
7463                        Slog.v(TAG,
7464                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7465                    persistChanged |= perm.revokeModes(
7466                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7467                    if (perm.modeFlags == 0) {
7468                        it.remove();
7469                    }
7470                }
7471            }
7472
7473            if (perms.isEmpty()) {
7474                mGrantedUriPermissions.remove(targetUid);
7475                N--;
7476                i--;
7477            }
7478        }
7479
7480        if (persistChanged) {
7481            schedulePersistUriGrants();
7482        }
7483    }
7484
7485    /**
7486     * @param uri This uri must NOT contain an embedded userId.
7487     * @param userId The userId in which the uri is to be resolved.
7488     */
7489    @Override
7490    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7491            int userId) {
7492        enforceNotIsolatedCaller("revokeUriPermission");
7493        synchronized(this) {
7494            final ProcessRecord r = getRecordForAppLocked(caller);
7495            if (r == null) {
7496                throw new SecurityException("Unable to find app for caller "
7497                        + caller
7498                        + " when revoking permission to uri " + uri);
7499            }
7500            if (uri == null) {
7501                Slog.w(TAG, "revokeUriPermission: null uri");
7502                return;
7503            }
7504
7505            if (!Intent.isAccessUriMode(modeFlags)) {
7506                return;
7507            }
7508
7509            final IPackageManager pm = AppGlobals.getPackageManager();
7510            final String authority = uri.getAuthority();
7511            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7512            if (pi == null) {
7513                Slog.w(TAG, "No content provider found for permission revoke: "
7514                        + uri.toSafeString());
7515                return;
7516            }
7517
7518            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7519        }
7520    }
7521
7522    /**
7523     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7524     * given package.
7525     *
7526     * @param packageName Package name to match, or {@code null} to apply to all
7527     *            packages.
7528     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7529     *            to all users.
7530     * @param persistable If persistable grants should be removed.
7531     */
7532    private void removeUriPermissionsForPackageLocked(
7533            String packageName, int userHandle, boolean persistable) {
7534        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7535            throw new IllegalArgumentException("Must narrow by either package or user");
7536        }
7537
7538        boolean persistChanged = false;
7539
7540        int N = mGrantedUriPermissions.size();
7541        for (int i = 0; i < N; i++) {
7542            final int targetUid = mGrantedUriPermissions.keyAt(i);
7543            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7544
7545            // Only inspect grants matching user
7546            if (userHandle == UserHandle.USER_ALL
7547                    || userHandle == UserHandle.getUserId(targetUid)) {
7548                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7549                    final UriPermission perm = it.next();
7550
7551                    // Only inspect grants matching package
7552                    if (packageName == null || perm.sourcePkg.equals(packageName)
7553                            || perm.targetPkg.equals(packageName)) {
7554                        persistChanged |= perm.revokeModes(persistable
7555                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7556
7557                        // Only remove when no modes remain; any persisted grants
7558                        // will keep this alive.
7559                        if (perm.modeFlags == 0) {
7560                            it.remove();
7561                        }
7562                    }
7563                }
7564
7565                if (perms.isEmpty()) {
7566                    mGrantedUriPermissions.remove(targetUid);
7567                    N--;
7568                    i--;
7569                }
7570            }
7571        }
7572
7573        if (persistChanged) {
7574            schedulePersistUriGrants();
7575        }
7576    }
7577
7578    @Override
7579    public IBinder newUriPermissionOwner(String name) {
7580        enforceNotIsolatedCaller("newUriPermissionOwner");
7581        synchronized(this) {
7582            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7583            return owner.getExternalTokenLocked();
7584        }
7585    }
7586
7587    /**
7588     * @param uri This uri must NOT contain an embedded userId.
7589     * @param sourceUserId The userId in which the uri is to be resolved.
7590     * @param targetUserId The userId of the app that receives the grant.
7591     */
7592    @Override
7593    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7594            final int modeFlags, int sourceUserId, int targetUserId) {
7595        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7596                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7597        synchronized(this) {
7598            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7599            if (owner == null) {
7600                throw new IllegalArgumentException("Unknown owner: " + token);
7601            }
7602            if (fromUid != Binder.getCallingUid()) {
7603                if (Binder.getCallingUid() != Process.myUid()) {
7604                    // Only system code can grant URI permissions on behalf
7605                    // of other users.
7606                    throw new SecurityException("nice try");
7607                }
7608            }
7609            if (targetPkg == null) {
7610                throw new IllegalArgumentException("null target");
7611            }
7612            if (uri == null) {
7613                throw new IllegalArgumentException("null uri");
7614            }
7615
7616            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7617                    modeFlags, owner, targetUserId);
7618        }
7619    }
7620
7621    /**
7622     * @param uri This uri must NOT contain an embedded userId.
7623     * @param userId The userId in which the uri is to be resolved.
7624     */
7625    @Override
7626    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7627        synchronized(this) {
7628            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7629            if (owner == null) {
7630                throw new IllegalArgumentException("Unknown owner: " + token);
7631            }
7632
7633            if (uri == null) {
7634                owner.removeUriPermissionsLocked(mode);
7635            } else {
7636                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7637            }
7638        }
7639    }
7640
7641    private void schedulePersistUriGrants() {
7642        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7643            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7644                    10 * DateUtils.SECOND_IN_MILLIS);
7645        }
7646    }
7647
7648    private void writeGrantedUriPermissions() {
7649        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7650
7651        // Snapshot permissions so we can persist without lock
7652        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7653        synchronized (this) {
7654            final int size = mGrantedUriPermissions.size();
7655            for (int i = 0; i < size; i++) {
7656                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7657                for (UriPermission perm : perms.values()) {
7658                    if (perm.persistedModeFlags != 0) {
7659                        persist.add(perm.snapshot());
7660                    }
7661                }
7662            }
7663        }
7664
7665        FileOutputStream fos = null;
7666        try {
7667            fos = mGrantFile.startWrite();
7668
7669            XmlSerializer out = new FastXmlSerializer();
7670            out.setOutput(fos, "utf-8");
7671            out.startDocument(null, true);
7672            out.startTag(null, TAG_URI_GRANTS);
7673            for (UriPermission.Snapshot perm : persist) {
7674                out.startTag(null, TAG_URI_GRANT);
7675                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7676                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7677                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7678                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7679                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7680                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7681                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7682                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7683                out.endTag(null, TAG_URI_GRANT);
7684            }
7685            out.endTag(null, TAG_URI_GRANTS);
7686            out.endDocument();
7687
7688            mGrantFile.finishWrite(fos);
7689        } catch (IOException e) {
7690            if (fos != null) {
7691                mGrantFile.failWrite(fos);
7692            }
7693        }
7694    }
7695
7696    private void readGrantedUriPermissionsLocked() {
7697        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7698
7699        final long now = System.currentTimeMillis();
7700
7701        FileInputStream fis = null;
7702        try {
7703            fis = mGrantFile.openRead();
7704            final XmlPullParser in = Xml.newPullParser();
7705            in.setInput(fis, null);
7706
7707            int type;
7708            while ((type = in.next()) != END_DOCUMENT) {
7709                final String tag = in.getName();
7710                if (type == START_TAG) {
7711                    if (TAG_URI_GRANT.equals(tag)) {
7712                        final int sourceUserId;
7713                        final int targetUserId;
7714                        final int userHandle = readIntAttribute(in,
7715                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7716                        if (userHandle != UserHandle.USER_NULL) {
7717                            // For backwards compatibility.
7718                            sourceUserId = userHandle;
7719                            targetUserId = userHandle;
7720                        } else {
7721                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7722                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7723                        }
7724                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7725                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7726                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7727                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7728                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7729                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7730
7731                        // Sanity check that provider still belongs to source package
7732                        final ProviderInfo pi = getProviderInfoLocked(
7733                                uri.getAuthority(), sourceUserId);
7734                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7735                            int targetUid = -1;
7736                            try {
7737                                targetUid = AppGlobals.getPackageManager()
7738                                        .getPackageUid(targetPkg, targetUserId);
7739                            } catch (RemoteException e) {
7740                            }
7741                            if (targetUid != -1) {
7742                                final UriPermission perm = findOrCreateUriPermissionLocked(
7743                                        sourcePkg, targetPkg, targetUid,
7744                                        new GrantUri(sourceUserId, uri, prefix));
7745                                perm.initPersistedModes(modeFlags, createdTime);
7746                            }
7747                        } else {
7748                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7749                                    + " but instead found " + pi);
7750                        }
7751                    }
7752                }
7753            }
7754        } catch (FileNotFoundException e) {
7755            // Missing grants is okay
7756        } catch (IOException e) {
7757            Slog.wtf(TAG, "Failed reading Uri grants", e);
7758        } catch (XmlPullParserException e) {
7759            Slog.wtf(TAG, "Failed reading Uri grants", e);
7760        } finally {
7761            IoUtils.closeQuietly(fis);
7762        }
7763    }
7764
7765    /**
7766     * @param uri This uri must NOT contain an embedded userId.
7767     * @param userId The userId in which the uri is to be resolved.
7768     */
7769    @Override
7770    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7771        enforceNotIsolatedCaller("takePersistableUriPermission");
7772
7773        Preconditions.checkFlagsArgument(modeFlags,
7774                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7775
7776        synchronized (this) {
7777            final int callingUid = Binder.getCallingUid();
7778            boolean persistChanged = false;
7779            GrantUri grantUri = new GrantUri(userId, uri, false);
7780
7781            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7782                    new GrantUri(userId, uri, false));
7783            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7784                    new GrantUri(userId, uri, true));
7785
7786            final boolean exactValid = (exactPerm != null)
7787                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7788            final boolean prefixValid = (prefixPerm != null)
7789                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7790
7791            if (!(exactValid || prefixValid)) {
7792                throw new SecurityException("No persistable permission grants found for UID "
7793                        + callingUid + " and Uri " + grantUri.toSafeString());
7794            }
7795
7796            if (exactValid) {
7797                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7798            }
7799            if (prefixValid) {
7800                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7801            }
7802
7803            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7804
7805            if (persistChanged) {
7806                schedulePersistUriGrants();
7807            }
7808        }
7809    }
7810
7811    /**
7812     * @param uri This uri must NOT contain an embedded userId.
7813     * @param userId The userId in which the uri is to be resolved.
7814     */
7815    @Override
7816    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7817        enforceNotIsolatedCaller("releasePersistableUriPermission");
7818
7819        Preconditions.checkFlagsArgument(modeFlags,
7820                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7821
7822        synchronized (this) {
7823            final int callingUid = Binder.getCallingUid();
7824            boolean persistChanged = false;
7825
7826            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7827                    new GrantUri(userId, uri, false));
7828            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7829                    new GrantUri(userId, uri, true));
7830            if (exactPerm == null && prefixPerm == null) {
7831                throw new SecurityException("No permission grants found for UID " + callingUid
7832                        + " and Uri " + uri.toSafeString());
7833            }
7834
7835            if (exactPerm != null) {
7836                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7837                removeUriPermissionIfNeededLocked(exactPerm);
7838            }
7839            if (prefixPerm != null) {
7840                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7841                removeUriPermissionIfNeededLocked(prefixPerm);
7842            }
7843
7844            if (persistChanged) {
7845                schedulePersistUriGrants();
7846            }
7847        }
7848    }
7849
7850    /**
7851     * Prune any older {@link UriPermission} for the given UID until outstanding
7852     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7853     *
7854     * @return if any mutations occured that require persisting.
7855     */
7856    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7857        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7858        if (perms == null) return false;
7859        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7860
7861        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7862        for (UriPermission perm : perms.values()) {
7863            if (perm.persistedModeFlags != 0) {
7864                persisted.add(perm);
7865            }
7866        }
7867
7868        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7869        if (trimCount <= 0) return false;
7870
7871        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7872        for (int i = 0; i < trimCount; i++) {
7873            final UriPermission perm = persisted.get(i);
7874
7875            if (DEBUG_URI_PERMISSION) {
7876                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7877            }
7878
7879            perm.releasePersistableModes(~0);
7880            removeUriPermissionIfNeededLocked(perm);
7881        }
7882
7883        return true;
7884    }
7885
7886    @Override
7887    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7888            String packageName, boolean incoming) {
7889        enforceNotIsolatedCaller("getPersistedUriPermissions");
7890        Preconditions.checkNotNull(packageName, "packageName");
7891
7892        final int callingUid = Binder.getCallingUid();
7893        final IPackageManager pm = AppGlobals.getPackageManager();
7894        try {
7895            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7896            if (packageUid != callingUid) {
7897                throw new SecurityException(
7898                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7899            }
7900        } catch (RemoteException e) {
7901            throw new SecurityException("Failed to verify package name ownership");
7902        }
7903
7904        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7905        synchronized (this) {
7906            if (incoming) {
7907                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7908                        callingUid);
7909                if (perms == null) {
7910                    Slog.w(TAG, "No permission grants found for " + packageName);
7911                } else {
7912                    for (UriPermission perm : perms.values()) {
7913                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7914                            result.add(perm.buildPersistedPublicApiObject());
7915                        }
7916                    }
7917                }
7918            } else {
7919                final int size = mGrantedUriPermissions.size();
7920                for (int i = 0; i < size; i++) {
7921                    final ArrayMap<GrantUri, UriPermission> perms =
7922                            mGrantedUriPermissions.valueAt(i);
7923                    for (UriPermission perm : perms.values()) {
7924                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7925                            result.add(perm.buildPersistedPublicApiObject());
7926                        }
7927                    }
7928                }
7929            }
7930        }
7931        return new ParceledListSlice<android.content.UriPermission>(result);
7932    }
7933
7934    @Override
7935    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7936        synchronized (this) {
7937            ProcessRecord app =
7938                who != null ? getRecordForAppLocked(who) : null;
7939            if (app == null) return;
7940
7941            Message msg = Message.obtain();
7942            msg.what = WAIT_FOR_DEBUGGER_MSG;
7943            msg.obj = app;
7944            msg.arg1 = waiting ? 1 : 0;
7945            mHandler.sendMessage(msg);
7946        }
7947    }
7948
7949    @Override
7950    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7951        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7952        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7953        outInfo.availMem = Process.getFreeMemory();
7954        outInfo.totalMem = Process.getTotalMemory();
7955        outInfo.threshold = homeAppMem;
7956        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7957        outInfo.hiddenAppThreshold = cachedAppMem;
7958        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7959                ProcessList.SERVICE_ADJ);
7960        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7961                ProcessList.VISIBLE_APP_ADJ);
7962        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7963                ProcessList.FOREGROUND_APP_ADJ);
7964    }
7965
7966    // =========================================================
7967    // TASK MANAGEMENT
7968    // =========================================================
7969
7970    @Override
7971    public List<IAppTask> getAppTasks(String callingPackage) {
7972        int callingUid = Binder.getCallingUid();
7973        long ident = Binder.clearCallingIdentity();
7974
7975        synchronized(this) {
7976            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7977            try {
7978                if (localLOGV) Slog.v(TAG, "getAppTasks");
7979
7980                final int N = mRecentTasks.size();
7981                for (int i = 0; i < N; i++) {
7982                    TaskRecord tr = mRecentTasks.get(i);
7983                    // Skip tasks that do not match the caller.  We don't need to verify
7984                    // callingPackage, because we are also limiting to callingUid and know
7985                    // that will limit to the correct security sandbox.
7986                    if (tr.effectiveUid != callingUid) {
7987                        continue;
7988                    }
7989                    Intent intent = tr.getBaseIntent();
7990                    if (intent == null ||
7991                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7992                        continue;
7993                    }
7994                    ActivityManager.RecentTaskInfo taskInfo =
7995                            createRecentTaskInfoFromTaskRecord(tr);
7996                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7997                    list.add(taskImpl);
7998                }
7999            } finally {
8000                Binder.restoreCallingIdentity(ident);
8001            }
8002            return list;
8003        }
8004    }
8005
8006    @Override
8007    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8008        final int callingUid = Binder.getCallingUid();
8009        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8010
8011        synchronized(this) {
8012            if (localLOGV) Slog.v(
8013                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8014
8015            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8016                    callingUid);
8017
8018            // TODO: Improve with MRU list from all ActivityStacks.
8019            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8020        }
8021
8022        return list;
8023    }
8024
8025    TaskRecord getMostRecentTask() {
8026        return mRecentTasks.get(0);
8027    }
8028
8029    /**
8030     * Creates a new RecentTaskInfo from a TaskRecord.
8031     */
8032    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8033        // Update the task description to reflect any changes in the task stack
8034        tr.updateTaskDescription();
8035
8036        // Compose the recent task info
8037        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8038        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8039        rti.persistentId = tr.taskId;
8040        rti.baseIntent = new Intent(tr.getBaseIntent());
8041        rti.origActivity = tr.origActivity;
8042        rti.description = tr.lastDescription;
8043        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8044        rti.userId = tr.userId;
8045        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8046        rti.firstActiveTime = tr.firstActiveTime;
8047        rti.lastActiveTime = tr.lastActiveTime;
8048        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8049        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8050        return rti;
8051    }
8052
8053    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8054        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8055                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8056        if (!allowed) {
8057            if (checkPermission(android.Manifest.permission.GET_TASKS,
8058                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8059                // Temporary compatibility: some existing apps on the system image may
8060                // still be requesting the old permission and not switched to the new
8061                // one; if so, we'll still allow them full access.  This means we need
8062                // to see if they are holding the old permission and are a system app.
8063                try {
8064                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8065                        allowed = true;
8066                        Slog.w(TAG, caller + ": caller " + callingUid
8067                                + " is using old GET_TASKS but privileged; allowing");
8068                    }
8069                } catch (RemoteException e) {
8070                }
8071            }
8072        }
8073        if (!allowed) {
8074            Slog.w(TAG, caller + ": caller " + callingUid
8075                    + " does not hold GET_TASKS; limiting output");
8076        }
8077        return allowed;
8078    }
8079
8080    @Override
8081    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8082        final int callingUid = Binder.getCallingUid();
8083        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8084                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8085
8086        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8087        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8088        synchronized (this) {
8089            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8090                    callingUid);
8091            final boolean detailed = checkCallingPermission(
8092                    android.Manifest.permission.GET_DETAILED_TASKS)
8093                    == PackageManager.PERMISSION_GRANTED;
8094
8095            final int N = mRecentTasks.size();
8096            ArrayList<ActivityManager.RecentTaskInfo> res
8097                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8098                            maxNum < N ? maxNum : N);
8099
8100            final Set<Integer> includedUsers;
8101            if (includeProfiles) {
8102                includedUsers = getProfileIdsLocked(userId);
8103            } else {
8104                includedUsers = new HashSet<Integer>();
8105            }
8106            includedUsers.add(Integer.valueOf(userId));
8107
8108            for (int i=0; i<N && maxNum > 0; i++) {
8109                TaskRecord tr = mRecentTasks.get(i);
8110                // Only add calling user or related users recent tasks
8111                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8112                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8113                    continue;
8114                }
8115
8116                // Return the entry if desired by the caller.  We always return
8117                // the first entry, because callers always expect this to be the
8118                // foreground app.  We may filter others if the caller has
8119                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8120                // we should exclude the entry.
8121
8122                if (i == 0
8123                        || withExcluded
8124                        || (tr.intent == null)
8125                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8126                                == 0)) {
8127                    if (!allowed) {
8128                        // If the caller doesn't have the GET_TASKS permission, then only
8129                        // allow them to see a small subset of tasks -- their own and home.
8130                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8131                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8132                            continue;
8133                        }
8134                    }
8135                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8136                        if (tr.stack != null && tr.stack.isHomeStack()) {
8137                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8138                            continue;
8139                        }
8140                    }
8141                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8142                        // Don't include auto remove tasks that are finished or finishing.
8143                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8144                                + tr);
8145                        continue;
8146                    }
8147                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8148                            && !tr.isAvailable) {
8149                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8150                        continue;
8151                    }
8152
8153                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8154                    if (!detailed) {
8155                        rti.baseIntent.replaceExtras((Bundle)null);
8156                    }
8157
8158                    res.add(rti);
8159                    maxNum--;
8160                }
8161            }
8162            return res;
8163        }
8164    }
8165
8166    private TaskRecord recentTaskForIdLocked(int id) {
8167        final int N = mRecentTasks.size();
8168            for (int i=0; i<N; i++) {
8169                TaskRecord tr = mRecentTasks.get(i);
8170                if (tr.taskId == id) {
8171                    return tr;
8172                }
8173            }
8174            return null;
8175    }
8176
8177    @Override
8178    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8179        synchronized (this) {
8180            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8181                    "getTaskThumbnail()");
8182            TaskRecord tr = recentTaskForIdLocked(id);
8183            if (tr != null) {
8184                return tr.getTaskThumbnailLocked();
8185            }
8186        }
8187        return null;
8188    }
8189
8190    @Override
8191    public int addAppTask(IBinder activityToken, Intent intent,
8192            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8193        final int callingUid = Binder.getCallingUid();
8194        final long callingIdent = Binder.clearCallingIdentity();
8195
8196        try {
8197            synchronized (this) {
8198                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8199                if (r == null) {
8200                    throw new IllegalArgumentException("Activity does not exist; token="
8201                            + activityToken);
8202                }
8203                ComponentName comp = intent.getComponent();
8204                if (comp == null) {
8205                    throw new IllegalArgumentException("Intent " + intent
8206                            + " must specify explicit component");
8207                }
8208                if (thumbnail.getWidth() != mThumbnailWidth
8209                        || thumbnail.getHeight() != mThumbnailHeight) {
8210                    throw new IllegalArgumentException("Bad thumbnail size: got "
8211                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8212                            + mThumbnailWidth + "x" + mThumbnailHeight);
8213                }
8214                if (intent.getSelector() != null) {
8215                    intent.setSelector(null);
8216                }
8217                if (intent.getSourceBounds() != null) {
8218                    intent.setSourceBounds(null);
8219                }
8220                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8221                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8222                        // The caller has added this as an auto-remove task...  that makes no
8223                        // sense, so turn off auto-remove.
8224                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8225                    }
8226                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8227                    // Must be a new task.
8228                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8229                }
8230                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8231                    mLastAddedTaskActivity = null;
8232                }
8233                ActivityInfo ainfo = mLastAddedTaskActivity;
8234                if (ainfo == null) {
8235                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8236                            comp, 0, UserHandle.getUserId(callingUid));
8237                    if (ainfo.applicationInfo.uid != callingUid) {
8238                        throw new SecurityException(
8239                                "Can't add task for another application: target uid="
8240                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8241                    }
8242                }
8243
8244                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8245                        intent, description);
8246
8247                int trimIdx = trimRecentsForTask(task, false);
8248                if (trimIdx >= 0) {
8249                    // If this would have caused a trim, then we'll abort because that
8250                    // means it would be added at the end of the list but then just removed.
8251                    return -1;
8252                }
8253
8254                final int N = mRecentTasks.size();
8255                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8256                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8257                    tr.removedFromRecents(mTaskPersister);
8258                }
8259
8260                task.inRecents = true;
8261                mRecentTasks.add(task);
8262                r.task.stack.addTask(task, false, false);
8263
8264                task.setLastThumbnail(thumbnail);
8265                task.freeLastThumbnail();
8266
8267                return task.taskId;
8268            }
8269        } finally {
8270            Binder.restoreCallingIdentity(callingIdent);
8271        }
8272    }
8273
8274    @Override
8275    public Point getAppTaskThumbnailSize() {
8276        synchronized (this) {
8277            return new Point(mThumbnailWidth,  mThumbnailHeight);
8278        }
8279    }
8280
8281    @Override
8282    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8283        synchronized (this) {
8284            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8285            if (r != null) {
8286                r.setTaskDescription(td);
8287                r.task.updateTaskDescription();
8288            }
8289        }
8290    }
8291
8292    @Override
8293    public Bitmap getTaskDescriptionIcon(String filename) {
8294        if (!FileUtils.isValidExtFilename(filename)
8295                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8296            throw new IllegalArgumentException("Bad filename: " + filename);
8297        }
8298        return mTaskPersister.getTaskDescriptionIcon(filename);
8299    }
8300
8301    @Override
8302    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8303            throws RemoteException {
8304        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8305                opts.getCustomInPlaceResId() == 0) {
8306            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8307                    "with valid animation");
8308        }
8309        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8310        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8311                opts.getCustomInPlaceResId());
8312        mWindowManager.executeAppTransition();
8313    }
8314
8315    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8316        mRecentTasks.remove(tr);
8317        tr.removedFromRecents(mTaskPersister);
8318        ComponentName component = tr.getBaseIntent().getComponent();
8319        if (component == null) {
8320            Slog.w(TAG, "No component for base intent of task: " + tr);
8321            return;
8322        }
8323
8324        if (!killProcess) {
8325            return;
8326        }
8327
8328        // Determine if the process(es) for this task should be killed.
8329        final String pkg = component.getPackageName();
8330        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8331        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8332        for (int i = 0; i < pmap.size(); i++) {
8333
8334            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8335            for (int j = 0; j < uids.size(); j++) {
8336                ProcessRecord proc = uids.valueAt(j);
8337                if (proc.userId != tr.userId) {
8338                    // Don't kill process for a different user.
8339                    continue;
8340                }
8341                if (proc == mHomeProcess) {
8342                    // Don't kill the home process along with tasks from the same package.
8343                    continue;
8344                }
8345                if (!proc.pkgList.containsKey(pkg)) {
8346                    // Don't kill process that is not associated with this task.
8347                    continue;
8348                }
8349
8350                for (int k = 0; k < proc.activities.size(); k++) {
8351                    TaskRecord otherTask = proc.activities.get(k).task;
8352                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8353                        // Don't kill process(es) that has an activity in a different task that is
8354                        // also in recents.
8355                        return;
8356                    }
8357                }
8358
8359                // Add process to kill list.
8360                procsToKill.add(proc);
8361            }
8362        }
8363
8364        // Find any running services associated with this app and stop if needed.
8365        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8366
8367        // Kill the running processes.
8368        for (int i = 0; i < procsToKill.size(); i++) {
8369            ProcessRecord pr = procsToKill.get(i);
8370            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8371                pr.kill("remove task", true);
8372            } else {
8373                pr.waitingToKill = "remove task";
8374            }
8375        }
8376    }
8377
8378    /**
8379     * Removes the task with the specified task id.
8380     *
8381     * @param taskId Identifier of the task to be removed.
8382     * @param killProcess Kill any process associated with the task if possible.
8383     * @return Returns true if the given task was found and removed.
8384     */
8385    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8386        TaskRecord tr = recentTaskForIdLocked(taskId);
8387        if (tr != null) {
8388            tr.removeTaskActivitiesLocked();
8389            cleanUpRemovedTaskLocked(tr, killProcess);
8390            if (tr.isPersistable) {
8391                notifyTaskPersisterLocked(null, true);
8392            }
8393            return true;
8394        }
8395        Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8396        return false;
8397    }
8398
8399    @Override
8400    public boolean removeTask(int taskId) {
8401        synchronized (this) {
8402            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8403                    "removeTask()");
8404            long ident = Binder.clearCallingIdentity();
8405            try {
8406                return removeTaskByIdLocked(taskId, true);
8407            } finally {
8408                Binder.restoreCallingIdentity(ident);
8409            }
8410        }
8411    }
8412
8413    /**
8414     * TODO: Add mController hook
8415     */
8416    @Override
8417    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8418        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8419                "moveTaskToFront()");
8420
8421        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8422        synchronized(this) {
8423            moveTaskToFrontLocked(taskId, flags, options);
8424        }
8425    }
8426
8427    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8428        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8429                Binder.getCallingUid(), -1, -1, "Task to front")) {
8430            ActivityOptions.abort(options);
8431            return;
8432        }
8433        final long origId = Binder.clearCallingIdentity();
8434        try {
8435            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8436            if (task == null) {
8437                return;
8438            }
8439            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8440                mStackSupervisor.showLockTaskToast();
8441                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8442                return;
8443            }
8444            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8445            if (prev != null && prev.isRecentsActivity()) {
8446                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8447            }
8448            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8449        } finally {
8450            Binder.restoreCallingIdentity(origId);
8451        }
8452        ActivityOptions.abort(options);
8453    }
8454
8455    @Override
8456    public void moveTaskToBack(int taskId) {
8457        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8458                "moveTaskToBack()");
8459
8460        synchronized(this) {
8461            TaskRecord tr = recentTaskForIdLocked(taskId);
8462            if (tr != null) {
8463                if (tr == mStackSupervisor.mLockTaskModeTask) {
8464                    mStackSupervisor.showLockTaskToast();
8465                    return;
8466                }
8467                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8468                ActivityStack stack = tr.stack;
8469                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8470                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8471                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8472                        return;
8473                    }
8474                }
8475                final long origId = Binder.clearCallingIdentity();
8476                try {
8477                    stack.moveTaskToBackLocked(taskId, null);
8478                } finally {
8479                    Binder.restoreCallingIdentity(origId);
8480                }
8481            }
8482        }
8483    }
8484
8485    /**
8486     * Moves an activity, and all of the other activities within the same task, to the bottom
8487     * of the history stack.  The activity's order within the task is unchanged.
8488     *
8489     * @param token A reference to the activity we wish to move
8490     * @param nonRoot If false then this only works if the activity is the root
8491     *                of a task; if true it will work for any activity in a task.
8492     * @return Returns true if the move completed, false if not.
8493     */
8494    @Override
8495    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8496        enforceNotIsolatedCaller("moveActivityTaskToBack");
8497        synchronized(this) {
8498            final long origId = Binder.clearCallingIdentity();
8499            try {
8500                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8501                if (taskId >= 0) {
8502                    if ((mStackSupervisor.mLockTaskModeTask != null)
8503                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8504                        mStackSupervisor.showLockTaskToast();
8505                        return false;
8506                    }
8507                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8508                }
8509            } finally {
8510                Binder.restoreCallingIdentity(origId);
8511            }
8512        }
8513        return false;
8514    }
8515
8516    @Override
8517    public void moveTaskBackwards(int task) {
8518        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8519                "moveTaskBackwards()");
8520
8521        synchronized(this) {
8522            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8523                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8524                return;
8525            }
8526            final long origId = Binder.clearCallingIdentity();
8527            moveTaskBackwardsLocked(task);
8528            Binder.restoreCallingIdentity(origId);
8529        }
8530    }
8531
8532    private final void moveTaskBackwardsLocked(int task) {
8533        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8534    }
8535
8536    @Override
8537    public IBinder getHomeActivityToken() throws RemoteException {
8538        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8539                "getHomeActivityToken()");
8540        synchronized (this) {
8541            return mStackSupervisor.getHomeActivityToken();
8542        }
8543    }
8544
8545    @Override
8546    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8547            IActivityContainerCallback callback) throws RemoteException {
8548        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8549                "createActivityContainer()");
8550        synchronized (this) {
8551            if (parentActivityToken == null) {
8552                throw new IllegalArgumentException("parent token must not be null");
8553            }
8554            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8555            if (r == null) {
8556                return null;
8557            }
8558            if (callback == null) {
8559                throw new IllegalArgumentException("callback must not be null");
8560            }
8561            return mStackSupervisor.createActivityContainer(r, callback);
8562        }
8563    }
8564
8565    @Override
8566    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8567        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8568                "deleteActivityContainer()");
8569        synchronized (this) {
8570            mStackSupervisor.deleteActivityContainer(container);
8571        }
8572    }
8573
8574    @Override
8575    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8576            throws RemoteException {
8577        synchronized (this) {
8578            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8579            if (stack != null) {
8580                return stack.mActivityContainer;
8581            }
8582            return null;
8583        }
8584    }
8585
8586    @Override
8587    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8588        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8589                "moveTaskToStack()");
8590        if (stackId == HOME_STACK_ID) {
8591            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8592                    new RuntimeException("here").fillInStackTrace());
8593        }
8594        synchronized (this) {
8595            long ident = Binder.clearCallingIdentity();
8596            try {
8597                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8598                        + stackId + " toTop=" + toTop);
8599                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8600            } finally {
8601                Binder.restoreCallingIdentity(ident);
8602            }
8603        }
8604    }
8605
8606    @Override
8607    public void resizeStack(int stackBoxId, Rect bounds) {
8608        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8609                "resizeStackBox()");
8610        long ident = Binder.clearCallingIdentity();
8611        try {
8612            mWindowManager.resizeStack(stackBoxId, bounds);
8613        } finally {
8614            Binder.restoreCallingIdentity(ident);
8615        }
8616    }
8617
8618    @Override
8619    public List<StackInfo> getAllStackInfos() {
8620        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8621                "getAllStackInfos()");
8622        long ident = Binder.clearCallingIdentity();
8623        try {
8624            synchronized (this) {
8625                return mStackSupervisor.getAllStackInfosLocked();
8626            }
8627        } finally {
8628            Binder.restoreCallingIdentity(ident);
8629        }
8630    }
8631
8632    @Override
8633    public StackInfo getStackInfo(int stackId) {
8634        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8635                "getStackInfo()");
8636        long ident = Binder.clearCallingIdentity();
8637        try {
8638            synchronized (this) {
8639                return mStackSupervisor.getStackInfoLocked(stackId);
8640            }
8641        } finally {
8642            Binder.restoreCallingIdentity(ident);
8643        }
8644    }
8645
8646    @Override
8647    public boolean isInHomeStack(int taskId) {
8648        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8649                "getStackInfo()");
8650        long ident = Binder.clearCallingIdentity();
8651        try {
8652            synchronized (this) {
8653                TaskRecord tr = recentTaskForIdLocked(taskId);
8654                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8655            }
8656        } finally {
8657            Binder.restoreCallingIdentity(ident);
8658        }
8659    }
8660
8661    @Override
8662    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8663        synchronized(this) {
8664            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8665        }
8666    }
8667
8668    private boolean isLockTaskAuthorized(String pkg) {
8669        final DevicePolicyManager dpm = (DevicePolicyManager)
8670                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8671        try {
8672            int uid = mContext.getPackageManager().getPackageUid(pkg,
8673                    Binder.getCallingUserHandle().getIdentifier());
8674            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8675        } catch (NameNotFoundException e) {
8676            return false;
8677        }
8678    }
8679
8680    void startLockTaskMode(TaskRecord task) {
8681        final String pkg;
8682        synchronized (this) {
8683            pkg = task.intent.getComponent().getPackageName();
8684        }
8685        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8686        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8687            final TaskRecord taskRecord = task;
8688            mHandler.post(new Runnable() {
8689                @Override
8690                public void run() {
8691                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8692                }
8693            });
8694            return;
8695        }
8696        long ident = Binder.clearCallingIdentity();
8697        try {
8698            synchronized (this) {
8699                // Since we lost lock on task, make sure it is still there.
8700                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8701                if (task != null) {
8702                    if (!isSystemInitiated
8703                            && ((mStackSupervisor.getFocusedStack() == null)
8704                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8705                        throw new IllegalArgumentException("Invalid task, not in foreground");
8706                    }
8707                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8708                }
8709            }
8710        } finally {
8711            Binder.restoreCallingIdentity(ident);
8712        }
8713    }
8714
8715    @Override
8716    public void startLockTaskMode(int taskId) {
8717        final TaskRecord task;
8718        long ident = Binder.clearCallingIdentity();
8719        try {
8720            synchronized (this) {
8721                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8722            }
8723        } finally {
8724            Binder.restoreCallingIdentity(ident);
8725        }
8726        if (task != null) {
8727            startLockTaskMode(task);
8728        }
8729    }
8730
8731    @Override
8732    public void startLockTaskMode(IBinder token) {
8733        final TaskRecord task;
8734        long ident = Binder.clearCallingIdentity();
8735        try {
8736            synchronized (this) {
8737                final ActivityRecord r = ActivityRecord.forToken(token);
8738                if (r == null) {
8739                    return;
8740                }
8741                task = r.task;
8742            }
8743        } finally {
8744            Binder.restoreCallingIdentity(ident);
8745        }
8746        if (task != null) {
8747            startLockTaskMode(task);
8748        }
8749    }
8750
8751    @Override
8752    public void startLockTaskModeOnCurrent() throws RemoteException {
8753        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8754                "startLockTaskModeOnCurrent");
8755        ActivityRecord r = null;
8756        synchronized (this) {
8757            r = mStackSupervisor.topRunningActivityLocked();
8758        }
8759        startLockTaskMode(r.task);
8760    }
8761
8762    @Override
8763    public void stopLockTaskMode() {
8764        // Verify that the user matches the package of the intent for the TaskRecord
8765        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8766        // and stopLockTaskMode.
8767        final int callingUid = Binder.getCallingUid();
8768        if (callingUid != Process.SYSTEM_UID) {
8769            try {
8770                String pkg =
8771                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8772                int uid = mContext.getPackageManager().getPackageUid(pkg,
8773                        Binder.getCallingUserHandle().getIdentifier());
8774                if (uid != callingUid) {
8775                    throw new SecurityException("Invalid uid, expected " + uid);
8776                }
8777            } catch (NameNotFoundException e) {
8778                Log.d(TAG, "stopLockTaskMode " + e);
8779                return;
8780            }
8781        }
8782        long ident = Binder.clearCallingIdentity();
8783        try {
8784            Log.d(TAG, "stopLockTaskMode");
8785            // Stop lock task
8786            synchronized (this) {
8787                mStackSupervisor.setLockTaskModeLocked(null, false);
8788            }
8789        } finally {
8790            Binder.restoreCallingIdentity(ident);
8791        }
8792    }
8793
8794    @Override
8795    public void stopLockTaskModeOnCurrent() throws RemoteException {
8796        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8797                "stopLockTaskModeOnCurrent");
8798        long ident = Binder.clearCallingIdentity();
8799        try {
8800            stopLockTaskMode();
8801        } finally {
8802            Binder.restoreCallingIdentity(ident);
8803        }
8804    }
8805
8806    @Override
8807    public boolean isInLockTaskMode() {
8808        synchronized (this) {
8809            return mStackSupervisor.isInLockTaskMode();
8810        }
8811    }
8812
8813    // =========================================================
8814    // CONTENT PROVIDERS
8815    // =========================================================
8816
8817    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8818        List<ProviderInfo> providers = null;
8819        try {
8820            providers = AppGlobals.getPackageManager().
8821                queryContentProviders(app.processName, app.uid,
8822                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8823        } catch (RemoteException ex) {
8824        }
8825        if (DEBUG_MU)
8826            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8827        int userId = app.userId;
8828        if (providers != null) {
8829            int N = providers.size();
8830            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8831            for (int i=0; i<N; i++) {
8832                ProviderInfo cpi =
8833                    (ProviderInfo)providers.get(i);
8834                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8835                        cpi.name, cpi.flags);
8836                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8837                    // This is a singleton provider, but a user besides the
8838                    // default user is asking to initialize a process it runs
8839                    // in...  well, no, it doesn't actually run in this process,
8840                    // it runs in the process of the default user.  Get rid of it.
8841                    providers.remove(i);
8842                    N--;
8843                    i--;
8844                    continue;
8845                }
8846
8847                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8848                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8849                if (cpr == null) {
8850                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8851                    mProviderMap.putProviderByClass(comp, cpr);
8852                }
8853                if (DEBUG_MU)
8854                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8855                app.pubProviders.put(cpi.name, cpr);
8856                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8857                    // Don't add this if it is a platform component that is marked
8858                    // to run in multiple processes, because this is actually
8859                    // part of the framework so doesn't make sense to track as a
8860                    // separate apk in the process.
8861                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8862                            mProcessStats);
8863                }
8864                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8865            }
8866        }
8867        return providers;
8868    }
8869
8870    /**
8871     * Check if {@link ProcessRecord} has a possible chance at accessing the
8872     * given {@link ProviderInfo}. Final permission checking is always done
8873     * in {@link ContentProvider}.
8874     */
8875    private final String checkContentProviderPermissionLocked(
8876            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8877        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8878        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8879        boolean checkedGrants = false;
8880        if (checkUser) {
8881            // Looking for cross-user grants before enforcing the typical cross-users permissions
8882            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8883            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8884                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8885                    return null;
8886                }
8887                checkedGrants = true;
8888            }
8889            userId = handleIncomingUser(callingPid, callingUid, userId,
8890                    false, ALLOW_NON_FULL,
8891                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8892            if (userId != tmpTargetUserId) {
8893                // When we actually went to determine the final targer user ID, this ended
8894                // up different than our initial check for the authority.  This is because
8895                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8896                // SELF.  So we need to re-check the grants again.
8897                checkedGrants = false;
8898            }
8899        }
8900        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8901                cpi.applicationInfo.uid, cpi.exported)
8902                == PackageManager.PERMISSION_GRANTED) {
8903            return null;
8904        }
8905        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8906                cpi.applicationInfo.uid, cpi.exported)
8907                == PackageManager.PERMISSION_GRANTED) {
8908            return null;
8909        }
8910
8911        PathPermission[] pps = cpi.pathPermissions;
8912        if (pps != null) {
8913            int i = pps.length;
8914            while (i > 0) {
8915                i--;
8916                PathPermission pp = pps[i];
8917                String pprperm = pp.getReadPermission();
8918                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8919                        cpi.applicationInfo.uid, cpi.exported)
8920                        == PackageManager.PERMISSION_GRANTED) {
8921                    return null;
8922                }
8923                String ppwperm = pp.getWritePermission();
8924                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8925                        cpi.applicationInfo.uid, cpi.exported)
8926                        == PackageManager.PERMISSION_GRANTED) {
8927                    return null;
8928                }
8929            }
8930        }
8931        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8932            return null;
8933        }
8934
8935        String msg;
8936        if (!cpi.exported) {
8937            msg = "Permission Denial: opening provider " + cpi.name
8938                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8939                    + ", uid=" + callingUid + ") that is not exported from uid "
8940                    + cpi.applicationInfo.uid;
8941        } else {
8942            msg = "Permission Denial: opening provider " + cpi.name
8943                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8944                    + ", uid=" + callingUid + ") requires "
8945                    + cpi.readPermission + " or " + cpi.writePermission;
8946        }
8947        Slog.w(TAG, msg);
8948        return msg;
8949    }
8950
8951    /**
8952     * Returns if the ContentProvider has granted a uri to callingUid
8953     */
8954    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8955        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8956        if (perms != null) {
8957            for (int i=perms.size()-1; i>=0; i--) {
8958                GrantUri grantUri = perms.keyAt(i);
8959                if (grantUri.sourceUserId == userId || !checkUser) {
8960                    if (matchesProvider(grantUri.uri, cpi)) {
8961                        return true;
8962                    }
8963                }
8964            }
8965        }
8966        return false;
8967    }
8968
8969    /**
8970     * Returns true if the uri authority is one of the authorities specified in the provider.
8971     */
8972    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8973        String uriAuth = uri.getAuthority();
8974        String cpiAuth = cpi.authority;
8975        if (cpiAuth.indexOf(';') == -1) {
8976            return cpiAuth.equals(uriAuth);
8977        }
8978        String[] cpiAuths = cpiAuth.split(";");
8979        int length = cpiAuths.length;
8980        for (int i = 0; i < length; i++) {
8981            if (cpiAuths[i].equals(uriAuth)) return true;
8982        }
8983        return false;
8984    }
8985
8986    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8987            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8988        if (r != null) {
8989            for (int i=0; i<r.conProviders.size(); i++) {
8990                ContentProviderConnection conn = r.conProviders.get(i);
8991                if (conn.provider == cpr) {
8992                    if (DEBUG_PROVIDER) Slog.v(TAG,
8993                            "Adding provider requested by "
8994                            + r.processName + " from process "
8995                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8996                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8997                    if (stable) {
8998                        conn.stableCount++;
8999                        conn.numStableIncs++;
9000                    } else {
9001                        conn.unstableCount++;
9002                        conn.numUnstableIncs++;
9003                    }
9004                    return conn;
9005                }
9006            }
9007            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9008            if (stable) {
9009                conn.stableCount = 1;
9010                conn.numStableIncs = 1;
9011            } else {
9012                conn.unstableCount = 1;
9013                conn.numUnstableIncs = 1;
9014            }
9015            cpr.connections.add(conn);
9016            r.conProviders.add(conn);
9017            return conn;
9018        }
9019        cpr.addExternalProcessHandleLocked(externalProcessToken);
9020        return null;
9021    }
9022
9023    boolean decProviderCountLocked(ContentProviderConnection conn,
9024            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9025        if (conn != null) {
9026            cpr = conn.provider;
9027            if (DEBUG_PROVIDER) Slog.v(TAG,
9028                    "Removing provider requested by "
9029                    + conn.client.processName + " from process "
9030                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9031                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9032            if (stable) {
9033                conn.stableCount--;
9034            } else {
9035                conn.unstableCount--;
9036            }
9037            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9038                cpr.connections.remove(conn);
9039                conn.client.conProviders.remove(conn);
9040                return true;
9041            }
9042            return false;
9043        }
9044        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9045        return false;
9046    }
9047
9048    private void checkTime(long startTime, String where) {
9049        long now = SystemClock.elapsedRealtime();
9050        if ((now-startTime) > 1000) {
9051            // If we are taking more than a second, log about it.
9052            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9053        }
9054    }
9055
9056    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9057            String name, IBinder token, boolean stable, int userId) {
9058        ContentProviderRecord cpr;
9059        ContentProviderConnection conn = null;
9060        ProviderInfo cpi = null;
9061
9062        synchronized(this) {
9063            long startTime = SystemClock.elapsedRealtime();
9064
9065            ProcessRecord r = null;
9066            if (caller != null) {
9067                r = getRecordForAppLocked(caller);
9068                if (r == null) {
9069                    throw new SecurityException(
9070                            "Unable to find app for caller " + caller
9071                          + " (pid=" + Binder.getCallingPid()
9072                          + ") when getting content provider " + name);
9073                }
9074            }
9075
9076            boolean checkCrossUser = true;
9077
9078            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9079
9080            // First check if this content provider has been published...
9081            cpr = mProviderMap.getProviderByName(name, userId);
9082            // If that didn't work, check if it exists for user 0 and then
9083            // verify that it's a singleton provider before using it.
9084            if (cpr == null && userId != UserHandle.USER_OWNER) {
9085                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9086                if (cpr != null) {
9087                    cpi = cpr.info;
9088                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9089                            cpi.name, cpi.flags)
9090                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9091                        userId = UserHandle.USER_OWNER;
9092                        checkCrossUser = false;
9093                    } else {
9094                        cpr = null;
9095                        cpi = null;
9096                    }
9097                }
9098            }
9099
9100            boolean providerRunning = cpr != null;
9101            if (providerRunning) {
9102                cpi = cpr.info;
9103                String msg;
9104                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9105                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9106                        != null) {
9107                    throw new SecurityException(msg);
9108                }
9109                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9110
9111                if (r != null && cpr.canRunHere(r)) {
9112                    // This provider has been published or is in the process
9113                    // of being published...  but it is also allowed to run
9114                    // in the caller's process, so don't make a connection
9115                    // and just let the caller instantiate its own instance.
9116                    ContentProviderHolder holder = cpr.newHolder(null);
9117                    // don't give caller the provider object, it needs
9118                    // to make its own.
9119                    holder.provider = null;
9120                    return holder;
9121                }
9122
9123                final long origId = Binder.clearCallingIdentity();
9124
9125                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9126
9127                // In this case the provider instance already exists, so we can
9128                // return it right away.
9129                conn = incProviderCountLocked(r, cpr, token, stable);
9130                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9131                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9132                        // If this is a perceptible app accessing the provider,
9133                        // make sure to count it as being accessed and thus
9134                        // back up on the LRU list.  This is good because
9135                        // content providers are often expensive to start.
9136                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9137                        updateLruProcessLocked(cpr.proc, false, null);
9138                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9139                    }
9140                }
9141
9142                if (cpr.proc != null) {
9143                    if (false) {
9144                        if (cpr.name.flattenToShortString().equals(
9145                                "com.android.providers.calendar/.CalendarProvider2")) {
9146                            Slog.v(TAG, "****************** KILLING "
9147                                + cpr.name.flattenToShortString());
9148                            Process.killProcess(cpr.proc.pid);
9149                        }
9150                    }
9151                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9152                    boolean success = updateOomAdjLocked(cpr.proc);
9153                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9154                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9155                    // NOTE: there is still a race here where a signal could be
9156                    // pending on the process even though we managed to update its
9157                    // adj level.  Not sure what to do about this, but at least
9158                    // the race is now smaller.
9159                    if (!success) {
9160                        // Uh oh...  it looks like the provider's process
9161                        // has been killed on us.  We need to wait for a new
9162                        // process to be started, and make sure its death
9163                        // doesn't kill our process.
9164                        Slog.i(TAG,
9165                                "Existing provider " + cpr.name.flattenToShortString()
9166                                + " is crashing; detaching " + r);
9167                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9168                        checkTime(startTime, "getContentProviderImpl: before appDied");
9169                        appDiedLocked(cpr.proc);
9170                        checkTime(startTime, "getContentProviderImpl: after appDied");
9171                        if (!lastRef) {
9172                            // This wasn't the last ref our process had on
9173                            // the provider...  we have now been killed, bail.
9174                            return null;
9175                        }
9176                        providerRunning = false;
9177                        conn = null;
9178                    }
9179                }
9180
9181                Binder.restoreCallingIdentity(origId);
9182            }
9183
9184            boolean singleton;
9185            if (!providerRunning) {
9186                try {
9187                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9188                    cpi = AppGlobals.getPackageManager().
9189                        resolveContentProvider(name,
9190                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9191                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9192                } catch (RemoteException ex) {
9193                }
9194                if (cpi == null) {
9195                    return null;
9196                }
9197                // If the provider is a singleton AND
9198                // (it's a call within the same user || the provider is a
9199                // privileged app)
9200                // Then allow connecting to the singleton provider
9201                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9202                        cpi.name, cpi.flags)
9203                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9204                if (singleton) {
9205                    userId = UserHandle.USER_OWNER;
9206                }
9207                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9208                checkTime(startTime, "getContentProviderImpl: got app info for user");
9209
9210                String msg;
9211                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9212                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9213                        != null) {
9214                    throw new SecurityException(msg);
9215                }
9216                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9217
9218                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9219                        && !cpi.processName.equals("system")) {
9220                    // If this content provider does not run in the system
9221                    // process, and the system is not yet ready to run other
9222                    // processes, then fail fast instead of hanging.
9223                    throw new IllegalArgumentException(
9224                            "Attempt to launch content provider before system ready");
9225                }
9226
9227                // Make sure that the user who owns this provider is started.  If not,
9228                // we don't want to allow it to run.
9229                if (mStartedUsers.get(userId) == null) {
9230                    Slog.w(TAG, "Unable to launch app "
9231                            + cpi.applicationInfo.packageName + "/"
9232                            + cpi.applicationInfo.uid + " for provider "
9233                            + name + ": user " + userId + " is stopped");
9234                    return null;
9235                }
9236
9237                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9238                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9239                cpr = mProviderMap.getProviderByClass(comp, userId);
9240                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9241                final boolean firstClass = cpr == null;
9242                if (firstClass) {
9243                    final long ident = Binder.clearCallingIdentity();
9244                    try {
9245                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9246                        ApplicationInfo ai =
9247                            AppGlobals.getPackageManager().
9248                                getApplicationInfo(
9249                                        cpi.applicationInfo.packageName,
9250                                        STOCK_PM_FLAGS, userId);
9251                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9252                        if (ai == null) {
9253                            Slog.w(TAG, "No package info for content provider "
9254                                    + cpi.name);
9255                            return null;
9256                        }
9257                        ai = getAppInfoForUser(ai, userId);
9258                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9259                    } catch (RemoteException ex) {
9260                        // pm is in same process, this will never happen.
9261                    } finally {
9262                        Binder.restoreCallingIdentity(ident);
9263                    }
9264                }
9265
9266                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9267
9268                if (r != null && cpr.canRunHere(r)) {
9269                    // If this is a multiprocess provider, then just return its
9270                    // info and allow the caller to instantiate it.  Only do
9271                    // this if the provider is the same user as the caller's
9272                    // process, or can run as root (so can be in any process).
9273                    return cpr.newHolder(null);
9274                }
9275
9276                if (DEBUG_PROVIDER) {
9277                    RuntimeException e = new RuntimeException("here");
9278                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9279                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9280                }
9281
9282                // This is single process, and our app is now connecting to it.
9283                // See if we are already in the process of launching this
9284                // provider.
9285                final int N = mLaunchingProviders.size();
9286                int i;
9287                for (i=0; i<N; i++) {
9288                    if (mLaunchingProviders.get(i) == cpr) {
9289                        break;
9290                    }
9291                }
9292
9293                // If the provider is not already being launched, then get it
9294                // started.
9295                if (i >= N) {
9296                    final long origId = Binder.clearCallingIdentity();
9297
9298                    try {
9299                        // Content provider is now in use, its package can't be stopped.
9300                        try {
9301                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9302                            AppGlobals.getPackageManager().setPackageStoppedState(
9303                                    cpr.appInfo.packageName, false, userId);
9304                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9305                        } catch (RemoteException e) {
9306                        } catch (IllegalArgumentException e) {
9307                            Slog.w(TAG, "Failed trying to unstop package "
9308                                    + cpr.appInfo.packageName + ": " + e);
9309                        }
9310
9311                        // Use existing process if already started
9312                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9313                        ProcessRecord proc = getProcessRecordLocked(
9314                                cpi.processName, cpr.appInfo.uid, false);
9315                        if (proc != null && proc.thread != null) {
9316                            if (DEBUG_PROVIDER) {
9317                                Slog.d(TAG, "Installing in existing process " + proc);
9318                            }
9319                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9320                            proc.pubProviders.put(cpi.name, cpr);
9321                            try {
9322                                proc.thread.scheduleInstallProvider(cpi);
9323                            } catch (RemoteException e) {
9324                            }
9325                        } else {
9326                            checkTime(startTime, "getContentProviderImpl: before start process");
9327                            proc = startProcessLocked(cpi.processName,
9328                                    cpr.appInfo, false, 0, "content provider",
9329                                    new ComponentName(cpi.applicationInfo.packageName,
9330                                            cpi.name), false, false, false);
9331                            checkTime(startTime, "getContentProviderImpl: after start process");
9332                            if (proc == null) {
9333                                Slog.w(TAG, "Unable to launch app "
9334                                        + cpi.applicationInfo.packageName + "/"
9335                                        + cpi.applicationInfo.uid + " for provider "
9336                                        + name + ": process is bad");
9337                                return null;
9338                            }
9339                        }
9340                        cpr.launchingApp = proc;
9341                        mLaunchingProviders.add(cpr);
9342                    } finally {
9343                        Binder.restoreCallingIdentity(origId);
9344                    }
9345                }
9346
9347                checkTime(startTime, "getContentProviderImpl: updating data structures");
9348
9349                // Make sure the provider is published (the same provider class
9350                // may be published under multiple names).
9351                if (firstClass) {
9352                    mProviderMap.putProviderByClass(comp, cpr);
9353                }
9354
9355                mProviderMap.putProviderByName(name, cpr);
9356                conn = incProviderCountLocked(r, cpr, token, stable);
9357                if (conn != null) {
9358                    conn.waiting = true;
9359                }
9360            }
9361            checkTime(startTime, "getContentProviderImpl: done!");
9362        }
9363
9364        // Wait for the provider to be published...
9365        synchronized (cpr) {
9366            while (cpr.provider == null) {
9367                if (cpr.launchingApp == null) {
9368                    Slog.w(TAG, "Unable to launch app "
9369                            + cpi.applicationInfo.packageName + "/"
9370                            + cpi.applicationInfo.uid + " for provider "
9371                            + name + ": launching app became null");
9372                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9373                            UserHandle.getUserId(cpi.applicationInfo.uid),
9374                            cpi.applicationInfo.packageName,
9375                            cpi.applicationInfo.uid, name);
9376                    return null;
9377                }
9378                try {
9379                    if (DEBUG_MU) {
9380                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9381                                + cpr.launchingApp);
9382                    }
9383                    if (conn != null) {
9384                        conn.waiting = true;
9385                    }
9386                    cpr.wait();
9387                } catch (InterruptedException ex) {
9388                } finally {
9389                    if (conn != null) {
9390                        conn.waiting = false;
9391                    }
9392                }
9393            }
9394        }
9395        return cpr != null ? cpr.newHolder(conn) : null;
9396    }
9397
9398    @Override
9399    public final ContentProviderHolder getContentProvider(
9400            IApplicationThread caller, String name, int userId, boolean stable) {
9401        enforceNotIsolatedCaller("getContentProvider");
9402        if (caller == null) {
9403            String msg = "null IApplicationThread when getting content provider "
9404                    + name;
9405            Slog.w(TAG, msg);
9406            throw new SecurityException(msg);
9407        }
9408        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9409        // with cross-user grant.
9410        return getContentProviderImpl(caller, name, null, stable, userId);
9411    }
9412
9413    public ContentProviderHolder getContentProviderExternal(
9414            String name, int userId, IBinder token) {
9415        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9416            "Do not have permission in call getContentProviderExternal()");
9417        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9418                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9419        return getContentProviderExternalUnchecked(name, token, userId);
9420    }
9421
9422    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9423            IBinder token, int userId) {
9424        return getContentProviderImpl(null, name, token, true, userId);
9425    }
9426
9427    /**
9428     * Drop a content provider from a ProcessRecord's bookkeeping
9429     */
9430    public void removeContentProvider(IBinder connection, boolean stable) {
9431        enforceNotIsolatedCaller("removeContentProvider");
9432        long ident = Binder.clearCallingIdentity();
9433        try {
9434            synchronized (this) {
9435                ContentProviderConnection conn;
9436                try {
9437                    conn = (ContentProviderConnection)connection;
9438                } catch (ClassCastException e) {
9439                    String msg ="removeContentProvider: " + connection
9440                            + " not a ContentProviderConnection";
9441                    Slog.w(TAG, msg);
9442                    throw new IllegalArgumentException(msg);
9443                }
9444                if (conn == null) {
9445                    throw new NullPointerException("connection is null");
9446                }
9447                if (decProviderCountLocked(conn, null, null, stable)) {
9448                    updateOomAdjLocked();
9449                }
9450            }
9451        } finally {
9452            Binder.restoreCallingIdentity(ident);
9453        }
9454    }
9455
9456    public void removeContentProviderExternal(String name, IBinder token) {
9457        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9458            "Do not have permission in call removeContentProviderExternal()");
9459        int userId = UserHandle.getCallingUserId();
9460        long ident = Binder.clearCallingIdentity();
9461        try {
9462            removeContentProviderExternalUnchecked(name, token, userId);
9463        } finally {
9464            Binder.restoreCallingIdentity(ident);
9465        }
9466    }
9467
9468    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9469        synchronized (this) {
9470            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9471            if(cpr == null) {
9472                //remove from mProvidersByClass
9473                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9474                return;
9475            }
9476
9477            //update content provider record entry info
9478            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9479            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9480            if (localCpr.hasExternalProcessHandles()) {
9481                if (localCpr.removeExternalProcessHandleLocked(token)) {
9482                    updateOomAdjLocked();
9483                } else {
9484                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9485                            + " with no external reference for token: "
9486                            + token + ".");
9487                }
9488            } else {
9489                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9490                        + " with no external references.");
9491            }
9492        }
9493    }
9494
9495    public final void publishContentProviders(IApplicationThread caller,
9496            List<ContentProviderHolder> providers) {
9497        if (providers == null) {
9498            return;
9499        }
9500
9501        enforceNotIsolatedCaller("publishContentProviders");
9502        synchronized (this) {
9503            final ProcessRecord r = getRecordForAppLocked(caller);
9504            if (DEBUG_MU)
9505                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9506            if (r == null) {
9507                throw new SecurityException(
9508                        "Unable to find app for caller " + caller
9509                      + " (pid=" + Binder.getCallingPid()
9510                      + ") when publishing content providers");
9511            }
9512
9513            final long origId = Binder.clearCallingIdentity();
9514
9515            final int N = providers.size();
9516            for (int i=0; i<N; i++) {
9517                ContentProviderHolder src = providers.get(i);
9518                if (src == null || src.info == null || src.provider == null) {
9519                    continue;
9520                }
9521                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9522                if (DEBUG_MU)
9523                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9524                if (dst != null) {
9525                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9526                    mProviderMap.putProviderByClass(comp, dst);
9527                    String names[] = dst.info.authority.split(";");
9528                    for (int j = 0; j < names.length; j++) {
9529                        mProviderMap.putProviderByName(names[j], dst);
9530                    }
9531
9532                    int NL = mLaunchingProviders.size();
9533                    int j;
9534                    for (j=0; j<NL; j++) {
9535                        if (mLaunchingProviders.get(j) == dst) {
9536                            mLaunchingProviders.remove(j);
9537                            j--;
9538                            NL--;
9539                        }
9540                    }
9541                    synchronized (dst) {
9542                        dst.provider = src.provider;
9543                        dst.proc = r;
9544                        dst.notifyAll();
9545                    }
9546                    updateOomAdjLocked(r);
9547                }
9548            }
9549
9550            Binder.restoreCallingIdentity(origId);
9551        }
9552    }
9553
9554    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9555        ContentProviderConnection conn;
9556        try {
9557            conn = (ContentProviderConnection)connection;
9558        } catch (ClassCastException e) {
9559            String msg ="refContentProvider: " + connection
9560                    + " not a ContentProviderConnection";
9561            Slog.w(TAG, msg);
9562            throw new IllegalArgumentException(msg);
9563        }
9564        if (conn == null) {
9565            throw new NullPointerException("connection is null");
9566        }
9567
9568        synchronized (this) {
9569            if (stable > 0) {
9570                conn.numStableIncs += stable;
9571            }
9572            stable = conn.stableCount + stable;
9573            if (stable < 0) {
9574                throw new IllegalStateException("stableCount < 0: " + stable);
9575            }
9576
9577            if (unstable > 0) {
9578                conn.numUnstableIncs += unstable;
9579            }
9580            unstable = conn.unstableCount + unstable;
9581            if (unstable < 0) {
9582                throw new IllegalStateException("unstableCount < 0: " + unstable);
9583            }
9584
9585            if ((stable+unstable) <= 0) {
9586                throw new IllegalStateException("ref counts can't go to zero here: stable="
9587                        + stable + " unstable=" + unstable);
9588            }
9589            conn.stableCount = stable;
9590            conn.unstableCount = unstable;
9591            return !conn.dead;
9592        }
9593    }
9594
9595    public void unstableProviderDied(IBinder connection) {
9596        ContentProviderConnection conn;
9597        try {
9598            conn = (ContentProviderConnection)connection;
9599        } catch (ClassCastException e) {
9600            String msg ="refContentProvider: " + connection
9601                    + " not a ContentProviderConnection";
9602            Slog.w(TAG, msg);
9603            throw new IllegalArgumentException(msg);
9604        }
9605        if (conn == null) {
9606            throw new NullPointerException("connection is null");
9607        }
9608
9609        // Safely retrieve the content provider associated with the connection.
9610        IContentProvider provider;
9611        synchronized (this) {
9612            provider = conn.provider.provider;
9613        }
9614
9615        if (provider == null) {
9616            // Um, yeah, we're way ahead of you.
9617            return;
9618        }
9619
9620        // Make sure the caller is being honest with us.
9621        if (provider.asBinder().pingBinder()) {
9622            // Er, no, still looks good to us.
9623            synchronized (this) {
9624                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9625                        + " says " + conn + " died, but we don't agree");
9626                return;
9627            }
9628        }
9629
9630        // Well look at that!  It's dead!
9631        synchronized (this) {
9632            if (conn.provider.provider != provider) {
9633                // But something changed...  good enough.
9634                return;
9635            }
9636
9637            ProcessRecord proc = conn.provider.proc;
9638            if (proc == null || proc.thread == null) {
9639                // Seems like the process is already cleaned up.
9640                return;
9641            }
9642
9643            // As far as we're concerned, this is just like receiving a
9644            // death notification...  just a bit prematurely.
9645            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9646                    + ") early provider death");
9647            final long ident = Binder.clearCallingIdentity();
9648            try {
9649                appDiedLocked(proc);
9650            } finally {
9651                Binder.restoreCallingIdentity(ident);
9652            }
9653        }
9654    }
9655
9656    @Override
9657    public void appNotRespondingViaProvider(IBinder connection) {
9658        enforceCallingPermission(
9659                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9660
9661        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9662        if (conn == null) {
9663            Slog.w(TAG, "ContentProviderConnection is null");
9664            return;
9665        }
9666
9667        final ProcessRecord host = conn.provider.proc;
9668        if (host == null) {
9669            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9670            return;
9671        }
9672
9673        final long token = Binder.clearCallingIdentity();
9674        try {
9675            appNotResponding(host, null, null, false, "ContentProvider not responding");
9676        } finally {
9677            Binder.restoreCallingIdentity(token);
9678        }
9679    }
9680
9681    public final void installSystemProviders() {
9682        List<ProviderInfo> providers;
9683        synchronized (this) {
9684            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9685            providers = generateApplicationProvidersLocked(app);
9686            if (providers != null) {
9687                for (int i=providers.size()-1; i>=0; i--) {
9688                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9689                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9690                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9691                                + ": not system .apk");
9692                        providers.remove(i);
9693                    }
9694                }
9695            }
9696        }
9697        if (providers != null) {
9698            mSystemThread.installSystemProviders(providers);
9699        }
9700
9701        mCoreSettingsObserver = new CoreSettingsObserver(this);
9702
9703        //mUsageStatsService.monitorPackages();
9704    }
9705
9706    /**
9707     * Allows apps to retrieve the MIME type of a URI.
9708     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9709     * users, then it does not need permission to access the ContentProvider.
9710     * Either, it needs cross-user uri grants.
9711     *
9712     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9713     *
9714     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9715     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9716     */
9717    public String getProviderMimeType(Uri uri, int userId) {
9718        enforceNotIsolatedCaller("getProviderMimeType");
9719        final String name = uri.getAuthority();
9720        int callingUid = Binder.getCallingUid();
9721        int callingPid = Binder.getCallingPid();
9722        long ident = 0;
9723        boolean clearedIdentity = false;
9724        userId = unsafeConvertIncomingUser(userId);
9725        if (canClearIdentity(callingPid, callingUid, userId)) {
9726            clearedIdentity = true;
9727            ident = Binder.clearCallingIdentity();
9728        }
9729        ContentProviderHolder holder = null;
9730        try {
9731            holder = getContentProviderExternalUnchecked(name, null, userId);
9732            if (holder != null) {
9733                return holder.provider.getType(uri);
9734            }
9735        } catch (RemoteException e) {
9736            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9737            return null;
9738        } finally {
9739            // We need to clear the identity to call removeContentProviderExternalUnchecked
9740            if (!clearedIdentity) {
9741                ident = Binder.clearCallingIdentity();
9742            }
9743            try {
9744                if (holder != null) {
9745                    removeContentProviderExternalUnchecked(name, null, userId);
9746                }
9747            } finally {
9748                Binder.restoreCallingIdentity(ident);
9749            }
9750        }
9751
9752        return null;
9753    }
9754
9755    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9756        if (UserHandle.getUserId(callingUid) == userId) {
9757            return true;
9758        }
9759        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9760                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9761                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9762                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9763                return true;
9764        }
9765        return false;
9766    }
9767
9768    // =========================================================
9769    // GLOBAL MANAGEMENT
9770    // =========================================================
9771
9772    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9773            boolean isolated, int isolatedUid) {
9774        String proc = customProcess != null ? customProcess : info.processName;
9775        BatteryStatsImpl.Uid.Proc ps = null;
9776        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9777        int uid = info.uid;
9778        if (isolated) {
9779            if (isolatedUid == 0) {
9780                int userId = UserHandle.getUserId(uid);
9781                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9782                while (true) {
9783                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9784                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9785                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9786                    }
9787                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9788                    mNextIsolatedProcessUid++;
9789                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9790                        // No process for this uid, use it.
9791                        break;
9792                    }
9793                    stepsLeft--;
9794                    if (stepsLeft <= 0) {
9795                        return null;
9796                    }
9797                }
9798            } else {
9799                // Special case for startIsolatedProcess (internal only), where
9800                // the uid of the isolated process is specified by the caller.
9801                uid = isolatedUid;
9802            }
9803        }
9804        return new ProcessRecord(stats, info, proc, uid);
9805    }
9806
9807    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9808            String abiOverride) {
9809        ProcessRecord app;
9810        if (!isolated) {
9811            app = getProcessRecordLocked(info.processName, info.uid, true);
9812        } else {
9813            app = null;
9814        }
9815
9816        if (app == null) {
9817            app = newProcessRecordLocked(info, null, isolated, 0);
9818            mProcessNames.put(info.processName, app.uid, app);
9819            if (isolated) {
9820                mIsolatedProcesses.put(app.uid, app);
9821            }
9822            updateLruProcessLocked(app, false, null);
9823            updateOomAdjLocked();
9824        }
9825
9826        // This package really, really can not be stopped.
9827        try {
9828            AppGlobals.getPackageManager().setPackageStoppedState(
9829                    info.packageName, false, UserHandle.getUserId(app.uid));
9830        } catch (RemoteException e) {
9831        } catch (IllegalArgumentException e) {
9832            Slog.w(TAG, "Failed trying to unstop package "
9833                    + info.packageName + ": " + e);
9834        }
9835
9836        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9837                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9838            app.persistent = true;
9839            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9840        }
9841        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9842            mPersistentStartingProcesses.add(app);
9843            startProcessLocked(app, "added application", app.processName, abiOverride,
9844                    null /* entryPoint */, null /* entryPointArgs */);
9845        }
9846
9847        return app;
9848    }
9849
9850    public void unhandledBack() {
9851        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9852                "unhandledBack()");
9853
9854        synchronized(this) {
9855            final long origId = Binder.clearCallingIdentity();
9856            try {
9857                getFocusedStack().unhandledBackLocked();
9858            } finally {
9859                Binder.restoreCallingIdentity(origId);
9860            }
9861        }
9862    }
9863
9864    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9865        enforceNotIsolatedCaller("openContentUri");
9866        final int userId = UserHandle.getCallingUserId();
9867        String name = uri.getAuthority();
9868        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9869        ParcelFileDescriptor pfd = null;
9870        if (cph != null) {
9871            // We record the binder invoker's uid in thread-local storage before
9872            // going to the content provider to open the file.  Later, in the code
9873            // that handles all permissions checks, we look for this uid and use
9874            // that rather than the Activity Manager's own uid.  The effect is that
9875            // we do the check against the caller's permissions even though it looks
9876            // to the content provider like the Activity Manager itself is making
9877            // the request.
9878            sCallerIdentity.set(new Identity(
9879                    Binder.getCallingPid(), Binder.getCallingUid()));
9880            try {
9881                pfd = cph.provider.openFile(null, uri, "r", null);
9882            } catch (FileNotFoundException e) {
9883                // do nothing; pfd will be returned null
9884            } finally {
9885                // Ensure that whatever happens, we clean up the identity state
9886                sCallerIdentity.remove();
9887            }
9888
9889            // We've got the fd now, so we're done with the provider.
9890            removeContentProviderExternalUnchecked(name, null, userId);
9891        } else {
9892            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9893        }
9894        return pfd;
9895    }
9896
9897    // Actually is sleeping or shutting down or whatever else in the future
9898    // is an inactive state.
9899    public boolean isSleepingOrShuttingDown() {
9900        return isSleeping() || mShuttingDown;
9901    }
9902
9903    public boolean isSleeping() {
9904        return mSleeping;
9905    }
9906
9907    void goingToSleep() {
9908        synchronized(this) {
9909            mWentToSleep = true;
9910            goToSleepIfNeededLocked();
9911        }
9912    }
9913
9914    void finishRunningVoiceLocked() {
9915        if (mRunningVoice) {
9916            mRunningVoice = false;
9917            goToSleepIfNeededLocked();
9918        }
9919    }
9920
9921    void goToSleepIfNeededLocked() {
9922        if (mWentToSleep && !mRunningVoice) {
9923            if (!mSleeping) {
9924                mSleeping = true;
9925                mStackSupervisor.goingToSleepLocked();
9926
9927                // Initialize the wake times of all processes.
9928                checkExcessivePowerUsageLocked(false);
9929                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9930                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9931                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9932            }
9933        }
9934    }
9935
9936    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9937        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9938            // Never persist the home stack.
9939            return;
9940        }
9941        mTaskPersister.wakeup(task, flush);
9942    }
9943
9944    @Override
9945    public boolean shutdown(int timeout) {
9946        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9947                != PackageManager.PERMISSION_GRANTED) {
9948            throw new SecurityException("Requires permission "
9949                    + android.Manifest.permission.SHUTDOWN);
9950        }
9951
9952        boolean timedout = false;
9953
9954        synchronized(this) {
9955            mShuttingDown = true;
9956            updateEventDispatchingLocked();
9957            timedout = mStackSupervisor.shutdownLocked(timeout);
9958        }
9959
9960        mAppOpsService.shutdown();
9961        if (mUsageStatsService != null) {
9962            mUsageStatsService.prepareShutdown();
9963        }
9964        mBatteryStatsService.shutdown();
9965        synchronized (this) {
9966            mProcessStats.shutdownLocked();
9967        }
9968        notifyTaskPersisterLocked(null, true);
9969
9970        return timedout;
9971    }
9972
9973    public final void activitySlept(IBinder token) {
9974        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9975
9976        final long origId = Binder.clearCallingIdentity();
9977
9978        synchronized (this) {
9979            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9980            if (r != null) {
9981                mStackSupervisor.activitySleptLocked(r);
9982            }
9983        }
9984
9985        Binder.restoreCallingIdentity(origId);
9986    }
9987
9988    private String lockScreenShownToString() {
9989        switch (mLockScreenShown) {
9990            case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
9991            case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
9992            case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
9993            default: return "Unknown=" + mLockScreenShown;
9994        }
9995    }
9996
9997    void logLockScreen(String msg) {
9998        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9999                " mLockScreenShown=" + lockScreenShownToString() + " mWentToSleep=" +
10000                mWentToSleep + " mSleeping=" + mSleeping);
10001    }
10002
10003    void comeOutOfSleepIfNeededLocked() {
10004        if ((!mWentToSleep && mLockScreenShown == LOCK_SCREEN_HIDDEN) || mRunningVoice) {
10005            if (mSleeping) {
10006                mSleeping = false;
10007                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10008            }
10009        }
10010    }
10011
10012    void wakingUp() {
10013        synchronized(this) {
10014            mWentToSleep = false;
10015            comeOutOfSleepIfNeededLocked();
10016        }
10017    }
10018
10019    void startRunningVoiceLocked() {
10020        if (!mRunningVoice) {
10021            mRunningVoice = true;
10022            comeOutOfSleepIfNeededLocked();
10023        }
10024    }
10025
10026    private void updateEventDispatchingLocked() {
10027        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10028    }
10029
10030    public void setLockScreenShown(boolean shown) {
10031        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10032                != PackageManager.PERMISSION_GRANTED) {
10033            throw new SecurityException("Requires permission "
10034                    + android.Manifest.permission.DEVICE_POWER);
10035        }
10036
10037        synchronized(this) {
10038            long ident = Binder.clearCallingIdentity();
10039            try {
10040                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10041                mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10042                comeOutOfSleepIfNeededLocked();
10043            } finally {
10044                Binder.restoreCallingIdentity(ident);
10045            }
10046        }
10047    }
10048
10049    @Override
10050    public void stopAppSwitches() {
10051        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10052                != PackageManager.PERMISSION_GRANTED) {
10053            throw new SecurityException("Requires permission "
10054                    + android.Manifest.permission.STOP_APP_SWITCHES);
10055        }
10056
10057        synchronized(this) {
10058            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10059                    + APP_SWITCH_DELAY_TIME;
10060            mDidAppSwitch = false;
10061            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10062            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10063            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10064        }
10065    }
10066
10067    public void resumeAppSwitches() {
10068        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10069                != PackageManager.PERMISSION_GRANTED) {
10070            throw new SecurityException("Requires permission "
10071                    + android.Manifest.permission.STOP_APP_SWITCHES);
10072        }
10073
10074        synchronized(this) {
10075            // Note that we don't execute any pending app switches... we will
10076            // let those wait until either the timeout, or the next start
10077            // activity request.
10078            mAppSwitchesAllowedTime = 0;
10079        }
10080    }
10081
10082    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10083            int callingPid, int callingUid, String name) {
10084        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10085            return true;
10086        }
10087
10088        int perm = checkComponentPermission(
10089                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10090                sourceUid, -1, true);
10091        if (perm == PackageManager.PERMISSION_GRANTED) {
10092            return true;
10093        }
10094
10095        // If the actual IPC caller is different from the logical source, then
10096        // also see if they are allowed to control app switches.
10097        if (callingUid != -1 && callingUid != sourceUid) {
10098            perm = checkComponentPermission(
10099                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10100                    callingUid, -1, true);
10101            if (perm == PackageManager.PERMISSION_GRANTED) {
10102                return true;
10103            }
10104        }
10105
10106        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10107        return false;
10108    }
10109
10110    public void setDebugApp(String packageName, boolean waitForDebugger,
10111            boolean persistent) {
10112        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10113                "setDebugApp()");
10114
10115        long ident = Binder.clearCallingIdentity();
10116        try {
10117            // Note that this is not really thread safe if there are multiple
10118            // callers into it at the same time, but that's not a situation we
10119            // care about.
10120            if (persistent) {
10121                final ContentResolver resolver = mContext.getContentResolver();
10122                Settings.Global.putString(
10123                    resolver, Settings.Global.DEBUG_APP,
10124                    packageName);
10125                Settings.Global.putInt(
10126                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10127                    waitForDebugger ? 1 : 0);
10128            }
10129
10130            synchronized (this) {
10131                if (!persistent) {
10132                    mOrigDebugApp = mDebugApp;
10133                    mOrigWaitForDebugger = mWaitForDebugger;
10134                }
10135                mDebugApp = packageName;
10136                mWaitForDebugger = waitForDebugger;
10137                mDebugTransient = !persistent;
10138                if (packageName != null) {
10139                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10140                            false, UserHandle.USER_ALL, "set debug app");
10141                }
10142            }
10143        } finally {
10144            Binder.restoreCallingIdentity(ident);
10145        }
10146    }
10147
10148    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10149        synchronized (this) {
10150            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10151            if (!isDebuggable) {
10152                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10153                    throw new SecurityException("Process not debuggable: " + app.packageName);
10154                }
10155            }
10156
10157            mOpenGlTraceApp = processName;
10158        }
10159    }
10160
10161    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10162        synchronized (this) {
10163            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10164            if (!isDebuggable) {
10165                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10166                    throw new SecurityException("Process not debuggable: " + app.packageName);
10167                }
10168            }
10169            mProfileApp = processName;
10170            mProfileFile = profilerInfo.profileFile;
10171            if (mProfileFd != null) {
10172                try {
10173                    mProfileFd.close();
10174                } catch (IOException e) {
10175                }
10176                mProfileFd = null;
10177            }
10178            mProfileFd = profilerInfo.profileFd;
10179            mSamplingInterval = profilerInfo.samplingInterval;
10180            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10181            mProfileType = 0;
10182        }
10183    }
10184
10185    @Override
10186    public void setAlwaysFinish(boolean enabled) {
10187        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10188                "setAlwaysFinish()");
10189
10190        Settings.Global.putInt(
10191                mContext.getContentResolver(),
10192                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10193
10194        synchronized (this) {
10195            mAlwaysFinishActivities = enabled;
10196        }
10197    }
10198
10199    @Override
10200    public void setActivityController(IActivityController controller) {
10201        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10202                "setActivityController()");
10203        synchronized (this) {
10204            mController = controller;
10205            Watchdog.getInstance().setActivityController(controller);
10206        }
10207    }
10208
10209    @Override
10210    public void setUserIsMonkey(boolean userIsMonkey) {
10211        synchronized (this) {
10212            synchronized (mPidsSelfLocked) {
10213                final int callingPid = Binder.getCallingPid();
10214                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10215                if (precessRecord == null) {
10216                    throw new SecurityException("Unknown process: " + callingPid);
10217                }
10218                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10219                    throw new SecurityException("Only an instrumentation process "
10220                            + "with a UiAutomation can call setUserIsMonkey");
10221                }
10222            }
10223            mUserIsMonkey = userIsMonkey;
10224        }
10225    }
10226
10227    @Override
10228    public boolean isUserAMonkey() {
10229        synchronized (this) {
10230            // If there is a controller also implies the user is a monkey.
10231            return (mUserIsMonkey || mController != null);
10232        }
10233    }
10234
10235    public void requestBugReport() {
10236        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10237        SystemProperties.set("ctl.start", "bugreport");
10238    }
10239
10240    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10241        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10242    }
10243
10244    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10245        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10246            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10247        }
10248        return KEY_DISPATCHING_TIMEOUT;
10249    }
10250
10251    @Override
10252    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10253        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10254                != PackageManager.PERMISSION_GRANTED) {
10255            throw new SecurityException("Requires permission "
10256                    + android.Manifest.permission.FILTER_EVENTS);
10257        }
10258        ProcessRecord proc;
10259        long timeout;
10260        synchronized (this) {
10261            synchronized (mPidsSelfLocked) {
10262                proc = mPidsSelfLocked.get(pid);
10263            }
10264            timeout = getInputDispatchingTimeoutLocked(proc);
10265        }
10266
10267        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10268            return -1;
10269        }
10270
10271        return timeout;
10272    }
10273
10274    /**
10275     * Handle input dispatching timeouts.
10276     * Returns whether input dispatching should be aborted or not.
10277     */
10278    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10279            final ActivityRecord activity, final ActivityRecord parent,
10280            final boolean aboveSystem, String reason) {
10281        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10282                != PackageManager.PERMISSION_GRANTED) {
10283            throw new SecurityException("Requires permission "
10284                    + android.Manifest.permission.FILTER_EVENTS);
10285        }
10286
10287        final String annotation;
10288        if (reason == null) {
10289            annotation = "Input dispatching timed out";
10290        } else {
10291            annotation = "Input dispatching timed out (" + reason + ")";
10292        }
10293
10294        if (proc != null) {
10295            synchronized (this) {
10296                if (proc.debugging) {
10297                    return false;
10298                }
10299
10300                if (mDidDexOpt) {
10301                    // Give more time since we were dexopting.
10302                    mDidDexOpt = false;
10303                    return false;
10304                }
10305
10306                if (proc.instrumentationClass != null) {
10307                    Bundle info = new Bundle();
10308                    info.putString("shortMsg", "keyDispatchingTimedOut");
10309                    info.putString("longMsg", annotation);
10310                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10311                    return true;
10312                }
10313            }
10314            mHandler.post(new Runnable() {
10315                @Override
10316                public void run() {
10317                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10318                }
10319            });
10320        }
10321
10322        return true;
10323    }
10324
10325    public Bundle getAssistContextExtras(int requestType) {
10326        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10327                UserHandle.getCallingUserId());
10328        if (pae == null) {
10329            return null;
10330        }
10331        synchronized (pae) {
10332            while (!pae.haveResult) {
10333                try {
10334                    pae.wait();
10335                } catch (InterruptedException e) {
10336                }
10337            }
10338            if (pae.result != null) {
10339                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10340            }
10341        }
10342        synchronized (this) {
10343            mPendingAssistExtras.remove(pae);
10344            mHandler.removeCallbacks(pae);
10345        }
10346        return pae.extras;
10347    }
10348
10349    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10350            int userHandle) {
10351        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10352                "getAssistContextExtras()");
10353        PendingAssistExtras pae;
10354        Bundle extras = new Bundle();
10355        synchronized (this) {
10356            ActivityRecord activity = getFocusedStack().mResumedActivity;
10357            if (activity == null) {
10358                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10359                return null;
10360            }
10361            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10362            if (activity.app == null || activity.app.thread == null) {
10363                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10364                return null;
10365            }
10366            if (activity.app.pid == Binder.getCallingPid()) {
10367                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10368                return null;
10369            }
10370            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10371            try {
10372                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10373                        requestType);
10374                mPendingAssistExtras.add(pae);
10375                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10376            } catch (RemoteException e) {
10377                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10378                return null;
10379            }
10380            return pae;
10381        }
10382    }
10383
10384    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10385        PendingAssistExtras pae = (PendingAssistExtras)token;
10386        synchronized (pae) {
10387            pae.result = extras;
10388            pae.haveResult = true;
10389            pae.notifyAll();
10390            if (pae.intent == null) {
10391                // Caller is just waiting for the result.
10392                return;
10393            }
10394        }
10395
10396        // We are now ready to launch the assist activity.
10397        synchronized (this) {
10398            boolean exists = mPendingAssistExtras.remove(pae);
10399            mHandler.removeCallbacks(pae);
10400            if (!exists) {
10401                // Timed out.
10402                return;
10403            }
10404        }
10405        pae.intent.replaceExtras(extras);
10406        if (pae.hint != null) {
10407            pae.intent.putExtra(pae.hint, true);
10408        }
10409        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10410                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10411                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10412        closeSystemDialogs("assist");
10413        try {
10414            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10415        } catch (ActivityNotFoundException e) {
10416            Slog.w(TAG, "No activity to handle assist action.", e);
10417        }
10418    }
10419
10420    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10421        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10422    }
10423
10424    public void registerProcessObserver(IProcessObserver observer) {
10425        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10426                "registerProcessObserver()");
10427        synchronized (this) {
10428            mProcessObservers.register(observer);
10429        }
10430    }
10431
10432    @Override
10433    public void unregisterProcessObserver(IProcessObserver observer) {
10434        synchronized (this) {
10435            mProcessObservers.unregister(observer);
10436        }
10437    }
10438
10439    @Override
10440    public boolean convertFromTranslucent(IBinder token) {
10441        final long origId = Binder.clearCallingIdentity();
10442        try {
10443            synchronized (this) {
10444                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10445                if (r == null) {
10446                    return false;
10447                }
10448                final boolean translucentChanged = r.changeWindowTranslucency(true);
10449                if (translucentChanged) {
10450                    r.task.stack.releaseBackgroundResources();
10451                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10452                }
10453                mWindowManager.setAppFullscreen(token, true);
10454                return translucentChanged;
10455            }
10456        } finally {
10457            Binder.restoreCallingIdentity(origId);
10458        }
10459    }
10460
10461    @Override
10462    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10463        final long origId = Binder.clearCallingIdentity();
10464        try {
10465            synchronized (this) {
10466                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10467                if (r == null) {
10468                    return false;
10469                }
10470                int index = r.task.mActivities.lastIndexOf(r);
10471                if (index > 0) {
10472                    ActivityRecord under = r.task.mActivities.get(index - 1);
10473                    under.returningOptions = options;
10474                }
10475                final boolean translucentChanged = r.changeWindowTranslucency(false);
10476                if (translucentChanged) {
10477                    r.task.stack.convertToTranslucent(r);
10478                }
10479                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10480                mWindowManager.setAppFullscreen(token, false);
10481                return translucentChanged;
10482            }
10483        } finally {
10484            Binder.restoreCallingIdentity(origId);
10485        }
10486    }
10487
10488    @Override
10489    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10490        final long origId = Binder.clearCallingIdentity();
10491        try {
10492            synchronized (this) {
10493                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10494                if (r != null) {
10495                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10496                }
10497            }
10498            return false;
10499        } finally {
10500            Binder.restoreCallingIdentity(origId);
10501        }
10502    }
10503
10504    @Override
10505    public boolean isBackgroundVisibleBehind(IBinder token) {
10506        final long origId = Binder.clearCallingIdentity();
10507        try {
10508            synchronized (this) {
10509                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10510                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10511                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10512                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10513                return visible;
10514            }
10515        } finally {
10516            Binder.restoreCallingIdentity(origId);
10517        }
10518    }
10519
10520    @Override
10521    public ActivityOptions getActivityOptions(IBinder token) {
10522        final long origId = Binder.clearCallingIdentity();
10523        try {
10524            synchronized (this) {
10525                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10526                if (r != null) {
10527                    final ActivityOptions activityOptions = r.pendingOptions;
10528                    r.pendingOptions = null;
10529                    return activityOptions;
10530                }
10531                return null;
10532            }
10533        } finally {
10534            Binder.restoreCallingIdentity(origId);
10535        }
10536    }
10537
10538    @Override
10539    public void setImmersive(IBinder token, boolean immersive) {
10540        synchronized(this) {
10541            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10542            if (r == null) {
10543                throw new IllegalArgumentException();
10544            }
10545            r.immersive = immersive;
10546
10547            // update associated state if we're frontmost
10548            if (r == mFocusedActivity) {
10549                if (DEBUG_IMMERSIVE) {
10550                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10551                }
10552                applyUpdateLockStateLocked(r);
10553            }
10554        }
10555    }
10556
10557    @Override
10558    public boolean isImmersive(IBinder token) {
10559        synchronized (this) {
10560            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10561            if (r == null) {
10562                throw new IllegalArgumentException();
10563            }
10564            return r.immersive;
10565        }
10566    }
10567
10568    public boolean isTopActivityImmersive() {
10569        enforceNotIsolatedCaller("startActivity");
10570        synchronized (this) {
10571            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10572            return (r != null) ? r.immersive : false;
10573        }
10574    }
10575
10576    @Override
10577    public boolean isTopOfTask(IBinder token) {
10578        synchronized (this) {
10579            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10580            if (r == null) {
10581                throw new IllegalArgumentException();
10582            }
10583            return r.task.getTopActivity() == r;
10584        }
10585    }
10586
10587    public final void enterSafeMode() {
10588        synchronized(this) {
10589            // It only makes sense to do this before the system is ready
10590            // and started launching other packages.
10591            if (!mSystemReady) {
10592                try {
10593                    AppGlobals.getPackageManager().enterSafeMode();
10594                } catch (RemoteException e) {
10595                }
10596            }
10597
10598            mSafeMode = true;
10599        }
10600    }
10601
10602    public final void showSafeModeOverlay() {
10603        View v = LayoutInflater.from(mContext).inflate(
10604                com.android.internal.R.layout.safe_mode, null);
10605        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10606        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10607        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10608        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10609        lp.gravity = Gravity.BOTTOM | Gravity.START;
10610        lp.format = v.getBackground().getOpacity();
10611        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10612                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10613        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10614        ((WindowManager)mContext.getSystemService(
10615                Context.WINDOW_SERVICE)).addView(v, lp);
10616    }
10617
10618    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10619        if (!(sender instanceof PendingIntentRecord)) {
10620            return;
10621        }
10622        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10623        synchronized (stats) {
10624            if (mBatteryStatsService.isOnBattery()) {
10625                mBatteryStatsService.enforceCallingPermission();
10626                PendingIntentRecord rec = (PendingIntentRecord)sender;
10627                int MY_UID = Binder.getCallingUid();
10628                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10629                BatteryStatsImpl.Uid.Pkg pkg =
10630                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10631                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10632                pkg.incWakeupsLocked();
10633            }
10634        }
10635    }
10636
10637    public boolean killPids(int[] pids, String pReason, boolean secure) {
10638        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10639            throw new SecurityException("killPids only available to the system");
10640        }
10641        String reason = (pReason == null) ? "Unknown" : pReason;
10642        // XXX Note: don't acquire main activity lock here, because the window
10643        // manager calls in with its locks held.
10644
10645        boolean killed = false;
10646        synchronized (mPidsSelfLocked) {
10647            int[] types = new int[pids.length];
10648            int worstType = 0;
10649            for (int i=0; i<pids.length; i++) {
10650                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10651                if (proc != null) {
10652                    int type = proc.setAdj;
10653                    types[i] = type;
10654                    if (type > worstType) {
10655                        worstType = type;
10656                    }
10657                }
10658            }
10659
10660            // If the worst oom_adj is somewhere in the cached proc LRU range,
10661            // then constrain it so we will kill all cached procs.
10662            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10663                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10664                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10665            }
10666
10667            // If this is not a secure call, don't let it kill processes that
10668            // are important.
10669            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10670                worstType = ProcessList.SERVICE_ADJ;
10671            }
10672
10673            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10674            for (int i=0; i<pids.length; i++) {
10675                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10676                if (proc == null) {
10677                    continue;
10678                }
10679                int adj = proc.setAdj;
10680                if (adj >= worstType && !proc.killedByAm) {
10681                    proc.kill(reason, true);
10682                    killed = true;
10683                }
10684            }
10685        }
10686        return killed;
10687    }
10688
10689    @Override
10690    public void killUid(int uid, String reason) {
10691        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10692            throw new SecurityException("killUid only available to the system");
10693        }
10694        synchronized (this) {
10695            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10696                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10697                    reason != null ? reason : "kill uid");
10698        }
10699    }
10700
10701    @Override
10702    public boolean killProcessesBelowForeground(String reason) {
10703        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10704            throw new SecurityException("killProcessesBelowForeground() only available to system");
10705        }
10706
10707        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10708    }
10709
10710    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10711        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10712            throw new SecurityException("killProcessesBelowAdj() only available to system");
10713        }
10714
10715        boolean killed = false;
10716        synchronized (mPidsSelfLocked) {
10717            final int size = mPidsSelfLocked.size();
10718            for (int i = 0; i < size; i++) {
10719                final int pid = mPidsSelfLocked.keyAt(i);
10720                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10721                if (proc == null) continue;
10722
10723                final int adj = proc.setAdj;
10724                if (adj > belowAdj && !proc.killedByAm) {
10725                    proc.kill(reason, true);
10726                    killed = true;
10727                }
10728            }
10729        }
10730        return killed;
10731    }
10732
10733    @Override
10734    public void hang(final IBinder who, boolean allowRestart) {
10735        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10736                != PackageManager.PERMISSION_GRANTED) {
10737            throw new SecurityException("Requires permission "
10738                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10739        }
10740
10741        final IBinder.DeathRecipient death = new DeathRecipient() {
10742            @Override
10743            public void binderDied() {
10744                synchronized (this) {
10745                    notifyAll();
10746                }
10747            }
10748        };
10749
10750        try {
10751            who.linkToDeath(death, 0);
10752        } catch (RemoteException e) {
10753            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10754            return;
10755        }
10756
10757        synchronized (this) {
10758            Watchdog.getInstance().setAllowRestart(allowRestart);
10759            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10760            synchronized (death) {
10761                while (who.isBinderAlive()) {
10762                    try {
10763                        death.wait();
10764                    } catch (InterruptedException e) {
10765                    }
10766                }
10767            }
10768            Watchdog.getInstance().setAllowRestart(true);
10769        }
10770    }
10771
10772    @Override
10773    public void restart() {
10774        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10775                != PackageManager.PERMISSION_GRANTED) {
10776            throw new SecurityException("Requires permission "
10777                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10778        }
10779
10780        Log.i(TAG, "Sending shutdown broadcast...");
10781
10782        BroadcastReceiver br = new BroadcastReceiver() {
10783            @Override public void onReceive(Context context, Intent intent) {
10784                // Now the broadcast is done, finish up the low-level shutdown.
10785                Log.i(TAG, "Shutting down activity manager...");
10786                shutdown(10000);
10787                Log.i(TAG, "Shutdown complete, restarting!");
10788                Process.killProcess(Process.myPid());
10789                System.exit(10);
10790            }
10791        };
10792
10793        // First send the high-level shut down broadcast.
10794        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10795        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10796        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10797        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10798        mContext.sendOrderedBroadcastAsUser(intent,
10799                UserHandle.ALL, null, br, mHandler, 0, null, null);
10800        */
10801        br.onReceive(mContext, intent);
10802    }
10803
10804    private long getLowRamTimeSinceIdle(long now) {
10805        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10806    }
10807
10808    @Override
10809    public void performIdleMaintenance() {
10810        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10811                != PackageManager.PERMISSION_GRANTED) {
10812            throw new SecurityException("Requires permission "
10813                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10814        }
10815
10816        synchronized (this) {
10817            final long now = SystemClock.uptimeMillis();
10818            final long timeSinceLastIdle = now - mLastIdleTime;
10819            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10820            mLastIdleTime = now;
10821            mLowRamTimeSinceLastIdle = 0;
10822            if (mLowRamStartTime != 0) {
10823                mLowRamStartTime = now;
10824            }
10825
10826            StringBuilder sb = new StringBuilder(128);
10827            sb.append("Idle maintenance over ");
10828            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10829            sb.append(" low RAM for ");
10830            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10831            Slog.i(TAG, sb.toString());
10832
10833            // If at least 1/3 of our time since the last idle period has been spent
10834            // with RAM low, then we want to kill processes.
10835            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10836
10837            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10838                ProcessRecord proc = mLruProcesses.get(i);
10839                if (proc.notCachedSinceIdle) {
10840                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10841                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10842                        if (doKilling && proc.initialIdlePss != 0
10843                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10844                            proc.kill("idle maint (pss " + proc.lastPss
10845                                    + " from " + proc.initialIdlePss + ")", true);
10846                        }
10847                    }
10848                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10849                    proc.notCachedSinceIdle = true;
10850                    proc.initialIdlePss = 0;
10851                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10852                            isSleeping(), now);
10853                }
10854            }
10855
10856            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10857            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10858        }
10859    }
10860
10861    private void retrieveSettings() {
10862        final ContentResolver resolver = mContext.getContentResolver();
10863        String debugApp = Settings.Global.getString(
10864            resolver, Settings.Global.DEBUG_APP);
10865        boolean waitForDebugger = Settings.Global.getInt(
10866            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10867        boolean alwaysFinishActivities = Settings.Global.getInt(
10868            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10869        boolean forceRtl = Settings.Global.getInt(
10870                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10871        // Transfer any global setting for forcing RTL layout, into a System Property
10872        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10873
10874        Configuration configuration = new Configuration();
10875        Settings.System.getConfiguration(resolver, configuration);
10876        if (forceRtl) {
10877            // This will take care of setting the correct layout direction flags
10878            configuration.setLayoutDirection(configuration.locale);
10879        }
10880
10881        synchronized (this) {
10882            mDebugApp = mOrigDebugApp = debugApp;
10883            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10884            mAlwaysFinishActivities = alwaysFinishActivities;
10885            // This happens before any activities are started, so we can
10886            // change mConfiguration in-place.
10887            updateConfigurationLocked(configuration, null, false, true);
10888            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10889        }
10890    }
10891
10892    /** Loads resources after the current configuration has been set. */
10893    private void loadResourcesOnSystemReady() {
10894        final Resources res = mContext.getResources();
10895        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10896        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10897        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10898    }
10899
10900    public boolean testIsSystemReady() {
10901        // no need to synchronize(this) just to read & return the value
10902        return mSystemReady;
10903    }
10904
10905    private static File getCalledPreBootReceiversFile() {
10906        File dataDir = Environment.getDataDirectory();
10907        File systemDir = new File(dataDir, "system");
10908        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10909        return fname;
10910    }
10911
10912    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10913        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10914        File file = getCalledPreBootReceiversFile();
10915        FileInputStream fis = null;
10916        try {
10917            fis = new FileInputStream(file);
10918            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10919            int fvers = dis.readInt();
10920            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10921                String vers = dis.readUTF();
10922                String codename = dis.readUTF();
10923                String build = dis.readUTF();
10924                if (android.os.Build.VERSION.RELEASE.equals(vers)
10925                        && android.os.Build.VERSION.CODENAME.equals(codename)
10926                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10927                    int num = dis.readInt();
10928                    while (num > 0) {
10929                        num--;
10930                        String pkg = dis.readUTF();
10931                        String cls = dis.readUTF();
10932                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10933                    }
10934                }
10935            }
10936        } catch (FileNotFoundException e) {
10937        } catch (IOException e) {
10938            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10939        } finally {
10940            if (fis != null) {
10941                try {
10942                    fis.close();
10943                } catch (IOException e) {
10944                }
10945            }
10946        }
10947        return lastDoneReceivers;
10948    }
10949
10950    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10951        File file = getCalledPreBootReceiversFile();
10952        FileOutputStream fos = null;
10953        DataOutputStream dos = null;
10954        try {
10955            fos = new FileOutputStream(file);
10956            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10957            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10958            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10959            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10960            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10961            dos.writeInt(list.size());
10962            for (int i=0; i<list.size(); i++) {
10963                dos.writeUTF(list.get(i).getPackageName());
10964                dos.writeUTF(list.get(i).getClassName());
10965            }
10966        } catch (IOException e) {
10967            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10968            file.delete();
10969        } finally {
10970            FileUtils.sync(fos);
10971            if (dos != null) {
10972                try {
10973                    dos.close();
10974                } catch (IOException e) {
10975                    // TODO Auto-generated catch block
10976                    e.printStackTrace();
10977                }
10978            }
10979        }
10980    }
10981
10982    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10983            ArrayList<ComponentName> doneReceivers, int userId) {
10984        boolean waitingUpdate = false;
10985        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10986        List<ResolveInfo> ris = null;
10987        try {
10988            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10989                    intent, null, 0, userId);
10990        } catch (RemoteException e) {
10991        }
10992        if (ris != null) {
10993            for (int i=ris.size()-1; i>=0; i--) {
10994                if ((ris.get(i).activityInfo.applicationInfo.flags
10995                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10996                    ris.remove(i);
10997                }
10998            }
10999            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11000
11001            // For User 0, load the version number. When delivering to a new user, deliver
11002            // to all receivers.
11003            if (userId == UserHandle.USER_OWNER) {
11004                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11005                for (int i=0; i<ris.size(); i++) {
11006                    ActivityInfo ai = ris.get(i).activityInfo;
11007                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11008                    if (lastDoneReceivers.contains(comp)) {
11009                        // We already did the pre boot receiver for this app with the current
11010                        // platform version, so don't do it again...
11011                        ris.remove(i);
11012                        i--;
11013                        // ...however, do keep it as one that has been done, so we don't
11014                        // forget about it when rewriting the file of last done receivers.
11015                        doneReceivers.add(comp);
11016                    }
11017                }
11018            }
11019
11020            // If primary user, send broadcast to all available users, else just to userId
11021            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11022                    : new int[] { userId };
11023            for (int i = 0; i < ris.size(); i++) {
11024                ActivityInfo ai = ris.get(i).activityInfo;
11025                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11026                doneReceivers.add(comp);
11027                intent.setComponent(comp);
11028                for (int j=0; j<users.length; j++) {
11029                    IIntentReceiver finisher = null;
11030                    // On last receiver and user, set up a completion callback
11031                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11032                        finisher = new IIntentReceiver.Stub() {
11033                            public void performReceive(Intent intent, int resultCode,
11034                                    String data, Bundle extras, boolean ordered,
11035                                    boolean sticky, int sendingUser) {
11036                                // The raw IIntentReceiver interface is called
11037                                // with the AM lock held, so redispatch to
11038                                // execute our code without the lock.
11039                                mHandler.post(onFinishCallback);
11040                            }
11041                        };
11042                    }
11043                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11044                            + " for user " + users[j]);
11045                    broadcastIntentLocked(null, null, intent, null, finisher,
11046                            0, null, null, null, AppOpsManager.OP_NONE,
11047                            true, false, MY_PID, Process.SYSTEM_UID,
11048                            users[j]);
11049                    if (finisher != null) {
11050                        waitingUpdate = true;
11051                    }
11052                }
11053            }
11054        }
11055
11056        return waitingUpdate;
11057    }
11058
11059    public void systemReady(final Runnable goingCallback) {
11060        synchronized(this) {
11061            if (mSystemReady) {
11062                // If we're done calling all the receivers, run the next "boot phase" passed in
11063                // by the SystemServer
11064                if (goingCallback != null) {
11065                    goingCallback.run();
11066                }
11067                return;
11068            }
11069
11070            // Make sure we have the current profile info, since it is needed for
11071            // security checks.
11072            updateCurrentProfileIdsLocked();
11073
11074            if (mRecentTasks == null) {
11075                mRecentTasks = mTaskPersister.restoreTasksLocked();
11076                if (!mRecentTasks.isEmpty()) {
11077                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11078                }
11079                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11080                mTaskPersister.startPersisting();
11081            }
11082
11083            // Check to see if there are any update receivers to run.
11084            if (!mDidUpdate) {
11085                if (mWaitingUpdate) {
11086                    return;
11087                }
11088                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11089                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11090                    public void run() {
11091                        synchronized (ActivityManagerService.this) {
11092                            mDidUpdate = true;
11093                        }
11094                        writeLastDonePreBootReceivers(doneReceivers);
11095                        showBootMessage(mContext.getText(
11096                                R.string.android_upgrading_complete),
11097                                false);
11098                        systemReady(goingCallback);
11099                    }
11100                }, doneReceivers, UserHandle.USER_OWNER);
11101
11102                if (mWaitingUpdate) {
11103                    return;
11104                }
11105                mDidUpdate = true;
11106            }
11107
11108            mAppOpsService.systemReady();
11109            mSystemReady = true;
11110        }
11111
11112        ArrayList<ProcessRecord> procsToKill = null;
11113        synchronized(mPidsSelfLocked) {
11114            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11115                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11116                if (!isAllowedWhileBooting(proc.info)){
11117                    if (procsToKill == null) {
11118                        procsToKill = new ArrayList<ProcessRecord>();
11119                    }
11120                    procsToKill.add(proc);
11121                }
11122            }
11123        }
11124
11125        synchronized(this) {
11126            if (procsToKill != null) {
11127                for (int i=procsToKill.size()-1; i>=0; i--) {
11128                    ProcessRecord proc = procsToKill.get(i);
11129                    Slog.i(TAG, "Removing system update proc: " + proc);
11130                    removeProcessLocked(proc, true, false, "system update done");
11131                }
11132            }
11133
11134            // Now that we have cleaned up any update processes, we
11135            // are ready to start launching real processes and know that
11136            // we won't trample on them any more.
11137            mProcessesReady = true;
11138        }
11139
11140        Slog.i(TAG, "System now ready");
11141        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11142            SystemClock.uptimeMillis());
11143
11144        synchronized(this) {
11145            // Make sure we have no pre-ready processes sitting around.
11146
11147            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11148                ResolveInfo ri = mContext.getPackageManager()
11149                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11150                                STOCK_PM_FLAGS);
11151                CharSequence errorMsg = null;
11152                if (ri != null) {
11153                    ActivityInfo ai = ri.activityInfo;
11154                    ApplicationInfo app = ai.applicationInfo;
11155                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11156                        mTopAction = Intent.ACTION_FACTORY_TEST;
11157                        mTopData = null;
11158                        mTopComponent = new ComponentName(app.packageName,
11159                                ai.name);
11160                    } else {
11161                        errorMsg = mContext.getResources().getText(
11162                                com.android.internal.R.string.factorytest_not_system);
11163                    }
11164                } else {
11165                    errorMsg = mContext.getResources().getText(
11166                            com.android.internal.R.string.factorytest_no_action);
11167                }
11168                if (errorMsg != null) {
11169                    mTopAction = null;
11170                    mTopData = null;
11171                    mTopComponent = null;
11172                    Message msg = Message.obtain();
11173                    msg.what = SHOW_FACTORY_ERROR_MSG;
11174                    msg.getData().putCharSequence("msg", errorMsg);
11175                    mHandler.sendMessage(msg);
11176                }
11177            }
11178        }
11179
11180        retrieveSettings();
11181        loadResourcesOnSystemReady();
11182
11183        synchronized (this) {
11184            readGrantedUriPermissionsLocked();
11185        }
11186
11187        if (goingCallback != null) goingCallback.run();
11188
11189        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11190                Integer.toString(mCurrentUserId), mCurrentUserId);
11191        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11192                Integer.toString(mCurrentUserId), mCurrentUserId);
11193        mSystemServiceManager.startUser(mCurrentUserId);
11194
11195        synchronized (this) {
11196            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11197                try {
11198                    List apps = AppGlobals.getPackageManager().
11199                        getPersistentApplications(STOCK_PM_FLAGS);
11200                    if (apps != null) {
11201                        int N = apps.size();
11202                        int i;
11203                        for (i=0; i<N; i++) {
11204                            ApplicationInfo info
11205                                = (ApplicationInfo)apps.get(i);
11206                            if (info != null &&
11207                                    !info.packageName.equals("android")) {
11208                                addAppLocked(info, false, null /* ABI override */);
11209                            }
11210                        }
11211                    }
11212                } catch (RemoteException ex) {
11213                    // pm is in same process, this will never happen.
11214                }
11215            }
11216
11217            // Start up initial activity.
11218            mBooting = true;
11219            startHomeActivityLocked(mCurrentUserId);
11220
11221            try {
11222                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11223                    Message msg = Message.obtain();
11224                    msg.what = SHOW_UID_ERROR_MSG;
11225                    mHandler.sendMessage(msg);
11226                }
11227            } catch (RemoteException e) {
11228            }
11229
11230            long ident = Binder.clearCallingIdentity();
11231            try {
11232                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11233                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11234                        | Intent.FLAG_RECEIVER_FOREGROUND);
11235                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11236                broadcastIntentLocked(null, null, intent,
11237                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11238                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11239                intent = new Intent(Intent.ACTION_USER_STARTING);
11240                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11241                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11242                broadcastIntentLocked(null, null, intent,
11243                        null, new IIntentReceiver.Stub() {
11244                            @Override
11245                            public void performReceive(Intent intent, int resultCode, String data,
11246                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11247                                    throws RemoteException {
11248                            }
11249                        }, 0, null, null,
11250                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11251                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11252            } catch (Throwable t) {
11253                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11254            } finally {
11255                Binder.restoreCallingIdentity(ident);
11256            }
11257            mStackSupervisor.resumeTopActivitiesLocked();
11258            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11259        }
11260    }
11261
11262    private boolean makeAppCrashingLocked(ProcessRecord app,
11263            String shortMsg, String longMsg, String stackTrace) {
11264        app.crashing = true;
11265        app.crashingReport = generateProcessError(app,
11266                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11267        startAppProblemLocked(app);
11268        app.stopFreezingAllLocked();
11269        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11270    }
11271
11272    private void makeAppNotRespondingLocked(ProcessRecord app,
11273            String activity, String shortMsg, String longMsg) {
11274        app.notResponding = true;
11275        app.notRespondingReport = generateProcessError(app,
11276                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11277                activity, shortMsg, longMsg, null);
11278        startAppProblemLocked(app);
11279        app.stopFreezingAllLocked();
11280    }
11281
11282    /**
11283     * Generate a process error record, suitable for attachment to a ProcessRecord.
11284     *
11285     * @param app The ProcessRecord in which the error occurred.
11286     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11287     *                      ActivityManager.AppErrorStateInfo
11288     * @param activity The activity associated with the crash, if known.
11289     * @param shortMsg Short message describing the crash.
11290     * @param longMsg Long message describing the crash.
11291     * @param stackTrace Full crash stack trace, may be null.
11292     *
11293     * @return Returns a fully-formed AppErrorStateInfo record.
11294     */
11295    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11296            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11297        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11298
11299        report.condition = condition;
11300        report.processName = app.processName;
11301        report.pid = app.pid;
11302        report.uid = app.info.uid;
11303        report.tag = activity;
11304        report.shortMsg = shortMsg;
11305        report.longMsg = longMsg;
11306        report.stackTrace = stackTrace;
11307
11308        return report;
11309    }
11310
11311    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11312        synchronized (this) {
11313            app.crashing = false;
11314            app.crashingReport = null;
11315            app.notResponding = false;
11316            app.notRespondingReport = null;
11317            if (app.anrDialog == fromDialog) {
11318                app.anrDialog = null;
11319            }
11320            if (app.waitDialog == fromDialog) {
11321                app.waitDialog = null;
11322            }
11323            if (app.pid > 0 && app.pid != MY_PID) {
11324                handleAppCrashLocked(app, null, null, null);
11325                app.kill("user request after error", true);
11326            }
11327        }
11328    }
11329
11330    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11331            String stackTrace) {
11332        long now = SystemClock.uptimeMillis();
11333
11334        Long crashTime;
11335        if (!app.isolated) {
11336            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11337        } else {
11338            crashTime = null;
11339        }
11340        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11341            // This process loses!
11342            Slog.w(TAG, "Process " + app.info.processName
11343                    + " has crashed too many times: killing!");
11344            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11345                    app.userId, app.info.processName, app.uid);
11346            mStackSupervisor.handleAppCrashLocked(app);
11347            if (!app.persistent) {
11348                // We don't want to start this process again until the user
11349                // explicitly does so...  but for persistent process, we really
11350                // need to keep it running.  If a persistent process is actually
11351                // repeatedly crashing, then badness for everyone.
11352                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11353                        app.info.processName);
11354                if (!app.isolated) {
11355                    // XXX We don't have a way to mark isolated processes
11356                    // as bad, since they don't have a peristent identity.
11357                    mBadProcesses.put(app.info.processName, app.uid,
11358                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11359                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11360                }
11361                app.bad = true;
11362                app.removed = true;
11363                // Don't let services in this process be restarted and potentially
11364                // annoy the user repeatedly.  Unless it is persistent, since those
11365                // processes run critical code.
11366                removeProcessLocked(app, false, false, "crash");
11367                mStackSupervisor.resumeTopActivitiesLocked();
11368                return false;
11369            }
11370            mStackSupervisor.resumeTopActivitiesLocked();
11371        } else {
11372            mStackSupervisor.finishTopRunningActivityLocked(app);
11373        }
11374
11375        // Bump up the crash count of any services currently running in the proc.
11376        for (int i=app.services.size()-1; i>=0; i--) {
11377            // Any services running in the application need to be placed
11378            // back in the pending list.
11379            ServiceRecord sr = app.services.valueAt(i);
11380            sr.crashCount++;
11381        }
11382
11383        // If the crashing process is what we consider to be the "home process" and it has been
11384        // replaced by a third-party app, clear the package preferred activities from packages
11385        // with a home activity running in the process to prevent a repeatedly crashing app
11386        // from blocking the user to manually clear the list.
11387        final ArrayList<ActivityRecord> activities = app.activities;
11388        if (app == mHomeProcess && activities.size() > 0
11389                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11390            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11391                final ActivityRecord r = activities.get(activityNdx);
11392                if (r.isHomeActivity()) {
11393                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11394                    try {
11395                        ActivityThread.getPackageManager()
11396                                .clearPackagePreferredActivities(r.packageName);
11397                    } catch (RemoteException c) {
11398                        // pm is in same process, this will never happen.
11399                    }
11400                }
11401            }
11402        }
11403
11404        if (!app.isolated) {
11405            // XXX Can't keep track of crash times for isolated processes,
11406            // because they don't have a perisistent identity.
11407            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11408        }
11409
11410        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11411        return true;
11412    }
11413
11414    void startAppProblemLocked(ProcessRecord app) {
11415        // If this app is not running under the current user, then we
11416        // can't give it a report button because that would require
11417        // launching the report UI under a different user.
11418        app.errorReportReceiver = null;
11419
11420        for (int userId : mCurrentProfileIds) {
11421            if (app.userId == userId) {
11422                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11423                        mContext, app.info.packageName, app.info.flags);
11424            }
11425        }
11426        skipCurrentReceiverLocked(app);
11427    }
11428
11429    void skipCurrentReceiverLocked(ProcessRecord app) {
11430        for (BroadcastQueue queue : mBroadcastQueues) {
11431            queue.skipCurrentReceiverLocked(app);
11432        }
11433    }
11434
11435    /**
11436     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11437     * The application process will exit immediately after this call returns.
11438     * @param app object of the crashing app, null for the system server
11439     * @param crashInfo describing the exception
11440     */
11441    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11442        ProcessRecord r = findAppProcess(app, "Crash");
11443        final String processName = app == null ? "system_server"
11444                : (r == null ? "unknown" : r.processName);
11445
11446        handleApplicationCrashInner("crash", r, processName, crashInfo);
11447    }
11448
11449    /* Native crash reporting uses this inner version because it needs to be somewhat
11450     * decoupled from the AM-managed cleanup lifecycle
11451     */
11452    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11453            ApplicationErrorReport.CrashInfo crashInfo) {
11454        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11455                UserHandle.getUserId(Binder.getCallingUid()), processName,
11456                r == null ? -1 : r.info.flags,
11457                crashInfo.exceptionClassName,
11458                crashInfo.exceptionMessage,
11459                crashInfo.throwFileName,
11460                crashInfo.throwLineNumber);
11461
11462        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11463
11464        crashApplication(r, crashInfo);
11465    }
11466
11467    public void handleApplicationStrictModeViolation(
11468            IBinder app,
11469            int violationMask,
11470            StrictMode.ViolationInfo info) {
11471        ProcessRecord r = findAppProcess(app, "StrictMode");
11472        if (r == null) {
11473            return;
11474        }
11475
11476        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11477            Integer stackFingerprint = info.hashCode();
11478            boolean logIt = true;
11479            synchronized (mAlreadyLoggedViolatedStacks) {
11480                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11481                    logIt = false;
11482                    // TODO: sub-sample into EventLog for these, with
11483                    // the info.durationMillis?  Then we'd get
11484                    // the relative pain numbers, without logging all
11485                    // the stack traces repeatedly.  We'd want to do
11486                    // likewise in the client code, which also does
11487                    // dup suppression, before the Binder call.
11488                } else {
11489                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11490                        mAlreadyLoggedViolatedStacks.clear();
11491                    }
11492                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11493                }
11494            }
11495            if (logIt) {
11496                logStrictModeViolationToDropBox(r, info);
11497            }
11498        }
11499
11500        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11501            AppErrorResult result = new AppErrorResult();
11502            synchronized (this) {
11503                final long origId = Binder.clearCallingIdentity();
11504
11505                Message msg = Message.obtain();
11506                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11507                HashMap<String, Object> data = new HashMap<String, Object>();
11508                data.put("result", result);
11509                data.put("app", r);
11510                data.put("violationMask", violationMask);
11511                data.put("info", info);
11512                msg.obj = data;
11513                mHandler.sendMessage(msg);
11514
11515                Binder.restoreCallingIdentity(origId);
11516            }
11517            int res = result.get();
11518            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11519        }
11520    }
11521
11522    // Depending on the policy in effect, there could be a bunch of
11523    // these in quick succession so we try to batch these together to
11524    // minimize disk writes, number of dropbox entries, and maximize
11525    // compression, by having more fewer, larger records.
11526    private void logStrictModeViolationToDropBox(
11527            ProcessRecord process,
11528            StrictMode.ViolationInfo info) {
11529        if (info == null) {
11530            return;
11531        }
11532        final boolean isSystemApp = process == null ||
11533                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11534                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11535        final String processName = process == null ? "unknown" : process.processName;
11536        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11537        final DropBoxManager dbox = (DropBoxManager)
11538                mContext.getSystemService(Context.DROPBOX_SERVICE);
11539
11540        // Exit early if the dropbox isn't configured to accept this report type.
11541        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11542
11543        boolean bufferWasEmpty;
11544        boolean needsFlush;
11545        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11546        synchronized (sb) {
11547            bufferWasEmpty = sb.length() == 0;
11548            appendDropBoxProcessHeaders(process, processName, sb);
11549            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11550            sb.append("System-App: ").append(isSystemApp).append("\n");
11551            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11552            if (info.violationNumThisLoop != 0) {
11553                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11554            }
11555            if (info.numAnimationsRunning != 0) {
11556                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11557            }
11558            if (info.broadcastIntentAction != null) {
11559                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11560            }
11561            if (info.durationMillis != -1) {
11562                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11563            }
11564            if (info.numInstances != -1) {
11565                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11566            }
11567            if (info.tags != null) {
11568                for (String tag : info.tags) {
11569                    sb.append("Span-Tag: ").append(tag).append("\n");
11570                }
11571            }
11572            sb.append("\n");
11573            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11574                sb.append(info.crashInfo.stackTrace);
11575            }
11576            sb.append("\n");
11577
11578            // Only buffer up to ~64k.  Various logging bits truncate
11579            // things at 128k.
11580            needsFlush = (sb.length() > 64 * 1024);
11581        }
11582
11583        // Flush immediately if the buffer's grown too large, or this
11584        // is a non-system app.  Non-system apps are isolated with a
11585        // different tag & policy and not batched.
11586        //
11587        // Batching is useful during internal testing with
11588        // StrictMode settings turned up high.  Without batching,
11589        // thousands of separate files could be created on boot.
11590        if (!isSystemApp || needsFlush) {
11591            new Thread("Error dump: " + dropboxTag) {
11592                @Override
11593                public void run() {
11594                    String report;
11595                    synchronized (sb) {
11596                        report = sb.toString();
11597                        sb.delete(0, sb.length());
11598                        sb.trimToSize();
11599                    }
11600                    if (report.length() != 0) {
11601                        dbox.addText(dropboxTag, report);
11602                    }
11603                }
11604            }.start();
11605            return;
11606        }
11607
11608        // System app batching:
11609        if (!bufferWasEmpty) {
11610            // An existing dropbox-writing thread is outstanding, so
11611            // we don't need to start it up.  The existing thread will
11612            // catch the buffer appends we just did.
11613            return;
11614        }
11615
11616        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11617        // (After this point, we shouldn't access AMS internal data structures.)
11618        new Thread("Error dump: " + dropboxTag) {
11619            @Override
11620            public void run() {
11621                // 5 second sleep to let stacks arrive and be batched together
11622                try {
11623                    Thread.sleep(5000);  // 5 seconds
11624                } catch (InterruptedException e) {}
11625
11626                String errorReport;
11627                synchronized (mStrictModeBuffer) {
11628                    errorReport = mStrictModeBuffer.toString();
11629                    if (errorReport.length() == 0) {
11630                        return;
11631                    }
11632                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11633                    mStrictModeBuffer.trimToSize();
11634                }
11635                dbox.addText(dropboxTag, errorReport);
11636            }
11637        }.start();
11638    }
11639
11640    /**
11641     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11642     * @param app object of the crashing app, null for the system server
11643     * @param tag reported by the caller
11644     * @param system whether this wtf is coming from the system
11645     * @param crashInfo describing the context of the error
11646     * @return true if the process should exit immediately (WTF is fatal)
11647     */
11648    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11649            final ApplicationErrorReport.CrashInfo crashInfo) {
11650        final int callingUid = Binder.getCallingUid();
11651        final int callingPid = Binder.getCallingPid();
11652
11653        if (system) {
11654            // If this is coming from the system, we could very well have low-level
11655            // system locks held, so we want to do this all asynchronously.  And we
11656            // never want this to become fatal, so there is that too.
11657            mHandler.post(new Runnable() {
11658                @Override public void run() {
11659                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11660                }
11661            });
11662            return false;
11663        }
11664
11665        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11666                crashInfo);
11667
11668        if (r != null && r.pid != Process.myPid() &&
11669                Settings.Global.getInt(mContext.getContentResolver(),
11670                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11671            crashApplication(r, crashInfo);
11672            return true;
11673        } else {
11674            return false;
11675        }
11676    }
11677
11678    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11679            final ApplicationErrorReport.CrashInfo crashInfo) {
11680        final ProcessRecord r = findAppProcess(app, "WTF");
11681        final String processName = app == null ? "system_server"
11682                : (r == null ? "unknown" : r.processName);
11683
11684        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11685                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11686
11687        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11688
11689        return r;
11690    }
11691
11692    /**
11693     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11694     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11695     */
11696    private ProcessRecord findAppProcess(IBinder app, String reason) {
11697        if (app == null) {
11698            return null;
11699        }
11700
11701        synchronized (this) {
11702            final int NP = mProcessNames.getMap().size();
11703            for (int ip=0; ip<NP; ip++) {
11704                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11705                final int NA = apps.size();
11706                for (int ia=0; ia<NA; ia++) {
11707                    ProcessRecord p = apps.valueAt(ia);
11708                    if (p.thread != null && p.thread.asBinder() == app) {
11709                        return p;
11710                    }
11711                }
11712            }
11713
11714            Slog.w(TAG, "Can't find mystery application for " + reason
11715                    + " from pid=" + Binder.getCallingPid()
11716                    + " uid=" + Binder.getCallingUid() + ": " + app);
11717            return null;
11718        }
11719    }
11720
11721    /**
11722     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11723     * to append various headers to the dropbox log text.
11724     */
11725    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11726            StringBuilder sb) {
11727        // Watchdog thread ends up invoking this function (with
11728        // a null ProcessRecord) to add the stack file to dropbox.
11729        // Do not acquire a lock on this (am) in such cases, as it
11730        // could cause a potential deadlock, if and when watchdog
11731        // is invoked due to unavailability of lock on am and it
11732        // would prevent watchdog from killing system_server.
11733        if (process == null) {
11734            sb.append("Process: ").append(processName).append("\n");
11735            return;
11736        }
11737        // Note: ProcessRecord 'process' is guarded by the service
11738        // instance.  (notably process.pkgList, which could otherwise change
11739        // concurrently during execution of this method)
11740        synchronized (this) {
11741            sb.append("Process: ").append(processName).append("\n");
11742            int flags = process.info.flags;
11743            IPackageManager pm = AppGlobals.getPackageManager();
11744            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11745            for (int ip=0; ip<process.pkgList.size(); ip++) {
11746                String pkg = process.pkgList.keyAt(ip);
11747                sb.append("Package: ").append(pkg);
11748                try {
11749                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11750                    if (pi != null) {
11751                        sb.append(" v").append(pi.versionCode);
11752                        if (pi.versionName != null) {
11753                            sb.append(" (").append(pi.versionName).append(")");
11754                        }
11755                    }
11756                } catch (RemoteException e) {
11757                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11758                }
11759                sb.append("\n");
11760            }
11761        }
11762    }
11763
11764    private static String processClass(ProcessRecord process) {
11765        if (process == null || process.pid == MY_PID) {
11766            return "system_server";
11767        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11768            return "system_app";
11769        } else {
11770            return "data_app";
11771        }
11772    }
11773
11774    /**
11775     * Write a description of an error (crash, WTF, ANR) to the drop box.
11776     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11777     * @param process which caused the error, null means the system server
11778     * @param activity which triggered the error, null if unknown
11779     * @param parent activity related to the error, null if unknown
11780     * @param subject line related to the error, null if absent
11781     * @param report in long form describing the error, null if absent
11782     * @param logFile to include in the report, null if none
11783     * @param crashInfo giving an application stack trace, null if absent
11784     */
11785    public void addErrorToDropBox(String eventType,
11786            ProcessRecord process, String processName, ActivityRecord activity,
11787            ActivityRecord parent, String subject,
11788            final String report, final File logFile,
11789            final ApplicationErrorReport.CrashInfo crashInfo) {
11790        // NOTE -- this must never acquire the ActivityManagerService lock,
11791        // otherwise the watchdog may be prevented from resetting the system.
11792
11793        final String dropboxTag = processClass(process) + "_" + eventType;
11794        final DropBoxManager dbox = (DropBoxManager)
11795                mContext.getSystemService(Context.DROPBOX_SERVICE);
11796
11797        // Exit early if the dropbox isn't configured to accept this report type.
11798        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11799
11800        final StringBuilder sb = new StringBuilder(1024);
11801        appendDropBoxProcessHeaders(process, processName, sb);
11802        if (activity != null) {
11803            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11804        }
11805        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11806            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11807        }
11808        if (parent != null && parent != activity) {
11809            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11810        }
11811        if (subject != null) {
11812            sb.append("Subject: ").append(subject).append("\n");
11813        }
11814        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11815        if (Debug.isDebuggerConnected()) {
11816            sb.append("Debugger: Connected\n");
11817        }
11818        sb.append("\n");
11819
11820        // Do the rest in a worker thread to avoid blocking the caller on I/O
11821        // (After this point, we shouldn't access AMS internal data structures.)
11822        Thread worker = new Thread("Error dump: " + dropboxTag) {
11823            @Override
11824            public void run() {
11825                if (report != null) {
11826                    sb.append(report);
11827                }
11828                if (logFile != null) {
11829                    try {
11830                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11831                                    "\n\n[[TRUNCATED]]"));
11832                    } catch (IOException e) {
11833                        Slog.e(TAG, "Error reading " + logFile, e);
11834                    }
11835                }
11836                if (crashInfo != null && crashInfo.stackTrace != null) {
11837                    sb.append(crashInfo.stackTrace);
11838                }
11839
11840                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11841                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11842                if (lines > 0) {
11843                    sb.append("\n");
11844
11845                    // Merge several logcat streams, and take the last N lines
11846                    InputStreamReader input = null;
11847                    try {
11848                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11849                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11850                                "-b", "crash",
11851                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11852
11853                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11854                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11855                        input = new InputStreamReader(logcat.getInputStream());
11856
11857                        int num;
11858                        char[] buf = new char[8192];
11859                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11860                    } catch (IOException e) {
11861                        Slog.e(TAG, "Error running logcat", e);
11862                    } finally {
11863                        if (input != null) try { input.close(); } catch (IOException e) {}
11864                    }
11865                }
11866
11867                dbox.addText(dropboxTag, sb.toString());
11868            }
11869        };
11870
11871        if (process == null) {
11872            // If process is null, we are being called from some internal code
11873            // and may be about to die -- run this synchronously.
11874            worker.run();
11875        } else {
11876            worker.start();
11877        }
11878    }
11879
11880    /**
11881     * Bring up the "unexpected error" dialog box for a crashing app.
11882     * Deal with edge cases (intercepts from instrumented applications,
11883     * ActivityController, error intent receivers, that sort of thing).
11884     * @param r the application crashing
11885     * @param crashInfo describing the failure
11886     */
11887    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11888        long timeMillis = System.currentTimeMillis();
11889        String shortMsg = crashInfo.exceptionClassName;
11890        String longMsg = crashInfo.exceptionMessage;
11891        String stackTrace = crashInfo.stackTrace;
11892        if (shortMsg != null && longMsg != null) {
11893            longMsg = shortMsg + ": " + longMsg;
11894        } else if (shortMsg != null) {
11895            longMsg = shortMsg;
11896        }
11897
11898        AppErrorResult result = new AppErrorResult();
11899        synchronized (this) {
11900            if (mController != null) {
11901                try {
11902                    String name = r != null ? r.processName : null;
11903                    int pid = r != null ? r.pid : Binder.getCallingPid();
11904                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11905                    if (!mController.appCrashed(name, pid,
11906                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11907                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11908                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11909                            Slog.w(TAG, "Skip killing native crashed app " + name
11910                                    + "(" + pid + ") during testing");
11911                        } else {
11912                            Slog.w(TAG, "Force-killing crashed app " + name
11913                                    + " at watcher's request");
11914                            if (r != null) {
11915                                r.kill("crash", true);
11916                            } else {
11917                                // Huh.
11918                                Process.killProcess(pid);
11919                                Process.killProcessGroup(uid, pid);
11920                            }
11921                        }
11922                        return;
11923                    }
11924                } catch (RemoteException e) {
11925                    mController = null;
11926                    Watchdog.getInstance().setActivityController(null);
11927                }
11928            }
11929
11930            final long origId = Binder.clearCallingIdentity();
11931
11932            // If this process is running instrumentation, finish it.
11933            if (r != null && r.instrumentationClass != null) {
11934                Slog.w(TAG, "Error in app " + r.processName
11935                      + " running instrumentation " + r.instrumentationClass + ":");
11936                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11937                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11938                Bundle info = new Bundle();
11939                info.putString("shortMsg", shortMsg);
11940                info.putString("longMsg", longMsg);
11941                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11942                Binder.restoreCallingIdentity(origId);
11943                return;
11944            }
11945
11946            // If we can't identify the process or it's already exceeded its crash quota,
11947            // quit right away without showing a crash dialog.
11948            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11949                Binder.restoreCallingIdentity(origId);
11950                return;
11951            }
11952
11953            Message msg = Message.obtain();
11954            msg.what = SHOW_ERROR_MSG;
11955            HashMap data = new HashMap();
11956            data.put("result", result);
11957            data.put("app", r);
11958            msg.obj = data;
11959            mHandler.sendMessage(msg);
11960
11961            Binder.restoreCallingIdentity(origId);
11962        }
11963
11964        int res = result.get();
11965
11966        Intent appErrorIntent = null;
11967        synchronized (this) {
11968            if (r != null && !r.isolated) {
11969                // XXX Can't keep track of crash time for isolated processes,
11970                // since they don't have a persistent identity.
11971                mProcessCrashTimes.put(r.info.processName, r.uid,
11972                        SystemClock.uptimeMillis());
11973            }
11974            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11975                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11976            }
11977        }
11978
11979        if (appErrorIntent != null) {
11980            try {
11981                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11982            } catch (ActivityNotFoundException e) {
11983                Slog.w(TAG, "bug report receiver dissappeared", e);
11984            }
11985        }
11986    }
11987
11988    Intent createAppErrorIntentLocked(ProcessRecord r,
11989            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11990        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11991        if (report == null) {
11992            return null;
11993        }
11994        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11995        result.setComponent(r.errorReportReceiver);
11996        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11997        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11998        return result;
11999    }
12000
12001    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12002            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12003        if (r.errorReportReceiver == null) {
12004            return null;
12005        }
12006
12007        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12008            return null;
12009        }
12010
12011        ApplicationErrorReport report = new ApplicationErrorReport();
12012        report.packageName = r.info.packageName;
12013        report.installerPackageName = r.errorReportReceiver.getPackageName();
12014        report.processName = r.processName;
12015        report.time = timeMillis;
12016        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12017
12018        if (r.crashing || r.forceCrashReport) {
12019            report.type = ApplicationErrorReport.TYPE_CRASH;
12020            report.crashInfo = crashInfo;
12021        } else if (r.notResponding) {
12022            report.type = ApplicationErrorReport.TYPE_ANR;
12023            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12024
12025            report.anrInfo.activity = r.notRespondingReport.tag;
12026            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12027            report.anrInfo.info = r.notRespondingReport.longMsg;
12028        }
12029
12030        return report;
12031    }
12032
12033    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12034        enforceNotIsolatedCaller("getProcessesInErrorState");
12035        // assume our apps are happy - lazy create the list
12036        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12037
12038        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12039                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12040        int userId = UserHandle.getUserId(Binder.getCallingUid());
12041
12042        synchronized (this) {
12043
12044            // iterate across all processes
12045            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12046                ProcessRecord app = mLruProcesses.get(i);
12047                if (!allUsers && app.userId != userId) {
12048                    continue;
12049                }
12050                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12051                    // This one's in trouble, so we'll generate a report for it
12052                    // crashes are higher priority (in case there's a crash *and* an anr)
12053                    ActivityManager.ProcessErrorStateInfo report = null;
12054                    if (app.crashing) {
12055                        report = app.crashingReport;
12056                    } else if (app.notResponding) {
12057                        report = app.notRespondingReport;
12058                    }
12059
12060                    if (report != null) {
12061                        if (errList == null) {
12062                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12063                        }
12064                        errList.add(report);
12065                    } else {
12066                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12067                                " crashing = " + app.crashing +
12068                                " notResponding = " + app.notResponding);
12069                    }
12070                }
12071            }
12072        }
12073
12074        return errList;
12075    }
12076
12077    static int procStateToImportance(int procState, int memAdj,
12078            ActivityManager.RunningAppProcessInfo currApp) {
12079        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12080        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12081            currApp.lru = memAdj;
12082        } else {
12083            currApp.lru = 0;
12084        }
12085        return imp;
12086    }
12087
12088    private void fillInProcMemInfo(ProcessRecord app,
12089            ActivityManager.RunningAppProcessInfo outInfo) {
12090        outInfo.pid = app.pid;
12091        outInfo.uid = app.info.uid;
12092        if (mHeavyWeightProcess == app) {
12093            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12094        }
12095        if (app.persistent) {
12096            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12097        }
12098        if (app.activities.size() > 0) {
12099            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12100        }
12101        outInfo.lastTrimLevel = app.trimMemoryLevel;
12102        int adj = app.curAdj;
12103        int procState = app.curProcState;
12104        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12105        outInfo.importanceReasonCode = app.adjTypeCode;
12106        outInfo.processState = app.curProcState;
12107    }
12108
12109    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12110        enforceNotIsolatedCaller("getRunningAppProcesses");
12111        // Lazy instantiation of list
12112        List<ActivityManager.RunningAppProcessInfo> runList = null;
12113        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12114                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12115        int userId = UserHandle.getUserId(Binder.getCallingUid());
12116        synchronized (this) {
12117            // Iterate across all processes
12118            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12119                ProcessRecord app = mLruProcesses.get(i);
12120                if (!allUsers && app.userId != userId) {
12121                    continue;
12122                }
12123                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12124                    // Generate process state info for running application
12125                    ActivityManager.RunningAppProcessInfo currApp =
12126                        new ActivityManager.RunningAppProcessInfo(app.processName,
12127                                app.pid, app.getPackageList());
12128                    fillInProcMemInfo(app, currApp);
12129                    if (app.adjSource instanceof ProcessRecord) {
12130                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12131                        currApp.importanceReasonImportance =
12132                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12133                                        app.adjSourceProcState);
12134                    } else if (app.adjSource instanceof ActivityRecord) {
12135                        ActivityRecord r = (ActivityRecord)app.adjSource;
12136                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12137                    }
12138                    if (app.adjTarget instanceof ComponentName) {
12139                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12140                    }
12141                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12142                    //        + " lru=" + currApp.lru);
12143                    if (runList == null) {
12144                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12145                    }
12146                    runList.add(currApp);
12147                }
12148            }
12149        }
12150        return runList;
12151    }
12152
12153    public List<ApplicationInfo> getRunningExternalApplications() {
12154        enforceNotIsolatedCaller("getRunningExternalApplications");
12155        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12156        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12157        if (runningApps != null && runningApps.size() > 0) {
12158            Set<String> extList = new HashSet<String>();
12159            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12160                if (app.pkgList != null) {
12161                    for (String pkg : app.pkgList) {
12162                        extList.add(pkg);
12163                    }
12164                }
12165            }
12166            IPackageManager pm = AppGlobals.getPackageManager();
12167            for (String pkg : extList) {
12168                try {
12169                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12170                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12171                        retList.add(info);
12172                    }
12173                } catch (RemoteException e) {
12174                }
12175            }
12176        }
12177        return retList;
12178    }
12179
12180    @Override
12181    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12182        enforceNotIsolatedCaller("getMyMemoryState");
12183        synchronized (this) {
12184            ProcessRecord proc;
12185            synchronized (mPidsSelfLocked) {
12186                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12187            }
12188            fillInProcMemInfo(proc, outInfo);
12189        }
12190    }
12191
12192    @Override
12193    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12194        if (checkCallingPermission(android.Manifest.permission.DUMP)
12195                != PackageManager.PERMISSION_GRANTED) {
12196            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12197                    + Binder.getCallingPid()
12198                    + ", uid=" + Binder.getCallingUid()
12199                    + " without permission "
12200                    + android.Manifest.permission.DUMP);
12201            return;
12202        }
12203
12204        boolean dumpAll = false;
12205        boolean dumpClient = false;
12206        String dumpPackage = null;
12207
12208        int opti = 0;
12209        while (opti < args.length) {
12210            String opt = args[opti];
12211            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12212                break;
12213            }
12214            opti++;
12215            if ("-a".equals(opt)) {
12216                dumpAll = true;
12217            } else if ("-c".equals(opt)) {
12218                dumpClient = true;
12219            } else if ("-h".equals(opt)) {
12220                pw.println("Activity manager dump options:");
12221                pw.println("  [-a] [-c] [-h] [cmd] ...");
12222                pw.println("  cmd may be one of:");
12223                pw.println("    a[ctivities]: activity stack state");
12224                pw.println("    r[recents]: recent activities state");
12225                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12226                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12227                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12228                pw.println("    o[om]: out of memory management");
12229                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12230                pw.println("    provider [COMP_SPEC]: provider client-side state");
12231                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12232                pw.println("    service [COMP_SPEC]: service client-side state");
12233                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12234                pw.println("    all: dump all activities");
12235                pw.println("    top: dump the top activity");
12236                pw.println("    write: write all pending state to storage");
12237                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12238                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12239                pw.println("    a partial substring in a component name, a");
12240                pw.println("    hex object identifier.");
12241                pw.println("  -a: include all available server state.");
12242                pw.println("  -c: include client state.");
12243                return;
12244            } else {
12245                pw.println("Unknown argument: " + opt + "; use -h for help");
12246            }
12247        }
12248
12249        long origId = Binder.clearCallingIdentity();
12250        boolean more = false;
12251        // Is the caller requesting to dump a particular piece of data?
12252        if (opti < args.length) {
12253            String cmd = args[opti];
12254            opti++;
12255            if ("activities".equals(cmd) || "a".equals(cmd)) {
12256                synchronized (this) {
12257                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12258                }
12259            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12260                synchronized (this) {
12261                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12262                }
12263            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12264                String[] newArgs;
12265                String name;
12266                if (opti >= args.length) {
12267                    name = null;
12268                    newArgs = EMPTY_STRING_ARRAY;
12269                } else {
12270                    name = args[opti];
12271                    opti++;
12272                    newArgs = new String[args.length - opti];
12273                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12274                            args.length - opti);
12275                }
12276                synchronized (this) {
12277                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12278                }
12279            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12280                String[] newArgs;
12281                String name;
12282                if (opti >= args.length) {
12283                    name = null;
12284                    newArgs = EMPTY_STRING_ARRAY;
12285                } else {
12286                    name = args[opti];
12287                    opti++;
12288                    newArgs = new String[args.length - opti];
12289                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12290                            args.length - opti);
12291                }
12292                synchronized (this) {
12293                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12294                }
12295            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12296                String[] newArgs;
12297                String name;
12298                if (opti >= args.length) {
12299                    name = null;
12300                    newArgs = EMPTY_STRING_ARRAY;
12301                } else {
12302                    name = args[opti];
12303                    opti++;
12304                    newArgs = new String[args.length - opti];
12305                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12306                            args.length - opti);
12307                }
12308                synchronized (this) {
12309                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12310                }
12311            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12312                synchronized (this) {
12313                    dumpOomLocked(fd, pw, args, opti, true);
12314                }
12315            } else if ("provider".equals(cmd)) {
12316                String[] newArgs;
12317                String name;
12318                if (opti >= args.length) {
12319                    name = null;
12320                    newArgs = EMPTY_STRING_ARRAY;
12321                } else {
12322                    name = args[opti];
12323                    opti++;
12324                    newArgs = new String[args.length - opti];
12325                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12326                }
12327                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12328                    pw.println("No providers match: " + name);
12329                    pw.println("Use -h for help.");
12330                }
12331            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12332                synchronized (this) {
12333                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12334                }
12335            } else if ("service".equals(cmd)) {
12336                String[] newArgs;
12337                String name;
12338                if (opti >= args.length) {
12339                    name = null;
12340                    newArgs = EMPTY_STRING_ARRAY;
12341                } else {
12342                    name = args[opti];
12343                    opti++;
12344                    newArgs = new String[args.length - opti];
12345                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12346                            args.length - opti);
12347                }
12348                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12349                    pw.println("No services match: " + name);
12350                    pw.println("Use -h for help.");
12351                }
12352            } else if ("package".equals(cmd)) {
12353                String[] newArgs;
12354                if (opti >= args.length) {
12355                    pw.println("package: no package name specified");
12356                    pw.println("Use -h for help.");
12357                } else {
12358                    dumpPackage = args[opti];
12359                    opti++;
12360                    newArgs = new String[args.length - opti];
12361                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12362                            args.length - opti);
12363                    args = newArgs;
12364                    opti = 0;
12365                    more = true;
12366                }
12367            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12368                synchronized (this) {
12369                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12370                }
12371            } else if ("write".equals(cmd)) {
12372                mTaskPersister.flush();
12373                pw.println("All tasks persisted.");
12374                return;
12375            } else {
12376                // Dumping a single activity?
12377                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12378                    pw.println("Bad activity command, or no activities match: " + cmd);
12379                    pw.println("Use -h for help.");
12380                }
12381            }
12382            if (!more) {
12383                Binder.restoreCallingIdentity(origId);
12384                return;
12385            }
12386        }
12387
12388        // No piece of data specified, dump everything.
12389        synchronized (this) {
12390            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12391            pw.println();
12392            if (dumpAll) {
12393                pw.println("-------------------------------------------------------------------------------");
12394            }
12395            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12396            pw.println();
12397            if (dumpAll) {
12398                pw.println("-------------------------------------------------------------------------------");
12399            }
12400            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12401            pw.println();
12402            if (dumpAll) {
12403                pw.println("-------------------------------------------------------------------------------");
12404            }
12405            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12406            pw.println();
12407            if (dumpAll) {
12408                pw.println("-------------------------------------------------------------------------------");
12409            }
12410            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12411            pw.println();
12412            if (dumpAll) {
12413                pw.println("-------------------------------------------------------------------------------");
12414            }
12415            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12416            pw.println();
12417            if (dumpAll) {
12418                pw.println("-------------------------------------------------------------------------------");
12419            }
12420            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12421        }
12422        Binder.restoreCallingIdentity(origId);
12423    }
12424
12425    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12426            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12427        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12428
12429        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12430                dumpPackage);
12431        boolean needSep = printedAnything;
12432
12433        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12434                dumpPackage, needSep, "  mFocusedActivity: ");
12435        if (printed) {
12436            printedAnything = true;
12437            needSep = false;
12438        }
12439
12440        if (dumpPackage == null) {
12441            if (needSep) {
12442                pw.println();
12443            }
12444            needSep = true;
12445            printedAnything = true;
12446            mStackSupervisor.dump(pw, "  ");
12447        }
12448
12449        if (!printedAnything) {
12450            pw.println("  (nothing)");
12451        }
12452    }
12453
12454    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12455            int opti, boolean dumpAll, String dumpPackage) {
12456        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12457
12458        boolean printedAnything = false;
12459
12460        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12461            boolean printedHeader = false;
12462
12463            final int N = mRecentTasks.size();
12464            for (int i=0; i<N; i++) {
12465                TaskRecord tr = mRecentTasks.get(i);
12466                if (dumpPackage != null) {
12467                    if (tr.realActivity == null ||
12468                            !dumpPackage.equals(tr.realActivity)) {
12469                        continue;
12470                    }
12471                }
12472                if (!printedHeader) {
12473                    pw.println("  Recent tasks:");
12474                    printedHeader = true;
12475                    printedAnything = true;
12476                }
12477                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12478                        pw.println(tr);
12479                if (dumpAll) {
12480                    mRecentTasks.get(i).dump(pw, "    ");
12481                }
12482            }
12483        }
12484
12485        if (!printedAnything) {
12486            pw.println("  (nothing)");
12487        }
12488    }
12489
12490    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12491            int opti, boolean dumpAll, String dumpPackage) {
12492        boolean needSep = false;
12493        boolean printedAnything = false;
12494        int numPers = 0;
12495
12496        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12497
12498        if (dumpAll) {
12499            final int NP = mProcessNames.getMap().size();
12500            for (int ip=0; ip<NP; ip++) {
12501                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12502                final int NA = procs.size();
12503                for (int ia=0; ia<NA; ia++) {
12504                    ProcessRecord r = procs.valueAt(ia);
12505                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12506                        continue;
12507                    }
12508                    if (!needSep) {
12509                        pw.println("  All known processes:");
12510                        needSep = true;
12511                        printedAnything = true;
12512                    }
12513                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12514                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12515                        pw.print(" "); pw.println(r);
12516                    r.dump(pw, "    ");
12517                    if (r.persistent) {
12518                        numPers++;
12519                    }
12520                }
12521            }
12522        }
12523
12524        if (mIsolatedProcesses.size() > 0) {
12525            boolean printed = false;
12526            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12527                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12528                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12529                    continue;
12530                }
12531                if (!printed) {
12532                    if (needSep) {
12533                        pw.println();
12534                    }
12535                    pw.println("  Isolated process list (sorted by uid):");
12536                    printedAnything = true;
12537                    printed = true;
12538                    needSep = true;
12539                }
12540                pw.println(String.format("%sIsolated #%2d: %s",
12541                        "    ", i, r.toString()));
12542            }
12543        }
12544
12545        if (mLruProcesses.size() > 0) {
12546            if (needSep) {
12547                pw.println();
12548            }
12549            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12550                    pw.print(" total, non-act at ");
12551                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12552                    pw.print(", non-svc at ");
12553                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12554                    pw.println("):");
12555            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12556            needSep = true;
12557            printedAnything = true;
12558        }
12559
12560        if (dumpAll || dumpPackage != null) {
12561            synchronized (mPidsSelfLocked) {
12562                boolean printed = false;
12563                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12564                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12565                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12566                        continue;
12567                    }
12568                    if (!printed) {
12569                        if (needSep) pw.println();
12570                        needSep = true;
12571                        pw.println("  PID mappings:");
12572                        printed = true;
12573                        printedAnything = true;
12574                    }
12575                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12576                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12577                }
12578            }
12579        }
12580
12581        if (mForegroundProcesses.size() > 0) {
12582            synchronized (mPidsSelfLocked) {
12583                boolean printed = false;
12584                for (int i=0; i<mForegroundProcesses.size(); i++) {
12585                    ProcessRecord r = mPidsSelfLocked.get(
12586                            mForegroundProcesses.valueAt(i).pid);
12587                    if (dumpPackage != null && (r == null
12588                            || !r.pkgList.containsKey(dumpPackage))) {
12589                        continue;
12590                    }
12591                    if (!printed) {
12592                        if (needSep) pw.println();
12593                        needSep = true;
12594                        pw.println("  Foreground Processes:");
12595                        printed = true;
12596                        printedAnything = true;
12597                    }
12598                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12599                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12600                }
12601            }
12602        }
12603
12604        if (mPersistentStartingProcesses.size() > 0) {
12605            if (needSep) pw.println();
12606            needSep = true;
12607            printedAnything = true;
12608            pw.println("  Persisent processes that are starting:");
12609            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12610                    "Starting Norm", "Restarting PERS", dumpPackage);
12611        }
12612
12613        if (mRemovedProcesses.size() > 0) {
12614            if (needSep) pw.println();
12615            needSep = true;
12616            printedAnything = true;
12617            pw.println("  Processes that are being removed:");
12618            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12619                    "Removed Norm", "Removed PERS", dumpPackage);
12620        }
12621
12622        if (mProcessesOnHold.size() > 0) {
12623            if (needSep) pw.println();
12624            needSep = true;
12625            printedAnything = true;
12626            pw.println("  Processes that are on old until the system is ready:");
12627            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12628                    "OnHold Norm", "OnHold PERS", dumpPackage);
12629        }
12630
12631        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12632
12633        if (mProcessCrashTimes.getMap().size() > 0) {
12634            boolean printed = false;
12635            long now = SystemClock.uptimeMillis();
12636            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12637            final int NP = pmap.size();
12638            for (int ip=0; ip<NP; ip++) {
12639                String pname = pmap.keyAt(ip);
12640                SparseArray<Long> uids = pmap.valueAt(ip);
12641                final int N = uids.size();
12642                for (int i=0; i<N; i++) {
12643                    int puid = uids.keyAt(i);
12644                    ProcessRecord r = mProcessNames.get(pname, puid);
12645                    if (dumpPackage != null && (r == null
12646                            || !r.pkgList.containsKey(dumpPackage))) {
12647                        continue;
12648                    }
12649                    if (!printed) {
12650                        if (needSep) pw.println();
12651                        needSep = true;
12652                        pw.println("  Time since processes crashed:");
12653                        printed = true;
12654                        printedAnything = true;
12655                    }
12656                    pw.print("    Process "); pw.print(pname);
12657                            pw.print(" uid "); pw.print(puid);
12658                            pw.print(": last crashed ");
12659                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12660                            pw.println(" ago");
12661                }
12662            }
12663        }
12664
12665        if (mBadProcesses.getMap().size() > 0) {
12666            boolean printed = false;
12667            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12668            final int NP = pmap.size();
12669            for (int ip=0; ip<NP; ip++) {
12670                String pname = pmap.keyAt(ip);
12671                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12672                final int N = uids.size();
12673                for (int i=0; i<N; i++) {
12674                    int puid = uids.keyAt(i);
12675                    ProcessRecord r = mProcessNames.get(pname, puid);
12676                    if (dumpPackage != null && (r == null
12677                            || !r.pkgList.containsKey(dumpPackage))) {
12678                        continue;
12679                    }
12680                    if (!printed) {
12681                        if (needSep) pw.println();
12682                        needSep = true;
12683                        pw.println("  Bad processes:");
12684                        printedAnything = true;
12685                    }
12686                    BadProcessInfo info = uids.valueAt(i);
12687                    pw.print("    Bad process "); pw.print(pname);
12688                            pw.print(" uid "); pw.print(puid);
12689                            pw.print(": crashed at time "); pw.println(info.time);
12690                    if (info.shortMsg != null) {
12691                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12692                    }
12693                    if (info.longMsg != null) {
12694                        pw.print("      Long msg: "); pw.println(info.longMsg);
12695                    }
12696                    if (info.stack != null) {
12697                        pw.println("      Stack:");
12698                        int lastPos = 0;
12699                        for (int pos=0; pos<info.stack.length(); pos++) {
12700                            if (info.stack.charAt(pos) == '\n') {
12701                                pw.print("        ");
12702                                pw.write(info.stack, lastPos, pos-lastPos);
12703                                pw.println();
12704                                lastPos = pos+1;
12705                            }
12706                        }
12707                        if (lastPos < info.stack.length()) {
12708                            pw.print("        ");
12709                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12710                            pw.println();
12711                        }
12712                    }
12713                }
12714            }
12715        }
12716
12717        if (dumpPackage == null) {
12718            pw.println();
12719            needSep = false;
12720            pw.println("  mStartedUsers:");
12721            for (int i=0; i<mStartedUsers.size(); i++) {
12722                UserStartedState uss = mStartedUsers.valueAt(i);
12723                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12724                        pw.print(": "); uss.dump("", pw);
12725            }
12726            pw.print("  mStartedUserArray: [");
12727            for (int i=0; i<mStartedUserArray.length; i++) {
12728                if (i > 0) pw.print(", ");
12729                pw.print(mStartedUserArray[i]);
12730            }
12731            pw.println("]");
12732            pw.print("  mUserLru: [");
12733            for (int i=0; i<mUserLru.size(); i++) {
12734                if (i > 0) pw.print(", ");
12735                pw.print(mUserLru.get(i));
12736            }
12737            pw.println("]");
12738            if (dumpAll) {
12739                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12740            }
12741            synchronized (mUserProfileGroupIdsSelfLocked) {
12742                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12743                    pw.println("  mUserProfileGroupIds:");
12744                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12745                        pw.print("    User #");
12746                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12747                        pw.print(" -> profile #");
12748                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12749                    }
12750                }
12751            }
12752        }
12753        if (mHomeProcess != null && (dumpPackage == null
12754                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12755            if (needSep) {
12756                pw.println();
12757                needSep = false;
12758            }
12759            pw.println("  mHomeProcess: " + mHomeProcess);
12760        }
12761        if (mPreviousProcess != null && (dumpPackage == null
12762                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12763            if (needSep) {
12764                pw.println();
12765                needSep = false;
12766            }
12767            pw.println("  mPreviousProcess: " + mPreviousProcess);
12768        }
12769        if (dumpAll) {
12770            StringBuilder sb = new StringBuilder(128);
12771            sb.append("  mPreviousProcessVisibleTime: ");
12772            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12773            pw.println(sb);
12774        }
12775        if (mHeavyWeightProcess != null && (dumpPackage == null
12776                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12777            if (needSep) {
12778                pw.println();
12779                needSep = false;
12780            }
12781            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12782        }
12783        if (dumpPackage == null) {
12784            pw.println("  mConfiguration: " + mConfiguration);
12785        }
12786        if (dumpAll) {
12787            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12788            if (mCompatModePackages.getPackages().size() > 0) {
12789                boolean printed = false;
12790                for (Map.Entry<String, Integer> entry
12791                        : mCompatModePackages.getPackages().entrySet()) {
12792                    String pkg = entry.getKey();
12793                    int mode = entry.getValue();
12794                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12795                        continue;
12796                    }
12797                    if (!printed) {
12798                        pw.println("  mScreenCompatPackages:");
12799                        printed = true;
12800                    }
12801                    pw.print("    "); pw.print(pkg); pw.print(": ");
12802                            pw.print(mode); pw.println();
12803                }
12804            }
12805        }
12806        if (dumpPackage == null) {
12807            if (mSleeping || mWentToSleep || mLockScreenShown != LOCK_SCREEN_HIDDEN) {
12808                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12809                        + " mLockScreenShown " + lockScreenShownToString());
12810            }
12811            if (mShuttingDown || mRunningVoice) {
12812                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12813            }
12814        }
12815        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12816                || mOrigWaitForDebugger) {
12817            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12818                    || dumpPackage.equals(mOrigDebugApp)) {
12819                if (needSep) {
12820                    pw.println();
12821                    needSep = false;
12822                }
12823                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12824                        + " mDebugTransient=" + mDebugTransient
12825                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12826            }
12827        }
12828        if (mOpenGlTraceApp != null) {
12829            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12830                if (needSep) {
12831                    pw.println();
12832                    needSep = false;
12833                }
12834                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12835            }
12836        }
12837        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12838                || mProfileFd != null) {
12839            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12840                if (needSep) {
12841                    pw.println();
12842                    needSep = false;
12843                }
12844                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12845                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12846                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12847                        + mAutoStopProfiler);
12848                pw.println("  mProfileType=" + mProfileType);
12849            }
12850        }
12851        if (dumpPackage == null) {
12852            if (mAlwaysFinishActivities || mController != null) {
12853                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12854                        + " mController=" + mController);
12855            }
12856            if (dumpAll) {
12857                pw.println("  Total persistent processes: " + numPers);
12858                pw.println("  mProcessesReady=" + mProcessesReady
12859                        + " mSystemReady=" + mSystemReady
12860                        + " mBooted=" + mBooted
12861                        + " mFactoryTest=" + mFactoryTest);
12862                pw.println("  mBooting=" + mBooting
12863                        + " mCallFinishBooting=" + mCallFinishBooting
12864                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12865                pw.print("  mLastPowerCheckRealtime=");
12866                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12867                        pw.println("");
12868                pw.print("  mLastPowerCheckUptime=");
12869                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12870                        pw.println("");
12871                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12872                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12873                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12874                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12875                        + " (" + mLruProcesses.size() + " total)"
12876                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12877                        + " mNumServiceProcs=" + mNumServiceProcs
12878                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12879                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12880                        + " mLastMemoryLevel" + mLastMemoryLevel
12881                        + " mLastNumProcesses" + mLastNumProcesses);
12882                long now = SystemClock.uptimeMillis();
12883                pw.print("  mLastIdleTime=");
12884                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12885                        pw.print(" mLowRamSinceLastIdle=");
12886                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12887                        pw.println();
12888            }
12889        }
12890
12891        if (!printedAnything) {
12892            pw.println("  (nothing)");
12893        }
12894    }
12895
12896    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12897            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12898        if (mProcessesToGc.size() > 0) {
12899            boolean printed = false;
12900            long now = SystemClock.uptimeMillis();
12901            for (int i=0; i<mProcessesToGc.size(); i++) {
12902                ProcessRecord proc = mProcessesToGc.get(i);
12903                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12904                    continue;
12905                }
12906                if (!printed) {
12907                    if (needSep) pw.println();
12908                    needSep = true;
12909                    pw.println("  Processes that are waiting to GC:");
12910                    printed = true;
12911                }
12912                pw.print("    Process "); pw.println(proc);
12913                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12914                        pw.print(", last gced=");
12915                        pw.print(now-proc.lastRequestedGc);
12916                        pw.print(" ms ago, last lowMem=");
12917                        pw.print(now-proc.lastLowMemory);
12918                        pw.println(" ms ago");
12919
12920            }
12921        }
12922        return needSep;
12923    }
12924
12925    void printOomLevel(PrintWriter pw, String name, int adj) {
12926        pw.print("    ");
12927        if (adj >= 0) {
12928            pw.print(' ');
12929            if (adj < 10) pw.print(' ');
12930        } else {
12931            if (adj > -10) pw.print(' ');
12932        }
12933        pw.print(adj);
12934        pw.print(": ");
12935        pw.print(name);
12936        pw.print(" (");
12937        pw.print(mProcessList.getMemLevel(adj)/1024);
12938        pw.println(" kB)");
12939    }
12940
12941    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12942            int opti, boolean dumpAll) {
12943        boolean needSep = false;
12944
12945        if (mLruProcesses.size() > 0) {
12946            if (needSep) pw.println();
12947            needSep = true;
12948            pw.println("  OOM levels:");
12949            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12950            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12951            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12952            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12953            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12954            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12955            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12956            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12957            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12958            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12959            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12960            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12961            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12962            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12963
12964            if (needSep) pw.println();
12965            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12966                    pw.print(" total, non-act at ");
12967                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12968                    pw.print(", non-svc at ");
12969                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12970                    pw.println("):");
12971            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12972            needSep = true;
12973        }
12974
12975        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12976
12977        pw.println();
12978        pw.println("  mHomeProcess: " + mHomeProcess);
12979        pw.println("  mPreviousProcess: " + mPreviousProcess);
12980        if (mHeavyWeightProcess != null) {
12981            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12982        }
12983
12984        return true;
12985    }
12986
12987    /**
12988     * There are three ways to call this:
12989     *  - no provider specified: dump all the providers
12990     *  - a flattened component name that matched an existing provider was specified as the
12991     *    first arg: dump that one provider
12992     *  - the first arg isn't the flattened component name of an existing provider:
12993     *    dump all providers whose component contains the first arg as a substring
12994     */
12995    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12996            int opti, boolean dumpAll) {
12997        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12998    }
12999
13000    static class ItemMatcher {
13001        ArrayList<ComponentName> components;
13002        ArrayList<String> strings;
13003        ArrayList<Integer> objects;
13004        boolean all;
13005
13006        ItemMatcher() {
13007            all = true;
13008        }
13009
13010        void build(String name) {
13011            ComponentName componentName = ComponentName.unflattenFromString(name);
13012            if (componentName != null) {
13013                if (components == null) {
13014                    components = new ArrayList<ComponentName>();
13015                }
13016                components.add(componentName);
13017                all = false;
13018            } else {
13019                int objectId = 0;
13020                // Not a '/' separated full component name; maybe an object ID?
13021                try {
13022                    objectId = Integer.parseInt(name, 16);
13023                    if (objects == null) {
13024                        objects = new ArrayList<Integer>();
13025                    }
13026                    objects.add(objectId);
13027                    all = false;
13028                } catch (RuntimeException e) {
13029                    // Not an integer; just do string match.
13030                    if (strings == null) {
13031                        strings = new ArrayList<String>();
13032                    }
13033                    strings.add(name);
13034                    all = false;
13035                }
13036            }
13037        }
13038
13039        int build(String[] args, int opti) {
13040            for (; opti<args.length; opti++) {
13041                String name = args[opti];
13042                if ("--".equals(name)) {
13043                    return opti+1;
13044                }
13045                build(name);
13046            }
13047            return opti;
13048        }
13049
13050        boolean match(Object object, ComponentName comp) {
13051            if (all) {
13052                return true;
13053            }
13054            if (components != null) {
13055                for (int i=0; i<components.size(); i++) {
13056                    if (components.get(i).equals(comp)) {
13057                        return true;
13058                    }
13059                }
13060            }
13061            if (objects != null) {
13062                for (int i=0; i<objects.size(); i++) {
13063                    if (System.identityHashCode(object) == objects.get(i)) {
13064                        return true;
13065                    }
13066                }
13067            }
13068            if (strings != null) {
13069                String flat = comp.flattenToString();
13070                for (int i=0; i<strings.size(); i++) {
13071                    if (flat.contains(strings.get(i))) {
13072                        return true;
13073                    }
13074                }
13075            }
13076            return false;
13077        }
13078    }
13079
13080    /**
13081     * There are three things that cmd can be:
13082     *  - a flattened component name that matches an existing activity
13083     *  - the cmd arg isn't the flattened component name of an existing activity:
13084     *    dump all activity whose component contains the cmd as a substring
13085     *  - A hex number of the ActivityRecord object instance.
13086     */
13087    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13088            int opti, boolean dumpAll) {
13089        ArrayList<ActivityRecord> activities;
13090
13091        synchronized (this) {
13092            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13093        }
13094
13095        if (activities.size() <= 0) {
13096            return false;
13097        }
13098
13099        String[] newArgs = new String[args.length - opti];
13100        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13101
13102        TaskRecord lastTask = null;
13103        boolean needSep = false;
13104        for (int i=activities.size()-1; i>=0; i--) {
13105            ActivityRecord r = activities.get(i);
13106            if (needSep) {
13107                pw.println();
13108            }
13109            needSep = true;
13110            synchronized (this) {
13111                if (lastTask != r.task) {
13112                    lastTask = r.task;
13113                    pw.print("TASK "); pw.print(lastTask.affinity);
13114                            pw.print(" id="); pw.println(lastTask.taskId);
13115                    if (dumpAll) {
13116                        lastTask.dump(pw, "  ");
13117                    }
13118                }
13119            }
13120            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13121        }
13122        return true;
13123    }
13124
13125    /**
13126     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13127     * there is a thread associated with the activity.
13128     */
13129    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13130            final ActivityRecord r, String[] args, boolean dumpAll) {
13131        String innerPrefix = prefix + "  ";
13132        synchronized (this) {
13133            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13134                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13135                    pw.print(" pid=");
13136                    if (r.app != null) pw.println(r.app.pid);
13137                    else pw.println("(not running)");
13138            if (dumpAll) {
13139                r.dump(pw, innerPrefix);
13140            }
13141        }
13142        if (r.app != null && r.app.thread != null) {
13143            // flush anything that is already in the PrintWriter since the thread is going
13144            // to write to the file descriptor directly
13145            pw.flush();
13146            try {
13147                TransferPipe tp = new TransferPipe();
13148                try {
13149                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13150                            r.appToken, innerPrefix, args);
13151                    tp.go(fd);
13152                } finally {
13153                    tp.kill();
13154                }
13155            } catch (IOException e) {
13156                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13157            } catch (RemoteException e) {
13158                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13159            }
13160        }
13161    }
13162
13163    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13164            int opti, boolean dumpAll, String dumpPackage) {
13165        boolean needSep = false;
13166        boolean onlyHistory = false;
13167        boolean printedAnything = false;
13168
13169        if ("history".equals(dumpPackage)) {
13170            if (opti < args.length && "-s".equals(args[opti])) {
13171                dumpAll = false;
13172            }
13173            onlyHistory = true;
13174            dumpPackage = null;
13175        }
13176
13177        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13178        if (!onlyHistory && dumpAll) {
13179            if (mRegisteredReceivers.size() > 0) {
13180                boolean printed = false;
13181                Iterator it = mRegisteredReceivers.values().iterator();
13182                while (it.hasNext()) {
13183                    ReceiverList r = (ReceiverList)it.next();
13184                    if (dumpPackage != null && (r.app == null ||
13185                            !dumpPackage.equals(r.app.info.packageName))) {
13186                        continue;
13187                    }
13188                    if (!printed) {
13189                        pw.println("  Registered Receivers:");
13190                        needSep = true;
13191                        printed = true;
13192                        printedAnything = true;
13193                    }
13194                    pw.print("  * "); pw.println(r);
13195                    r.dump(pw, "    ");
13196                }
13197            }
13198
13199            if (mReceiverResolver.dump(pw, needSep ?
13200                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13201                    "    ", dumpPackage, false)) {
13202                needSep = true;
13203                printedAnything = true;
13204            }
13205        }
13206
13207        for (BroadcastQueue q : mBroadcastQueues) {
13208            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13209            printedAnything |= needSep;
13210        }
13211
13212        needSep = true;
13213
13214        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13215            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13216                if (needSep) {
13217                    pw.println();
13218                }
13219                needSep = true;
13220                printedAnything = true;
13221                pw.print("  Sticky broadcasts for user ");
13222                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13223                StringBuilder sb = new StringBuilder(128);
13224                for (Map.Entry<String, ArrayList<Intent>> ent
13225                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13226                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13227                    if (dumpAll) {
13228                        pw.println(":");
13229                        ArrayList<Intent> intents = ent.getValue();
13230                        final int N = intents.size();
13231                        for (int i=0; i<N; i++) {
13232                            sb.setLength(0);
13233                            sb.append("    Intent: ");
13234                            intents.get(i).toShortString(sb, false, true, false, false);
13235                            pw.println(sb.toString());
13236                            Bundle bundle = intents.get(i).getExtras();
13237                            if (bundle != null) {
13238                                pw.print("      ");
13239                                pw.println(bundle.toString());
13240                            }
13241                        }
13242                    } else {
13243                        pw.println("");
13244                    }
13245                }
13246            }
13247        }
13248
13249        if (!onlyHistory && dumpAll) {
13250            pw.println();
13251            for (BroadcastQueue queue : mBroadcastQueues) {
13252                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13253                        + queue.mBroadcastsScheduled);
13254            }
13255            pw.println("  mHandler:");
13256            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13257            needSep = true;
13258            printedAnything = true;
13259        }
13260
13261        if (!printedAnything) {
13262            pw.println("  (nothing)");
13263        }
13264    }
13265
13266    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13267            int opti, boolean dumpAll, String dumpPackage) {
13268        boolean needSep;
13269        boolean printedAnything = false;
13270
13271        ItemMatcher matcher = new ItemMatcher();
13272        matcher.build(args, opti);
13273
13274        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13275
13276        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13277        printedAnything |= needSep;
13278
13279        if (mLaunchingProviders.size() > 0) {
13280            boolean printed = false;
13281            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13282                ContentProviderRecord r = mLaunchingProviders.get(i);
13283                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13284                    continue;
13285                }
13286                if (!printed) {
13287                    if (needSep) pw.println();
13288                    needSep = true;
13289                    pw.println("  Launching content providers:");
13290                    printed = true;
13291                    printedAnything = true;
13292                }
13293                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13294                        pw.println(r);
13295            }
13296        }
13297
13298        if (mGrantedUriPermissions.size() > 0) {
13299            boolean printed = false;
13300            int dumpUid = -2;
13301            if (dumpPackage != null) {
13302                try {
13303                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13304                } catch (NameNotFoundException e) {
13305                    dumpUid = -1;
13306                }
13307            }
13308            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13309                int uid = mGrantedUriPermissions.keyAt(i);
13310                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13311                    continue;
13312                }
13313                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13314                if (!printed) {
13315                    if (needSep) pw.println();
13316                    needSep = true;
13317                    pw.println("  Granted Uri Permissions:");
13318                    printed = true;
13319                    printedAnything = true;
13320                }
13321                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13322                for (UriPermission perm : perms.values()) {
13323                    pw.print("    "); pw.println(perm);
13324                    if (dumpAll) {
13325                        perm.dump(pw, "      ");
13326                    }
13327                }
13328            }
13329        }
13330
13331        if (!printedAnything) {
13332            pw.println("  (nothing)");
13333        }
13334    }
13335
13336    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13337            int opti, boolean dumpAll, String dumpPackage) {
13338        boolean printed = false;
13339
13340        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13341
13342        if (mIntentSenderRecords.size() > 0) {
13343            Iterator<WeakReference<PendingIntentRecord>> it
13344                    = mIntentSenderRecords.values().iterator();
13345            while (it.hasNext()) {
13346                WeakReference<PendingIntentRecord> ref = it.next();
13347                PendingIntentRecord rec = ref != null ? ref.get(): null;
13348                if (dumpPackage != null && (rec == null
13349                        || !dumpPackage.equals(rec.key.packageName))) {
13350                    continue;
13351                }
13352                printed = true;
13353                if (rec != null) {
13354                    pw.print("  * "); pw.println(rec);
13355                    if (dumpAll) {
13356                        rec.dump(pw, "    ");
13357                    }
13358                } else {
13359                    pw.print("  * "); pw.println(ref);
13360                }
13361            }
13362        }
13363
13364        if (!printed) {
13365            pw.println("  (nothing)");
13366        }
13367    }
13368
13369    private static final int dumpProcessList(PrintWriter pw,
13370            ActivityManagerService service, List list,
13371            String prefix, String normalLabel, String persistentLabel,
13372            String dumpPackage) {
13373        int numPers = 0;
13374        final int N = list.size()-1;
13375        for (int i=N; i>=0; i--) {
13376            ProcessRecord r = (ProcessRecord)list.get(i);
13377            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13378                continue;
13379            }
13380            pw.println(String.format("%s%s #%2d: %s",
13381                    prefix, (r.persistent ? persistentLabel : normalLabel),
13382                    i, r.toString()));
13383            if (r.persistent) {
13384                numPers++;
13385            }
13386        }
13387        return numPers;
13388    }
13389
13390    private static final boolean dumpProcessOomList(PrintWriter pw,
13391            ActivityManagerService service, List<ProcessRecord> origList,
13392            String prefix, String normalLabel, String persistentLabel,
13393            boolean inclDetails, String dumpPackage) {
13394
13395        ArrayList<Pair<ProcessRecord, Integer>> list
13396                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13397        for (int i=0; i<origList.size(); i++) {
13398            ProcessRecord r = origList.get(i);
13399            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13400                continue;
13401            }
13402            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13403        }
13404
13405        if (list.size() <= 0) {
13406            return false;
13407        }
13408
13409        Comparator<Pair<ProcessRecord, Integer>> comparator
13410                = new Comparator<Pair<ProcessRecord, Integer>>() {
13411            @Override
13412            public int compare(Pair<ProcessRecord, Integer> object1,
13413                    Pair<ProcessRecord, Integer> object2) {
13414                if (object1.first.setAdj != object2.first.setAdj) {
13415                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13416                }
13417                if (object1.second.intValue() != object2.second.intValue()) {
13418                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13419                }
13420                return 0;
13421            }
13422        };
13423
13424        Collections.sort(list, comparator);
13425
13426        final long curRealtime = SystemClock.elapsedRealtime();
13427        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13428        final long curUptime = SystemClock.uptimeMillis();
13429        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13430
13431        for (int i=list.size()-1; i>=0; i--) {
13432            ProcessRecord r = list.get(i).first;
13433            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13434            char schedGroup;
13435            switch (r.setSchedGroup) {
13436                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13437                    schedGroup = 'B';
13438                    break;
13439                case Process.THREAD_GROUP_DEFAULT:
13440                    schedGroup = 'F';
13441                    break;
13442                default:
13443                    schedGroup = '?';
13444                    break;
13445            }
13446            char foreground;
13447            if (r.foregroundActivities) {
13448                foreground = 'A';
13449            } else if (r.foregroundServices) {
13450                foreground = 'S';
13451            } else {
13452                foreground = ' ';
13453            }
13454            String procState = ProcessList.makeProcStateString(r.curProcState);
13455            pw.print(prefix);
13456            pw.print(r.persistent ? persistentLabel : normalLabel);
13457            pw.print(" #");
13458            int num = (origList.size()-1)-list.get(i).second;
13459            if (num < 10) pw.print(' ');
13460            pw.print(num);
13461            pw.print(": ");
13462            pw.print(oomAdj);
13463            pw.print(' ');
13464            pw.print(schedGroup);
13465            pw.print('/');
13466            pw.print(foreground);
13467            pw.print('/');
13468            pw.print(procState);
13469            pw.print(" trm:");
13470            if (r.trimMemoryLevel < 10) pw.print(' ');
13471            pw.print(r.trimMemoryLevel);
13472            pw.print(' ');
13473            pw.print(r.toShortString());
13474            pw.print(" (");
13475            pw.print(r.adjType);
13476            pw.println(')');
13477            if (r.adjSource != null || r.adjTarget != null) {
13478                pw.print(prefix);
13479                pw.print("    ");
13480                if (r.adjTarget instanceof ComponentName) {
13481                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13482                } else if (r.adjTarget != null) {
13483                    pw.print(r.adjTarget.toString());
13484                } else {
13485                    pw.print("{null}");
13486                }
13487                pw.print("<=");
13488                if (r.adjSource instanceof ProcessRecord) {
13489                    pw.print("Proc{");
13490                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13491                    pw.println("}");
13492                } else if (r.adjSource != null) {
13493                    pw.println(r.adjSource.toString());
13494                } else {
13495                    pw.println("{null}");
13496                }
13497            }
13498            if (inclDetails) {
13499                pw.print(prefix);
13500                pw.print("    ");
13501                pw.print("oom: max="); pw.print(r.maxAdj);
13502                pw.print(" curRaw="); pw.print(r.curRawAdj);
13503                pw.print(" setRaw="); pw.print(r.setRawAdj);
13504                pw.print(" cur="); pw.print(r.curAdj);
13505                pw.print(" set="); pw.println(r.setAdj);
13506                pw.print(prefix);
13507                pw.print("    ");
13508                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13509                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13510                pw.print(" lastPss="); pw.print(r.lastPss);
13511                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13512                pw.print(prefix);
13513                pw.print("    ");
13514                pw.print("cached="); pw.print(r.cached);
13515                pw.print(" empty="); pw.print(r.empty);
13516                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13517
13518                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13519                    if (r.lastWakeTime != 0) {
13520                        long wtime;
13521                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13522                        synchronized (stats) {
13523                            wtime = stats.getProcessWakeTime(r.info.uid,
13524                                    r.pid, curRealtime);
13525                        }
13526                        long timeUsed = wtime - r.lastWakeTime;
13527                        pw.print(prefix);
13528                        pw.print("    ");
13529                        pw.print("keep awake over ");
13530                        TimeUtils.formatDuration(realtimeSince, pw);
13531                        pw.print(" used ");
13532                        TimeUtils.formatDuration(timeUsed, pw);
13533                        pw.print(" (");
13534                        pw.print((timeUsed*100)/realtimeSince);
13535                        pw.println("%)");
13536                    }
13537                    if (r.lastCpuTime != 0) {
13538                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13539                        pw.print(prefix);
13540                        pw.print("    ");
13541                        pw.print("run cpu over ");
13542                        TimeUtils.formatDuration(uptimeSince, pw);
13543                        pw.print(" used ");
13544                        TimeUtils.formatDuration(timeUsed, pw);
13545                        pw.print(" (");
13546                        pw.print((timeUsed*100)/uptimeSince);
13547                        pw.println("%)");
13548                    }
13549                }
13550            }
13551        }
13552        return true;
13553    }
13554
13555    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13556            String[] args) {
13557        ArrayList<ProcessRecord> procs;
13558        synchronized (this) {
13559            if (args != null && args.length > start
13560                    && args[start].charAt(0) != '-') {
13561                procs = new ArrayList<ProcessRecord>();
13562                int pid = -1;
13563                try {
13564                    pid = Integer.parseInt(args[start]);
13565                } catch (NumberFormatException e) {
13566                }
13567                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13568                    ProcessRecord proc = mLruProcesses.get(i);
13569                    if (proc.pid == pid) {
13570                        procs.add(proc);
13571                    } else if (allPkgs && proc.pkgList != null
13572                            && proc.pkgList.containsKey(args[start])) {
13573                        procs.add(proc);
13574                    } else if (proc.processName.equals(args[start])) {
13575                        procs.add(proc);
13576                    }
13577                }
13578                if (procs.size() <= 0) {
13579                    return null;
13580                }
13581            } else {
13582                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13583            }
13584        }
13585        return procs;
13586    }
13587
13588    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13589            PrintWriter pw, String[] args) {
13590        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13591        if (procs == null) {
13592            pw.println("No process found for: " + args[0]);
13593            return;
13594        }
13595
13596        long uptime = SystemClock.uptimeMillis();
13597        long realtime = SystemClock.elapsedRealtime();
13598        pw.println("Applications Graphics Acceleration Info:");
13599        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13600
13601        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13602            ProcessRecord r = procs.get(i);
13603            if (r.thread != null) {
13604                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13605                pw.flush();
13606                try {
13607                    TransferPipe tp = new TransferPipe();
13608                    try {
13609                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13610                        tp.go(fd);
13611                    } finally {
13612                        tp.kill();
13613                    }
13614                } catch (IOException e) {
13615                    pw.println("Failure while dumping the app: " + r);
13616                    pw.flush();
13617                } catch (RemoteException e) {
13618                    pw.println("Got a RemoteException while dumping the app " + r);
13619                    pw.flush();
13620                }
13621            }
13622        }
13623    }
13624
13625    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13626        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13627        if (procs == null) {
13628            pw.println("No process found for: " + args[0]);
13629            return;
13630        }
13631
13632        pw.println("Applications Database Info:");
13633
13634        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13635            ProcessRecord r = procs.get(i);
13636            if (r.thread != null) {
13637                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13638                pw.flush();
13639                try {
13640                    TransferPipe tp = new TransferPipe();
13641                    try {
13642                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13643                        tp.go(fd);
13644                    } finally {
13645                        tp.kill();
13646                    }
13647                } catch (IOException e) {
13648                    pw.println("Failure while dumping the app: " + r);
13649                    pw.flush();
13650                } catch (RemoteException e) {
13651                    pw.println("Got a RemoteException while dumping the app " + r);
13652                    pw.flush();
13653                }
13654            }
13655        }
13656    }
13657
13658    final static class MemItem {
13659        final boolean isProc;
13660        final String label;
13661        final String shortLabel;
13662        final long pss;
13663        final int id;
13664        final boolean hasActivities;
13665        ArrayList<MemItem> subitems;
13666
13667        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13668                boolean _hasActivities) {
13669            isProc = true;
13670            label = _label;
13671            shortLabel = _shortLabel;
13672            pss = _pss;
13673            id = _id;
13674            hasActivities = _hasActivities;
13675        }
13676
13677        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13678            isProc = false;
13679            label = _label;
13680            shortLabel = _shortLabel;
13681            pss = _pss;
13682            id = _id;
13683            hasActivities = false;
13684        }
13685    }
13686
13687    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13688            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13689        if (sort && !isCompact) {
13690            Collections.sort(items, new Comparator<MemItem>() {
13691                @Override
13692                public int compare(MemItem lhs, MemItem rhs) {
13693                    if (lhs.pss < rhs.pss) {
13694                        return 1;
13695                    } else if (lhs.pss > rhs.pss) {
13696                        return -1;
13697                    }
13698                    return 0;
13699                }
13700            });
13701        }
13702
13703        for (int i=0; i<items.size(); i++) {
13704            MemItem mi = items.get(i);
13705            if (!isCompact) {
13706                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13707            } else if (mi.isProc) {
13708                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13709                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13710                pw.println(mi.hasActivities ? ",a" : ",e");
13711            } else {
13712                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13713                pw.println(mi.pss);
13714            }
13715            if (mi.subitems != null) {
13716                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13717                        true, isCompact);
13718            }
13719        }
13720    }
13721
13722    // These are in KB.
13723    static final long[] DUMP_MEM_BUCKETS = new long[] {
13724        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13725        120*1024, 160*1024, 200*1024,
13726        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13727        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13728    };
13729
13730    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13731            boolean stackLike) {
13732        int start = label.lastIndexOf('.');
13733        if (start >= 0) start++;
13734        else start = 0;
13735        int end = label.length();
13736        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13737            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13738                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13739                out.append(bucket);
13740                out.append(stackLike ? "MB." : "MB ");
13741                out.append(label, start, end);
13742                return;
13743            }
13744        }
13745        out.append(memKB/1024);
13746        out.append(stackLike ? "MB." : "MB ");
13747        out.append(label, start, end);
13748    }
13749
13750    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13751            ProcessList.NATIVE_ADJ,
13752            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13753            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13754            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13755            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13756            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13757            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13758    };
13759    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13760            "Native",
13761            "System", "Persistent", "Persistent Service", "Foreground",
13762            "Visible", "Perceptible",
13763            "Heavy Weight", "Backup",
13764            "A Services", "Home",
13765            "Previous", "B Services", "Cached"
13766    };
13767    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13768            "native",
13769            "sys", "pers", "persvc", "fore",
13770            "vis", "percept",
13771            "heavy", "backup",
13772            "servicea", "home",
13773            "prev", "serviceb", "cached"
13774    };
13775
13776    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13777            long realtime, boolean isCheckinRequest, boolean isCompact) {
13778        if (isCheckinRequest || isCompact) {
13779            // short checkin version
13780            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13781        } else {
13782            pw.println("Applications Memory Usage (kB):");
13783            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13784        }
13785    }
13786
13787    private static final int KSM_SHARED = 0;
13788    private static final int KSM_SHARING = 1;
13789    private static final int KSM_UNSHARED = 2;
13790    private static final int KSM_VOLATILE = 3;
13791
13792    private final long[] getKsmInfo() {
13793        long[] longOut = new long[4];
13794        final int[] SINGLE_LONG_FORMAT = new int[] {
13795            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13796        };
13797        long[] longTmp = new long[1];
13798        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13799                SINGLE_LONG_FORMAT, null, longTmp, null);
13800        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13801        longTmp[0] = 0;
13802        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13803                SINGLE_LONG_FORMAT, null, longTmp, null);
13804        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13805        longTmp[0] = 0;
13806        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13807                SINGLE_LONG_FORMAT, null, longTmp, null);
13808        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13809        longTmp[0] = 0;
13810        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13811                SINGLE_LONG_FORMAT, null, longTmp, null);
13812        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13813        return longOut;
13814    }
13815
13816    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13817            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13818        boolean dumpDetails = false;
13819        boolean dumpFullDetails = false;
13820        boolean dumpDalvik = false;
13821        boolean oomOnly = false;
13822        boolean isCompact = false;
13823        boolean localOnly = false;
13824        boolean packages = false;
13825
13826        int opti = 0;
13827        while (opti < args.length) {
13828            String opt = args[opti];
13829            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13830                break;
13831            }
13832            opti++;
13833            if ("-a".equals(opt)) {
13834                dumpDetails = true;
13835                dumpFullDetails = true;
13836                dumpDalvik = true;
13837            } else if ("-d".equals(opt)) {
13838                dumpDalvik = true;
13839            } else if ("-c".equals(opt)) {
13840                isCompact = true;
13841            } else if ("--oom".equals(opt)) {
13842                oomOnly = true;
13843            } else if ("--local".equals(opt)) {
13844                localOnly = true;
13845            } else if ("--package".equals(opt)) {
13846                packages = true;
13847            } else if ("-h".equals(opt)) {
13848                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13849                pw.println("  -a: include all available information for each process.");
13850                pw.println("  -d: include dalvik details when dumping process details.");
13851                pw.println("  -c: dump in a compact machine-parseable representation.");
13852                pw.println("  --oom: only show processes organized by oom adj.");
13853                pw.println("  --local: only collect details locally, don't call process.");
13854                pw.println("  --package: interpret process arg as package, dumping all");
13855                pw.println("             processes that have loaded that package.");
13856                pw.println("If [process] is specified it can be the name or ");
13857                pw.println("pid of a specific process to dump.");
13858                return;
13859            } else {
13860                pw.println("Unknown argument: " + opt + "; use -h for help");
13861            }
13862        }
13863
13864        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13865        long uptime = SystemClock.uptimeMillis();
13866        long realtime = SystemClock.elapsedRealtime();
13867        final long[] tmpLong = new long[1];
13868
13869        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13870        if (procs == null) {
13871            // No Java processes.  Maybe they want to print a native process.
13872            if (args != null && args.length > opti
13873                    && args[opti].charAt(0) != '-') {
13874                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13875                        = new ArrayList<ProcessCpuTracker.Stats>();
13876                updateCpuStatsNow();
13877                int findPid = -1;
13878                try {
13879                    findPid = Integer.parseInt(args[opti]);
13880                } catch (NumberFormatException e) {
13881                }
13882                synchronized (mProcessCpuTracker) {
13883                    final int N = mProcessCpuTracker.countStats();
13884                    for (int i=0; i<N; i++) {
13885                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13886                        if (st.pid == findPid || (st.baseName != null
13887                                && st.baseName.equals(args[opti]))) {
13888                            nativeProcs.add(st);
13889                        }
13890                    }
13891                }
13892                if (nativeProcs.size() > 0) {
13893                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13894                            isCompact);
13895                    Debug.MemoryInfo mi = null;
13896                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13897                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13898                        final int pid = r.pid;
13899                        if (!isCheckinRequest && dumpDetails) {
13900                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13901                        }
13902                        if (mi == null) {
13903                            mi = new Debug.MemoryInfo();
13904                        }
13905                        if (dumpDetails || (!brief && !oomOnly)) {
13906                            Debug.getMemoryInfo(pid, mi);
13907                        } else {
13908                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13909                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13910                        }
13911                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13912                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13913                        if (isCheckinRequest) {
13914                            pw.println();
13915                        }
13916                    }
13917                    return;
13918                }
13919            }
13920            pw.println("No process found for: " + args[opti]);
13921            return;
13922        }
13923
13924        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13925            dumpDetails = true;
13926        }
13927
13928        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13929
13930        String[] innerArgs = new String[args.length-opti];
13931        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13932
13933        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13934        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13935        long nativePss=0, dalvikPss=0, otherPss=0;
13936        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13937
13938        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13939        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13940                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13941
13942        long totalPss = 0;
13943        long cachedPss = 0;
13944
13945        Debug.MemoryInfo mi = null;
13946        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13947            final ProcessRecord r = procs.get(i);
13948            final IApplicationThread thread;
13949            final int pid;
13950            final int oomAdj;
13951            final boolean hasActivities;
13952            synchronized (this) {
13953                thread = r.thread;
13954                pid = r.pid;
13955                oomAdj = r.getSetAdjWithServices();
13956                hasActivities = r.activities.size() > 0;
13957            }
13958            if (thread != null) {
13959                if (!isCheckinRequest && dumpDetails) {
13960                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13961                }
13962                if (mi == null) {
13963                    mi = new Debug.MemoryInfo();
13964                }
13965                if (dumpDetails || (!brief && !oomOnly)) {
13966                    Debug.getMemoryInfo(pid, mi);
13967                } else {
13968                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13969                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13970                }
13971                if (dumpDetails) {
13972                    if (localOnly) {
13973                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13974                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13975                        if (isCheckinRequest) {
13976                            pw.println();
13977                        }
13978                    } else {
13979                        try {
13980                            pw.flush();
13981                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13982                                    dumpDalvik, innerArgs);
13983                        } catch (RemoteException e) {
13984                            if (!isCheckinRequest) {
13985                                pw.println("Got RemoteException!");
13986                                pw.flush();
13987                            }
13988                        }
13989                    }
13990                }
13991
13992                final long myTotalPss = mi.getTotalPss();
13993                final long myTotalUss = mi.getTotalUss();
13994
13995                synchronized (this) {
13996                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13997                        // Record this for posterity if the process has been stable.
13998                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13999                    }
14000                }
14001
14002                if (!isCheckinRequest && mi != null) {
14003                    totalPss += myTotalPss;
14004                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14005                            (hasActivities ? " / activities)" : ")"),
14006                            r.processName, myTotalPss, pid, hasActivities);
14007                    procMems.add(pssItem);
14008                    procMemsMap.put(pid, pssItem);
14009
14010                    nativePss += mi.nativePss;
14011                    dalvikPss += mi.dalvikPss;
14012                    otherPss += mi.otherPss;
14013                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14014                        long mem = mi.getOtherPss(j);
14015                        miscPss[j] += mem;
14016                        otherPss -= mem;
14017                    }
14018
14019                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14020                        cachedPss += myTotalPss;
14021                    }
14022
14023                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14024                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14025                                || oomIndex == (oomPss.length-1)) {
14026                            oomPss[oomIndex] += myTotalPss;
14027                            if (oomProcs[oomIndex] == null) {
14028                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14029                            }
14030                            oomProcs[oomIndex].add(pssItem);
14031                            break;
14032                        }
14033                    }
14034                }
14035            }
14036        }
14037
14038        long nativeProcTotalPss = 0;
14039
14040        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14041            // If we are showing aggregations, also look for native processes to
14042            // include so that our aggregations are more accurate.
14043            updateCpuStatsNow();
14044            synchronized (mProcessCpuTracker) {
14045                final int N = mProcessCpuTracker.countStats();
14046                for (int i=0; i<N; i++) {
14047                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14048                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14049                        if (mi == null) {
14050                            mi = new Debug.MemoryInfo();
14051                        }
14052                        if (!brief && !oomOnly) {
14053                            Debug.getMemoryInfo(st.pid, mi);
14054                        } else {
14055                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14056                            mi.nativePrivateDirty = (int)tmpLong[0];
14057                        }
14058
14059                        final long myTotalPss = mi.getTotalPss();
14060                        totalPss += myTotalPss;
14061                        nativeProcTotalPss += myTotalPss;
14062
14063                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14064                                st.name, myTotalPss, st.pid, false);
14065                        procMems.add(pssItem);
14066
14067                        nativePss += mi.nativePss;
14068                        dalvikPss += mi.dalvikPss;
14069                        otherPss += mi.otherPss;
14070                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14071                            long mem = mi.getOtherPss(j);
14072                            miscPss[j] += mem;
14073                            otherPss -= mem;
14074                        }
14075                        oomPss[0] += myTotalPss;
14076                        if (oomProcs[0] == null) {
14077                            oomProcs[0] = new ArrayList<MemItem>();
14078                        }
14079                        oomProcs[0].add(pssItem);
14080                    }
14081                }
14082            }
14083
14084            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14085
14086            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14087            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14088            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14089            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14090                String label = Debug.MemoryInfo.getOtherLabel(j);
14091                catMems.add(new MemItem(label, label, miscPss[j], j));
14092            }
14093
14094            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14095            for (int j=0; j<oomPss.length; j++) {
14096                if (oomPss[j] != 0) {
14097                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14098                            : DUMP_MEM_OOM_LABEL[j];
14099                    MemItem item = new MemItem(label, label, oomPss[j],
14100                            DUMP_MEM_OOM_ADJ[j]);
14101                    item.subitems = oomProcs[j];
14102                    oomMems.add(item);
14103                }
14104            }
14105
14106            if (!brief && !oomOnly && !isCompact) {
14107                pw.println();
14108                pw.println("Total PSS by process:");
14109                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14110                pw.println();
14111            }
14112            if (!isCompact) {
14113                pw.println("Total PSS by OOM adjustment:");
14114            }
14115            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14116            if (!brief && !oomOnly) {
14117                PrintWriter out = categoryPw != null ? categoryPw : pw;
14118                if (!isCompact) {
14119                    out.println();
14120                    out.println("Total PSS by category:");
14121                }
14122                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14123            }
14124            if (!isCompact) {
14125                pw.println();
14126            }
14127            MemInfoReader memInfo = new MemInfoReader();
14128            memInfo.readMemInfo();
14129            if (nativeProcTotalPss > 0) {
14130                synchronized (this) {
14131                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14132                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14133                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14134                }
14135            }
14136            if (!brief) {
14137                if (!isCompact) {
14138                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14139                    pw.print(" kB (status ");
14140                    switch (mLastMemoryLevel) {
14141                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14142                            pw.println("normal)");
14143                            break;
14144                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14145                            pw.println("moderate)");
14146                            break;
14147                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14148                            pw.println("low)");
14149                            break;
14150                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14151                            pw.println("critical)");
14152                            break;
14153                        default:
14154                            pw.print(mLastMemoryLevel);
14155                            pw.println(")");
14156                            break;
14157                    }
14158                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14159                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14160                            pw.print(cachedPss); pw.print(" cached pss + ");
14161                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14162                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14163                } else {
14164                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14165                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14166                            + memInfo.getFreeSizeKb()); pw.print(",");
14167                    pw.println(totalPss - cachedPss);
14168                }
14169            }
14170            if (!isCompact) {
14171                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14172                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14173                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14174                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14175                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14176                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14177                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14178            }
14179            if (!brief) {
14180                if (memInfo.getZramTotalSizeKb() != 0) {
14181                    if (!isCompact) {
14182                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14183                                pw.print(" kB physical used for ");
14184                                pw.print(memInfo.getSwapTotalSizeKb()
14185                                        - memInfo.getSwapFreeSizeKb());
14186                                pw.print(" kB in swap (");
14187                                pw.print(memInfo.getSwapTotalSizeKb());
14188                                pw.println(" kB total swap)");
14189                    } else {
14190                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14191                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14192                                pw.println(memInfo.getSwapFreeSizeKb());
14193                    }
14194                }
14195                final long[] ksm = getKsmInfo();
14196                if (!isCompact) {
14197                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14198                            || ksm[KSM_VOLATILE] != 0) {
14199                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14200                                pw.print(" kB saved from shared ");
14201                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14202                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14203                                pw.print(" kB unshared; ");
14204                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14205                    }
14206                    pw.print("   Tuning: ");
14207                    pw.print(ActivityManager.staticGetMemoryClass());
14208                    pw.print(" (large ");
14209                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14210                    pw.print("), oom ");
14211                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14212                    pw.print(" kB");
14213                    pw.print(", restore limit ");
14214                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14215                    pw.print(" kB");
14216                    if (ActivityManager.isLowRamDeviceStatic()) {
14217                        pw.print(" (low-ram)");
14218                    }
14219                    if (ActivityManager.isHighEndGfx()) {
14220                        pw.print(" (high-end-gfx)");
14221                    }
14222                    pw.println();
14223                } else {
14224                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14225                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14226                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14227                    pw.print("tuning,");
14228                    pw.print(ActivityManager.staticGetMemoryClass());
14229                    pw.print(',');
14230                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14231                    pw.print(',');
14232                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14233                    if (ActivityManager.isLowRamDeviceStatic()) {
14234                        pw.print(",low-ram");
14235                    }
14236                    if (ActivityManager.isHighEndGfx()) {
14237                        pw.print(",high-end-gfx");
14238                    }
14239                    pw.println();
14240                }
14241            }
14242        }
14243    }
14244
14245    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14246            String name) {
14247        sb.append("  ");
14248        sb.append(ProcessList.makeOomAdjString(oomAdj));
14249        sb.append(' ');
14250        sb.append(ProcessList.makeProcStateString(procState));
14251        sb.append(' ');
14252        ProcessList.appendRamKb(sb, pss);
14253        sb.append(" kB: ");
14254        sb.append(name);
14255    }
14256
14257    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14258        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14259        sb.append(" (");
14260        sb.append(mi.pid);
14261        sb.append(") ");
14262        sb.append(mi.adjType);
14263        sb.append('\n');
14264        if (mi.adjReason != null) {
14265            sb.append("                      ");
14266            sb.append(mi.adjReason);
14267            sb.append('\n');
14268        }
14269    }
14270
14271    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14272        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14273        for (int i=0, N=memInfos.size(); i<N; i++) {
14274            ProcessMemInfo mi = memInfos.get(i);
14275            infoMap.put(mi.pid, mi);
14276        }
14277        updateCpuStatsNow();
14278        synchronized (mProcessCpuTracker) {
14279            final int N = mProcessCpuTracker.countStats();
14280            for (int i=0; i<N; i++) {
14281                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14282                if (st.vsize > 0) {
14283                    long pss = Debug.getPss(st.pid, null);
14284                    if (pss > 0) {
14285                        if (infoMap.indexOfKey(st.pid) < 0) {
14286                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14287                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14288                            mi.pss = pss;
14289                            memInfos.add(mi);
14290                        }
14291                    }
14292                }
14293            }
14294        }
14295
14296        long totalPss = 0;
14297        for (int i=0, N=memInfos.size(); i<N; i++) {
14298            ProcessMemInfo mi = memInfos.get(i);
14299            if (mi.pss == 0) {
14300                mi.pss = Debug.getPss(mi.pid, null);
14301            }
14302            totalPss += mi.pss;
14303        }
14304        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14305            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14306                if (lhs.oomAdj != rhs.oomAdj) {
14307                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14308                }
14309                if (lhs.pss != rhs.pss) {
14310                    return lhs.pss < rhs.pss ? 1 : -1;
14311                }
14312                return 0;
14313            }
14314        });
14315
14316        StringBuilder tag = new StringBuilder(128);
14317        StringBuilder stack = new StringBuilder(128);
14318        tag.append("Low on memory -- ");
14319        appendMemBucket(tag, totalPss, "total", false);
14320        appendMemBucket(stack, totalPss, "total", true);
14321
14322        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14323        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14324        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14325
14326        boolean firstLine = true;
14327        int lastOomAdj = Integer.MIN_VALUE;
14328        long extraNativeRam = 0;
14329        long cachedPss = 0;
14330        for (int i=0, N=memInfos.size(); i<N; i++) {
14331            ProcessMemInfo mi = memInfos.get(i);
14332
14333            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14334                cachedPss += mi.pss;
14335            }
14336
14337            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14338                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14339                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14340                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14341                if (lastOomAdj != mi.oomAdj) {
14342                    lastOomAdj = mi.oomAdj;
14343                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14344                        tag.append(" / ");
14345                    }
14346                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14347                        if (firstLine) {
14348                            stack.append(":");
14349                            firstLine = false;
14350                        }
14351                        stack.append("\n\t at ");
14352                    } else {
14353                        stack.append("$");
14354                    }
14355                } else {
14356                    tag.append(" ");
14357                    stack.append("$");
14358                }
14359                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14360                    appendMemBucket(tag, mi.pss, mi.name, false);
14361                }
14362                appendMemBucket(stack, mi.pss, mi.name, true);
14363                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14364                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14365                    stack.append("(");
14366                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14367                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14368                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14369                            stack.append(":");
14370                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14371                        }
14372                    }
14373                    stack.append(")");
14374                }
14375            }
14376
14377            appendMemInfo(fullNativeBuilder, mi);
14378            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14379                // The short form only has native processes that are >= 1MB.
14380                if (mi.pss >= 1000) {
14381                    appendMemInfo(shortNativeBuilder, mi);
14382                } else {
14383                    extraNativeRam += mi.pss;
14384                }
14385            } else {
14386                // Short form has all other details, but if we have collected RAM
14387                // from smaller native processes let's dump a summary of that.
14388                if (extraNativeRam > 0) {
14389                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14390                            -1, extraNativeRam, "(Other native)");
14391                    shortNativeBuilder.append('\n');
14392                    extraNativeRam = 0;
14393                }
14394                appendMemInfo(fullJavaBuilder, mi);
14395            }
14396        }
14397
14398        fullJavaBuilder.append("           ");
14399        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14400        fullJavaBuilder.append(" kB: TOTAL\n");
14401
14402        MemInfoReader memInfo = new MemInfoReader();
14403        memInfo.readMemInfo();
14404        final long[] infos = memInfo.getRawInfo();
14405
14406        StringBuilder memInfoBuilder = new StringBuilder(1024);
14407        Debug.getMemInfo(infos);
14408        memInfoBuilder.append("  MemInfo: ");
14409        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14410        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14411        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14412        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14413        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14414        memInfoBuilder.append("           ");
14415        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14416        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14417        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14418        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14419        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14420            memInfoBuilder.append("  ZRAM: ");
14421            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14422            memInfoBuilder.append(" kB RAM, ");
14423            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14424            memInfoBuilder.append(" kB swap total, ");
14425            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14426            memInfoBuilder.append(" kB swap free\n");
14427        }
14428        final long[] ksm = getKsmInfo();
14429        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14430                || ksm[KSM_VOLATILE] != 0) {
14431            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14432            memInfoBuilder.append(" kB saved from shared ");
14433            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14434            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14435            memInfoBuilder.append(" kB unshared; ");
14436            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14437        }
14438        memInfoBuilder.append("  Free RAM: ");
14439        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14440                + memInfo.getFreeSizeKb());
14441        memInfoBuilder.append(" kB\n");
14442        memInfoBuilder.append("  Used RAM: ");
14443        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14444        memInfoBuilder.append(" kB\n");
14445        memInfoBuilder.append("  Lost RAM: ");
14446        memInfoBuilder.append(memInfo.getTotalSizeKb()
14447                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14448                - memInfo.getKernelUsedSizeKb());
14449        memInfoBuilder.append(" kB\n");
14450        Slog.i(TAG, "Low on memory:");
14451        Slog.i(TAG, shortNativeBuilder.toString());
14452        Slog.i(TAG, fullJavaBuilder.toString());
14453        Slog.i(TAG, memInfoBuilder.toString());
14454
14455        StringBuilder dropBuilder = new StringBuilder(1024);
14456        /*
14457        StringWriter oomSw = new StringWriter();
14458        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14459        StringWriter catSw = new StringWriter();
14460        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14461        String[] emptyArgs = new String[] { };
14462        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14463        oomPw.flush();
14464        String oomString = oomSw.toString();
14465        */
14466        dropBuilder.append("Low on memory:");
14467        dropBuilder.append(stack);
14468        dropBuilder.append('\n');
14469        dropBuilder.append(fullNativeBuilder);
14470        dropBuilder.append(fullJavaBuilder);
14471        dropBuilder.append('\n');
14472        dropBuilder.append(memInfoBuilder);
14473        dropBuilder.append('\n');
14474        /*
14475        dropBuilder.append(oomString);
14476        dropBuilder.append('\n');
14477        */
14478        StringWriter catSw = new StringWriter();
14479        synchronized (ActivityManagerService.this) {
14480            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14481            String[] emptyArgs = new String[] { };
14482            catPw.println();
14483            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14484            catPw.println();
14485            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14486                    false, false, null);
14487            catPw.println();
14488            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14489            catPw.flush();
14490        }
14491        dropBuilder.append(catSw.toString());
14492        addErrorToDropBox("lowmem", null, "system_server", null,
14493                null, tag.toString(), dropBuilder.toString(), null, null);
14494        //Slog.i(TAG, "Sent to dropbox:");
14495        //Slog.i(TAG, dropBuilder.toString());
14496        synchronized (ActivityManagerService.this) {
14497            long now = SystemClock.uptimeMillis();
14498            if (mLastMemUsageReportTime < now) {
14499                mLastMemUsageReportTime = now;
14500            }
14501        }
14502    }
14503
14504    /**
14505     * Searches array of arguments for the specified string
14506     * @param args array of argument strings
14507     * @param value value to search for
14508     * @return true if the value is contained in the array
14509     */
14510    private static boolean scanArgs(String[] args, String value) {
14511        if (args != null) {
14512            for (String arg : args) {
14513                if (value.equals(arg)) {
14514                    return true;
14515                }
14516            }
14517        }
14518        return false;
14519    }
14520
14521    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14522            ContentProviderRecord cpr, boolean always) {
14523        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14524
14525        if (!inLaunching || always) {
14526            synchronized (cpr) {
14527                cpr.launchingApp = null;
14528                cpr.notifyAll();
14529            }
14530            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14531            String names[] = cpr.info.authority.split(";");
14532            for (int j = 0; j < names.length; j++) {
14533                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14534            }
14535        }
14536
14537        for (int i=0; i<cpr.connections.size(); i++) {
14538            ContentProviderConnection conn = cpr.connections.get(i);
14539            if (conn.waiting) {
14540                // If this connection is waiting for the provider, then we don't
14541                // need to mess with its process unless we are always removing
14542                // or for some reason the provider is not currently launching.
14543                if (inLaunching && !always) {
14544                    continue;
14545                }
14546            }
14547            ProcessRecord capp = conn.client;
14548            conn.dead = true;
14549            if (conn.stableCount > 0) {
14550                if (!capp.persistent && capp.thread != null
14551                        && capp.pid != 0
14552                        && capp.pid != MY_PID) {
14553                    capp.kill("depends on provider "
14554                            + cpr.name.flattenToShortString()
14555                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14556                }
14557            } else if (capp.thread != null && conn.provider.provider != null) {
14558                try {
14559                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14560                } catch (RemoteException e) {
14561                }
14562                // In the protocol here, we don't expect the client to correctly
14563                // clean up this connection, we'll just remove it.
14564                cpr.connections.remove(i);
14565                conn.client.conProviders.remove(conn);
14566            }
14567        }
14568
14569        if (inLaunching && always) {
14570            mLaunchingProviders.remove(cpr);
14571        }
14572        return inLaunching;
14573    }
14574
14575    /**
14576     * Main code for cleaning up a process when it has gone away.  This is
14577     * called both as a result of the process dying, or directly when stopping
14578     * a process when running in single process mode.
14579     *
14580     * @return Returns true if the given process has been restarted, so the
14581     * app that was passed in must remain on the process lists.
14582     */
14583    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14584            boolean restarting, boolean allowRestart, int index) {
14585        if (index >= 0) {
14586            removeLruProcessLocked(app);
14587            ProcessList.remove(app.pid);
14588        }
14589
14590        mProcessesToGc.remove(app);
14591        mPendingPssProcesses.remove(app);
14592
14593        // Dismiss any open dialogs.
14594        if (app.crashDialog != null && !app.forceCrashReport) {
14595            app.crashDialog.dismiss();
14596            app.crashDialog = null;
14597        }
14598        if (app.anrDialog != null) {
14599            app.anrDialog.dismiss();
14600            app.anrDialog = null;
14601        }
14602        if (app.waitDialog != null) {
14603            app.waitDialog.dismiss();
14604            app.waitDialog = null;
14605        }
14606
14607        app.crashing = false;
14608        app.notResponding = false;
14609
14610        app.resetPackageList(mProcessStats);
14611        app.unlinkDeathRecipient();
14612        app.makeInactive(mProcessStats);
14613        app.waitingToKill = null;
14614        app.forcingToForeground = null;
14615        updateProcessForegroundLocked(app, false, false);
14616        app.foregroundActivities = false;
14617        app.hasShownUi = false;
14618        app.treatLikeActivity = false;
14619        app.hasAboveClient = false;
14620        app.hasClientActivities = false;
14621
14622        mServices.killServicesLocked(app, allowRestart);
14623
14624        boolean restart = false;
14625
14626        // Remove published content providers.
14627        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14628            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14629            final boolean always = app.bad || !allowRestart;
14630            if (removeDyingProviderLocked(app, cpr, always) || always) {
14631                // We left the provider in the launching list, need to
14632                // restart it.
14633                restart = true;
14634            }
14635
14636            cpr.provider = null;
14637            cpr.proc = null;
14638        }
14639        app.pubProviders.clear();
14640
14641        // Take care of any launching providers waiting for this process.
14642        if (checkAppInLaunchingProvidersLocked(app, false)) {
14643            restart = true;
14644        }
14645
14646        // Unregister from connected content providers.
14647        if (!app.conProviders.isEmpty()) {
14648            for (int i=0; i<app.conProviders.size(); i++) {
14649                ContentProviderConnection conn = app.conProviders.get(i);
14650                conn.provider.connections.remove(conn);
14651            }
14652            app.conProviders.clear();
14653        }
14654
14655        // At this point there may be remaining entries in mLaunchingProviders
14656        // where we were the only one waiting, so they are no longer of use.
14657        // Look for these and clean up if found.
14658        // XXX Commented out for now.  Trying to figure out a way to reproduce
14659        // the actual situation to identify what is actually going on.
14660        if (false) {
14661            for (int i=0; i<mLaunchingProviders.size(); i++) {
14662                ContentProviderRecord cpr = (ContentProviderRecord)
14663                        mLaunchingProviders.get(i);
14664                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14665                    synchronized (cpr) {
14666                        cpr.launchingApp = null;
14667                        cpr.notifyAll();
14668                    }
14669                }
14670            }
14671        }
14672
14673        skipCurrentReceiverLocked(app);
14674
14675        // Unregister any receivers.
14676        for (int i=app.receivers.size()-1; i>=0; i--) {
14677            removeReceiverLocked(app.receivers.valueAt(i));
14678        }
14679        app.receivers.clear();
14680
14681        // If the app is undergoing backup, tell the backup manager about it
14682        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14683            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14684                    + mBackupTarget.appInfo + " died during backup");
14685            try {
14686                IBackupManager bm = IBackupManager.Stub.asInterface(
14687                        ServiceManager.getService(Context.BACKUP_SERVICE));
14688                bm.agentDisconnected(app.info.packageName);
14689            } catch (RemoteException e) {
14690                // can't happen; backup manager is local
14691            }
14692        }
14693
14694        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14695            ProcessChangeItem item = mPendingProcessChanges.get(i);
14696            if (item.pid == app.pid) {
14697                mPendingProcessChanges.remove(i);
14698                mAvailProcessChanges.add(item);
14699            }
14700        }
14701        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14702
14703        // If the caller is restarting this app, then leave it in its
14704        // current lists and let the caller take care of it.
14705        if (restarting) {
14706            return false;
14707        }
14708
14709        if (!app.persistent || app.isolated) {
14710            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14711                    "Removing non-persistent process during cleanup: " + app);
14712            mProcessNames.remove(app.processName, app.uid);
14713            mIsolatedProcesses.remove(app.uid);
14714            if (mHeavyWeightProcess == app) {
14715                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14716                        mHeavyWeightProcess.userId, 0));
14717                mHeavyWeightProcess = null;
14718            }
14719        } else if (!app.removed) {
14720            // This app is persistent, so we need to keep its record around.
14721            // If it is not already on the pending app list, add it there
14722            // and start a new process for it.
14723            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14724                mPersistentStartingProcesses.add(app);
14725                restart = true;
14726            }
14727        }
14728        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14729                "Clean-up removing on hold: " + app);
14730        mProcessesOnHold.remove(app);
14731
14732        if (app == mHomeProcess) {
14733            mHomeProcess = null;
14734        }
14735        if (app == mPreviousProcess) {
14736            mPreviousProcess = null;
14737        }
14738
14739        if (restart && !app.isolated) {
14740            // We have components that still need to be running in the
14741            // process, so re-launch it.
14742            if (index < 0) {
14743                ProcessList.remove(app.pid);
14744            }
14745            mProcessNames.put(app.processName, app.uid, app);
14746            startProcessLocked(app, "restart", app.processName);
14747            return true;
14748        } else if (app.pid > 0 && app.pid != MY_PID) {
14749            // Goodbye!
14750            boolean removed;
14751            synchronized (mPidsSelfLocked) {
14752                mPidsSelfLocked.remove(app.pid);
14753                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14754            }
14755            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14756            if (app.isolated) {
14757                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14758            }
14759            app.setPid(0);
14760        }
14761        return false;
14762    }
14763
14764    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14765        // Look through the content providers we are waiting to have launched,
14766        // and if any run in this process then either schedule a restart of
14767        // the process or kill the client waiting for it if this process has
14768        // gone bad.
14769        int NL = mLaunchingProviders.size();
14770        boolean restart = false;
14771        for (int i=0; i<NL; i++) {
14772            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14773            if (cpr.launchingApp == app) {
14774                if (!alwaysBad && !app.bad) {
14775                    restart = true;
14776                } else {
14777                    removeDyingProviderLocked(app, cpr, true);
14778                    // cpr should have been removed from mLaunchingProviders
14779                    NL = mLaunchingProviders.size();
14780                    i--;
14781                }
14782            }
14783        }
14784        return restart;
14785    }
14786
14787    // =========================================================
14788    // SERVICES
14789    // =========================================================
14790
14791    @Override
14792    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14793            int flags) {
14794        enforceNotIsolatedCaller("getServices");
14795        synchronized (this) {
14796            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14797        }
14798    }
14799
14800    @Override
14801    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14802        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14803        synchronized (this) {
14804            return mServices.getRunningServiceControlPanelLocked(name);
14805        }
14806    }
14807
14808    @Override
14809    public ComponentName startService(IApplicationThread caller, Intent service,
14810            String resolvedType, int userId) {
14811        enforceNotIsolatedCaller("startService");
14812        // Refuse possible leaked file descriptors
14813        if (service != null && service.hasFileDescriptors() == true) {
14814            throw new IllegalArgumentException("File descriptors passed in Intent");
14815        }
14816
14817        if (DEBUG_SERVICE)
14818            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14819        synchronized(this) {
14820            final int callingPid = Binder.getCallingPid();
14821            final int callingUid = Binder.getCallingUid();
14822            final long origId = Binder.clearCallingIdentity();
14823            ComponentName res = mServices.startServiceLocked(caller, service,
14824                    resolvedType, callingPid, callingUid, userId);
14825            Binder.restoreCallingIdentity(origId);
14826            return res;
14827        }
14828    }
14829
14830    ComponentName startServiceInPackage(int uid,
14831            Intent service, String resolvedType, int userId) {
14832        synchronized(this) {
14833            if (DEBUG_SERVICE)
14834                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14835            final long origId = Binder.clearCallingIdentity();
14836            ComponentName res = mServices.startServiceLocked(null, service,
14837                    resolvedType, -1, uid, userId);
14838            Binder.restoreCallingIdentity(origId);
14839            return res;
14840        }
14841    }
14842
14843    @Override
14844    public int stopService(IApplicationThread caller, Intent service,
14845            String resolvedType, int userId) {
14846        enforceNotIsolatedCaller("stopService");
14847        // Refuse possible leaked file descriptors
14848        if (service != null && service.hasFileDescriptors() == true) {
14849            throw new IllegalArgumentException("File descriptors passed in Intent");
14850        }
14851
14852        synchronized(this) {
14853            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14854        }
14855    }
14856
14857    @Override
14858    public IBinder peekService(Intent service, String resolvedType) {
14859        enforceNotIsolatedCaller("peekService");
14860        // Refuse possible leaked file descriptors
14861        if (service != null && service.hasFileDescriptors() == true) {
14862            throw new IllegalArgumentException("File descriptors passed in Intent");
14863        }
14864        synchronized(this) {
14865            return mServices.peekServiceLocked(service, resolvedType);
14866        }
14867    }
14868
14869    @Override
14870    public boolean stopServiceToken(ComponentName className, IBinder token,
14871            int startId) {
14872        synchronized(this) {
14873            return mServices.stopServiceTokenLocked(className, token, startId);
14874        }
14875    }
14876
14877    @Override
14878    public void setServiceForeground(ComponentName className, IBinder token,
14879            int id, Notification notification, boolean removeNotification) {
14880        synchronized(this) {
14881            mServices.setServiceForegroundLocked(className, token, id, notification,
14882                    removeNotification);
14883        }
14884    }
14885
14886    @Override
14887    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14888            boolean requireFull, String name, String callerPackage) {
14889        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14890                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14891    }
14892
14893    int unsafeConvertIncomingUser(int userId) {
14894        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14895                ? mCurrentUserId : userId;
14896    }
14897
14898    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14899            int allowMode, String name, String callerPackage) {
14900        final int callingUserId = UserHandle.getUserId(callingUid);
14901        if (callingUserId == userId) {
14902            return userId;
14903        }
14904
14905        // Note that we may be accessing mCurrentUserId outside of a lock...
14906        // shouldn't be a big deal, if this is being called outside
14907        // of a locked context there is intrinsically a race with
14908        // the value the caller will receive and someone else changing it.
14909        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14910        // we will switch to the calling user if access to the current user fails.
14911        int targetUserId = unsafeConvertIncomingUser(userId);
14912
14913        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14914            final boolean allow;
14915            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14916                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14917                // If the caller has this permission, they always pass go.  And collect $200.
14918                allow = true;
14919            } else if (allowMode == ALLOW_FULL_ONLY) {
14920                // We require full access, sucks to be you.
14921                allow = false;
14922            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14923                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14924                // If the caller does not have either permission, they are always doomed.
14925                allow = false;
14926            } else if (allowMode == ALLOW_NON_FULL) {
14927                // We are blanket allowing non-full access, you lucky caller!
14928                allow = true;
14929            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14930                // We may or may not allow this depending on whether the two users are
14931                // in the same profile.
14932                synchronized (mUserProfileGroupIdsSelfLocked) {
14933                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14934                            UserInfo.NO_PROFILE_GROUP_ID);
14935                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14936                            UserInfo.NO_PROFILE_GROUP_ID);
14937                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14938                            && callingProfile == targetProfile;
14939                }
14940            } else {
14941                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14942            }
14943            if (!allow) {
14944                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14945                    // In this case, they would like to just execute as their
14946                    // owner user instead of failing.
14947                    targetUserId = callingUserId;
14948                } else {
14949                    StringBuilder builder = new StringBuilder(128);
14950                    builder.append("Permission Denial: ");
14951                    builder.append(name);
14952                    if (callerPackage != null) {
14953                        builder.append(" from ");
14954                        builder.append(callerPackage);
14955                    }
14956                    builder.append(" asks to run as user ");
14957                    builder.append(userId);
14958                    builder.append(" but is calling from user ");
14959                    builder.append(UserHandle.getUserId(callingUid));
14960                    builder.append("; this requires ");
14961                    builder.append(INTERACT_ACROSS_USERS_FULL);
14962                    if (allowMode != ALLOW_FULL_ONLY) {
14963                        builder.append(" or ");
14964                        builder.append(INTERACT_ACROSS_USERS);
14965                    }
14966                    String msg = builder.toString();
14967                    Slog.w(TAG, msg);
14968                    throw new SecurityException(msg);
14969                }
14970            }
14971        }
14972        if (!allowAll && targetUserId < 0) {
14973            throw new IllegalArgumentException(
14974                    "Call does not support special user #" + targetUserId);
14975        }
14976        // Check shell permission
14977        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14978            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14979                    targetUserId)) {
14980                throw new SecurityException("Shell does not have permission to access user "
14981                        + targetUserId + "\n " + Debug.getCallers(3));
14982            }
14983        }
14984        return targetUserId;
14985    }
14986
14987    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14988            String className, int flags) {
14989        boolean result = false;
14990        // For apps that don't have pre-defined UIDs, check for permission
14991        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14992            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14993                if (ActivityManager.checkUidPermission(
14994                        INTERACT_ACROSS_USERS,
14995                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14996                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14997                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14998                            + " requests FLAG_SINGLE_USER, but app does not hold "
14999                            + INTERACT_ACROSS_USERS;
15000                    Slog.w(TAG, msg);
15001                    throw new SecurityException(msg);
15002                }
15003                // Permission passed
15004                result = true;
15005            }
15006        } else if ("system".equals(componentProcessName)) {
15007            result = true;
15008        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15009            // Phone app and persistent apps are allowed to export singleuser providers.
15010            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15011                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15012        }
15013        if (DEBUG_MU) {
15014            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15015                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15016        }
15017        return result;
15018    }
15019
15020    /**
15021     * Checks to see if the caller is in the same app as the singleton
15022     * component, or the component is in a special app. It allows special apps
15023     * to export singleton components but prevents exporting singleton
15024     * components for regular apps.
15025     */
15026    boolean isValidSingletonCall(int callingUid, int componentUid) {
15027        int componentAppId = UserHandle.getAppId(componentUid);
15028        return UserHandle.isSameApp(callingUid, componentUid)
15029                || componentAppId == Process.SYSTEM_UID
15030                || componentAppId == Process.PHONE_UID
15031                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15032                        == PackageManager.PERMISSION_GRANTED;
15033    }
15034
15035    public int bindService(IApplicationThread caller, IBinder token,
15036            Intent service, String resolvedType,
15037            IServiceConnection connection, int flags, int userId) {
15038        enforceNotIsolatedCaller("bindService");
15039
15040        // Refuse possible leaked file descriptors
15041        if (service != null && service.hasFileDescriptors() == true) {
15042            throw new IllegalArgumentException("File descriptors passed in Intent");
15043        }
15044
15045        synchronized(this) {
15046            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15047                    connection, flags, userId);
15048        }
15049    }
15050
15051    public boolean unbindService(IServiceConnection connection) {
15052        synchronized (this) {
15053            return mServices.unbindServiceLocked(connection);
15054        }
15055    }
15056
15057    public void publishService(IBinder token, Intent intent, IBinder service) {
15058        // Refuse possible leaked file descriptors
15059        if (intent != null && intent.hasFileDescriptors() == true) {
15060            throw new IllegalArgumentException("File descriptors passed in Intent");
15061        }
15062
15063        synchronized(this) {
15064            if (!(token instanceof ServiceRecord)) {
15065                throw new IllegalArgumentException("Invalid service token");
15066            }
15067            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15068        }
15069    }
15070
15071    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15072        // Refuse possible leaked file descriptors
15073        if (intent != null && intent.hasFileDescriptors() == true) {
15074            throw new IllegalArgumentException("File descriptors passed in Intent");
15075        }
15076
15077        synchronized(this) {
15078            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15079        }
15080    }
15081
15082    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15083        synchronized(this) {
15084            if (!(token instanceof ServiceRecord)) {
15085                throw new IllegalArgumentException("Invalid service token");
15086            }
15087            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15088        }
15089    }
15090
15091    // =========================================================
15092    // BACKUP AND RESTORE
15093    // =========================================================
15094
15095    // Cause the target app to be launched if necessary and its backup agent
15096    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15097    // activity manager to announce its creation.
15098    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15099        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15100        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15101
15102        synchronized(this) {
15103            // !!! TODO: currently no check here that we're already bound
15104            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15105            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15106            synchronized (stats) {
15107                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15108            }
15109
15110            // Backup agent is now in use, its package can't be stopped.
15111            try {
15112                AppGlobals.getPackageManager().setPackageStoppedState(
15113                        app.packageName, false, UserHandle.getUserId(app.uid));
15114            } catch (RemoteException e) {
15115            } catch (IllegalArgumentException e) {
15116                Slog.w(TAG, "Failed trying to unstop package "
15117                        + app.packageName + ": " + e);
15118            }
15119
15120            BackupRecord r = new BackupRecord(ss, app, backupMode);
15121            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15122                    ? new ComponentName(app.packageName, app.backupAgentName)
15123                    : new ComponentName("android", "FullBackupAgent");
15124            // startProcessLocked() returns existing proc's record if it's already running
15125            ProcessRecord proc = startProcessLocked(app.processName, app,
15126                    false, 0, "backup", hostingName, false, false, false);
15127            if (proc == null) {
15128                Slog.e(TAG, "Unable to start backup agent process " + r);
15129                return false;
15130            }
15131
15132            r.app = proc;
15133            mBackupTarget = r;
15134            mBackupAppName = app.packageName;
15135
15136            // Try not to kill the process during backup
15137            updateOomAdjLocked(proc);
15138
15139            // If the process is already attached, schedule the creation of the backup agent now.
15140            // If it is not yet live, this will be done when it attaches to the framework.
15141            if (proc.thread != null) {
15142                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15143                try {
15144                    proc.thread.scheduleCreateBackupAgent(app,
15145                            compatibilityInfoForPackageLocked(app), backupMode);
15146                } catch (RemoteException e) {
15147                    // Will time out on the backup manager side
15148                }
15149            } else {
15150                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15151            }
15152            // Invariants: at this point, the target app process exists and the application
15153            // is either already running or in the process of coming up.  mBackupTarget and
15154            // mBackupAppName describe the app, so that when it binds back to the AM we
15155            // know that it's scheduled for a backup-agent operation.
15156        }
15157
15158        return true;
15159    }
15160
15161    @Override
15162    public void clearPendingBackup() {
15163        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15164        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15165
15166        synchronized (this) {
15167            mBackupTarget = null;
15168            mBackupAppName = null;
15169        }
15170    }
15171
15172    // A backup agent has just come up
15173    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15174        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15175                + " = " + agent);
15176
15177        synchronized(this) {
15178            if (!agentPackageName.equals(mBackupAppName)) {
15179                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15180                return;
15181            }
15182        }
15183
15184        long oldIdent = Binder.clearCallingIdentity();
15185        try {
15186            IBackupManager bm = IBackupManager.Stub.asInterface(
15187                    ServiceManager.getService(Context.BACKUP_SERVICE));
15188            bm.agentConnected(agentPackageName, agent);
15189        } catch (RemoteException e) {
15190            // can't happen; the backup manager service is local
15191        } catch (Exception e) {
15192            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15193            e.printStackTrace();
15194        } finally {
15195            Binder.restoreCallingIdentity(oldIdent);
15196        }
15197    }
15198
15199    // done with this agent
15200    public void unbindBackupAgent(ApplicationInfo appInfo) {
15201        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15202        if (appInfo == null) {
15203            Slog.w(TAG, "unbind backup agent for null app");
15204            return;
15205        }
15206
15207        synchronized(this) {
15208            try {
15209                if (mBackupAppName == null) {
15210                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15211                    return;
15212                }
15213
15214                if (!mBackupAppName.equals(appInfo.packageName)) {
15215                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15216                    return;
15217                }
15218
15219                // Not backing this app up any more; reset its OOM adjustment
15220                final ProcessRecord proc = mBackupTarget.app;
15221                updateOomAdjLocked(proc);
15222
15223                // If the app crashed during backup, 'thread' will be null here
15224                if (proc.thread != null) {
15225                    try {
15226                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15227                                compatibilityInfoForPackageLocked(appInfo));
15228                    } catch (Exception e) {
15229                        Slog.e(TAG, "Exception when unbinding backup agent:");
15230                        e.printStackTrace();
15231                    }
15232                }
15233            } finally {
15234                mBackupTarget = null;
15235                mBackupAppName = null;
15236            }
15237        }
15238    }
15239    // =========================================================
15240    // BROADCASTS
15241    // =========================================================
15242
15243    private final List getStickiesLocked(String action, IntentFilter filter,
15244            List cur, int userId) {
15245        final ContentResolver resolver = mContext.getContentResolver();
15246        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15247        if (stickies == null) {
15248            return cur;
15249        }
15250        final ArrayList<Intent> list = stickies.get(action);
15251        if (list == null) {
15252            return cur;
15253        }
15254        int N = list.size();
15255        for (int i=0; i<N; i++) {
15256            Intent intent = list.get(i);
15257            if (filter.match(resolver, intent, true, TAG) >= 0) {
15258                if (cur == null) {
15259                    cur = new ArrayList<Intent>();
15260                }
15261                cur.add(intent);
15262            }
15263        }
15264        return cur;
15265    }
15266
15267    boolean isPendingBroadcastProcessLocked(int pid) {
15268        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15269                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15270    }
15271
15272    void skipPendingBroadcastLocked(int pid) {
15273            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15274            for (BroadcastQueue queue : mBroadcastQueues) {
15275                queue.skipPendingBroadcastLocked(pid);
15276            }
15277    }
15278
15279    // The app just attached; send any pending broadcasts that it should receive
15280    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15281        boolean didSomething = false;
15282        for (BroadcastQueue queue : mBroadcastQueues) {
15283            didSomething |= queue.sendPendingBroadcastsLocked(app);
15284        }
15285        return didSomething;
15286    }
15287
15288    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15289            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15290        enforceNotIsolatedCaller("registerReceiver");
15291        int callingUid;
15292        int callingPid;
15293        synchronized(this) {
15294            ProcessRecord callerApp = null;
15295            if (caller != null) {
15296                callerApp = getRecordForAppLocked(caller);
15297                if (callerApp == null) {
15298                    throw new SecurityException(
15299                            "Unable to find app for caller " + caller
15300                            + " (pid=" + Binder.getCallingPid()
15301                            + ") when registering receiver " + receiver);
15302                }
15303                if (callerApp.info.uid != Process.SYSTEM_UID &&
15304                        !callerApp.pkgList.containsKey(callerPackage) &&
15305                        !"android".equals(callerPackage)) {
15306                    throw new SecurityException("Given caller package " + callerPackage
15307                            + " is not running in process " + callerApp);
15308                }
15309                callingUid = callerApp.info.uid;
15310                callingPid = callerApp.pid;
15311            } else {
15312                callerPackage = null;
15313                callingUid = Binder.getCallingUid();
15314                callingPid = Binder.getCallingPid();
15315            }
15316
15317            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15318                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15319
15320            List allSticky = null;
15321
15322            // Look for any matching sticky broadcasts...
15323            Iterator actions = filter.actionsIterator();
15324            if (actions != null) {
15325                while (actions.hasNext()) {
15326                    String action = (String)actions.next();
15327                    allSticky = getStickiesLocked(action, filter, allSticky,
15328                            UserHandle.USER_ALL);
15329                    allSticky = getStickiesLocked(action, filter, allSticky,
15330                            UserHandle.getUserId(callingUid));
15331                }
15332            } else {
15333                allSticky = getStickiesLocked(null, filter, allSticky,
15334                        UserHandle.USER_ALL);
15335                allSticky = getStickiesLocked(null, filter, allSticky,
15336                        UserHandle.getUserId(callingUid));
15337            }
15338
15339            // The first sticky in the list is returned directly back to
15340            // the client.
15341            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15342
15343            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15344                    + ": " + sticky);
15345
15346            if (receiver == null) {
15347                return sticky;
15348            }
15349
15350            ReceiverList rl
15351                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15352            if (rl == null) {
15353                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15354                        userId, receiver);
15355                if (rl.app != null) {
15356                    rl.app.receivers.add(rl);
15357                } else {
15358                    try {
15359                        receiver.asBinder().linkToDeath(rl, 0);
15360                    } catch (RemoteException e) {
15361                        return sticky;
15362                    }
15363                    rl.linkedToDeath = true;
15364                }
15365                mRegisteredReceivers.put(receiver.asBinder(), rl);
15366            } else if (rl.uid != callingUid) {
15367                throw new IllegalArgumentException(
15368                        "Receiver requested to register for uid " + callingUid
15369                        + " was previously registered for uid " + rl.uid);
15370            } else if (rl.pid != callingPid) {
15371                throw new IllegalArgumentException(
15372                        "Receiver requested to register for pid " + callingPid
15373                        + " was previously registered for pid " + rl.pid);
15374            } else if (rl.userId != userId) {
15375                throw new IllegalArgumentException(
15376                        "Receiver requested to register for user " + userId
15377                        + " was previously registered for user " + rl.userId);
15378            }
15379            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15380                    permission, callingUid, userId);
15381            rl.add(bf);
15382            if (!bf.debugCheck()) {
15383                Slog.w(TAG, "==> For Dynamic broadast");
15384            }
15385            mReceiverResolver.addFilter(bf);
15386
15387            // Enqueue broadcasts for all existing stickies that match
15388            // this filter.
15389            if (allSticky != null) {
15390                ArrayList receivers = new ArrayList();
15391                receivers.add(bf);
15392
15393                int N = allSticky.size();
15394                for (int i=0; i<N; i++) {
15395                    Intent intent = (Intent)allSticky.get(i);
15396                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15397                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15398                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15399                            null, null, false, true, true, -1);
15400                    queue.enqueueParallelBroadcastLocked(r);
15401                    queue.scheduleBroadcastsLocked();
15402                }
15403            }
15404
15405            return sticky;
15406        }
15407    }
15408
15409    public void unregisterReceiver(IIntentReceiver receiver) {
15410        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15411
15412        final long origId = Binder.clearCallingIdentity();
15413        try {
15414            boolean doTrim = false;
15415
15416            synchronized(this) {
15417                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15418                if (rl != null) {
15419                    if (rl.curBroadcast != null) {
15420                        BroadcastRecord r = rl.curBroadcast;
15421                        final boolean doNext = finishReceiverLocked(
15422                                receiver.asBinder(), r.resultCode, r.resultData,
15423                                r.resultExtras, r.resultAbort);
15424                        if (doNext) {
15425                            doTrim = true;
15426                            r.queue.processNextBroadcast(false);
15427                        }
15428                    }
15429
15430                    if (rl.app != null) {
15431                        rl.app.receivers.remove(rl);
15432                    }
15433                    removeReceiverLocked(rl);
15434                    if (rl.linkedToDeath) {
15435                        rl.linkedToDeath = false;
15436                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15437                    }
15438                }
15439            }
15440
15441            // If we actually concluded any broadcasts, we might now be able
15442            // to trim the recipients' apps from our working set
15443            if (doTrim) {
15444                trimApplications();
15445                return;
15446            }
15447
15448        } finally {
15449            Binder.restoreCallingIdentity(origId);
15450        }
15451    }
15452
15453    void removeReceiverLocked(ReceiverList rl) {
15454        mRegisteredReceivers.remove(rl.receiver.asBinder());
15455        int N = rl.size();
15456        for (int i=0; i<N; i++) {
15457            mReceiverResolver.removeFilter(rl.get(i));
15458        }
15459    }
15460
15461    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15462        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15463            ProcessRecord r = mLruProcesses.get(i);
15464            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15465                try {
15466                    r.thread.dispatchPackageBroadcast(cmd, packages);
15467                } catch (RemoteException ex) {
15468                }
15469            }
15470        }
15471    }
15472
15473    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15474            int callingUid, int[] users) {
15475        List<ResolveInfo> receivers = null;
15476        try {
15477            HashSet<ComponentName> singleUserReceivers = null;
15478            boolean scannedFirstReceivers = false;
15479            for (int user : users) {
15480                // Skip users that have Shell restrictions
15481                if (callingUid == Process.SHELL_UID
15482                        && getUserManagerLocked().hasUserRestriction(
15483                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15484                    continue;
15485                }
15486                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15487                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15488                if (user != 0 && newReceivers != null) {
15489                    // If this is not the primary user, we need to check for
15490                    // any receivers that should be filtered out.
15491                    for (int i=0; i<newReceivers.size(); i++) {
15492                        ResolveInfo ri = newReceivers.get(i);
15493                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15494                            newReceivers.remove(i);
15495                            i--;
15496                        }
15497                    }
15498                }
15499                if (newReceivers != null && newReceivers.size() == 0) {
15500                    newReceivers = null;
15501                }
15502                if (receivers == null) {
15503                    receivers = newReceivers;
15504                } else if (newReceivers != null) {
15505                    // We need to concatenate the additional receivers
15506                    // found with what we have do far.  This would be easy,
15507                    // but we also need to de-dup any receivers that are
15508                    // singleUser.
15509                    if (!scannedFirstReceivers) {
15510                        // Collect any single user receivers we had already retrieved.
15511                        scannedFirstReceivers = true;
15512                        for (int i=0; i<receivers.size(); i++) {
15513                            ResolveInfo ri = receivers.get(i);
15514                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15515                                ComponentName cn = new ComponentName(
15516                                        ri.activityInfo.packageName, ri.activityInfo.name);
15517                                if (singleUserReceivers == null) {
15518                                    singleUserReceivers = new HashSet<ComponentName>();
15519                                }
15520                                singleUserReceivers.add(cn);
15521                            }
15522                        }
15523                    }
15524                    // Add the new results to the existing results, tracking
15525                    // and de-dupping single user receivers.
15526                    for (int i=0; i<newReceivers.size(); i++) {
15527                        ResolveInfo ri = newReceivers.get(i);
15528                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15529                            ComponentName cn = new ComponentName(
15530                                    ri.activityInfo.packageName, ri.activityInfo.name);
15531                            if (singleUserReceivers == null) {
15532                                singleUserReceivers = new HashSet<ComponentName>();
15533                            }
15534                            if (!singleUserReceivers.contains(cn)) {
15535                                singleUserReceivers.add(cn);
15536                                receivers.add(ri);
15537                            }
15538                        } else {
15539                            receivers.add(ri);
15540                        }
15541                    }
15542                }
15543            }
15544        } catch (RemoteException ex) {
15545            // pm is in same process, this will never happen.
15546        }
15547        return receivers;
15548    }
15549
15550    private final int broadcastIntentLocked(ProcessRecord callerApp,
15551            String callerPackage, Intent intent, String resolvedType,
15552            IIntentReceiver resultTo, int resultCode, String resultData,
15553            Bundle map, String requiredPermission, int appOp,
15554            boolean ordered, boolean sticky, int callingPid, int callingUid,
15555            int userId) {
15556        intent = new Intent(intent);
15557
15558        // By default broadcasts do not go to stopped apps.
15559        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15560
15561        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15562            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15563            + " ordered=" + ordered + " userid=" + userId);
15564        if ((resultTo != null) && !ordered) {
15565            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15566        }
15567
15568        userId = handleIncomingUser(callingPid, callingUid, userId,
15569                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15570
15571        // Make sure that the user who is receiving this broadcast is started.
15572        // If not, we will just skip it.
15573
15574        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15575            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15576                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15577                Slog.w(TAG, "Skipping broadcast of " + intent
15578                        + ": user " + userId + " is stopped");
15579                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15580            }
15581        }
15582
15583        /*
15584         * Prevent non-system code (defined here to be non-persistent
15585         * processes) from sending protected broadcasts.
15586         */
15587        int callingAppId = UserHandle.getAppId(callingUid);
15588        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15589            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15590            || callingAppId == Process.NFC_UID || callingUid == 0) {
15591            // Always okay.
15592        } else if (callerApp == null || !callerApp.persistent) {
15593            try {
15594                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15595                        intent.getAction())) {
15596                    String msg = "Permission Denial: not allowed to send broadcast "
15597                            + intent.getAction() + " from pid="
15598                            + callingPid + ", uid=" + callingUid;
15599                    Slog.w(TAG, msg);
15600                    throw new SecurityException(msg);
15601                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15602                    // Special case for compatibility: we don't want apps to send this,
15603                    // but historically it has not been protected and apps may be using it
15604                    // to poke their own app widget.  So, instead of making it protected,
15605                    // just limit it to the caller.
15606                    if (callerApp == null) {
15607                        String msg = "Permission Denial: not allowed to send broadcast "
15608                                + intent.getAction() + " from unknown caller.";
15609                        Slog.w(TAG, msg);
15610                        throw new SecurityException(msg);
15611                    } else if (intent.getComponent() != null) {
15612                        // They are good enough to send to an explicit component...  verify
15613                        // it is being sent to the calling app.
15614                        if (!intent.getComponent().getPackageName().equals(
15615                                callerApp.info.packageName)) {
15616                            String msg = "Permission Denial: not allowed to send broadcast "
15617                                    + intent.getAction() + " to "
15618                                    + intent.getComponent().getPackageName() + " from "
15619                                    + callerApp.info.packageName;
15620                            Slog.w(TAG, msg);
15621                            throw new SecurityException(msg);
15622                        }
15623                    } else {
15624                        // Limit broadcast to their own package.
15625                        intent.setPackage(callerApp.info.packageName);
15626                    }
15627                }
15628            } catch (RemoteException e) {
15629                Slog.w(TAG, "Remote exception", e);
15630                return ActivityManager.BROADCAST_SUCCESS;
15631            }
15632        }
15633
15634        // Handle special intents: if this broadcast is from the package
15635        // manager about a package being removed, we need to remove all of
15636        // its activities from the history stack.
15637        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15638                intent.getAction());
15639        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15640                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15641                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15642                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15643                || uidRemoved) {
15644            if (checkComponentPermission(
15645                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15646                    callingPid, callingUid, -1, true)
15647                    == PackageManager.PERMISSION_GRANTED) {
15648                if (uidRemoved) {
15649                    final Bundle intentExtras = intent.getExtras();
15650                    final int uid = intentExtras != null
15651                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15652                    if (uid >= 0) {
15653                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15654                        synchronized (bs) {
15655                            bs.removeUidStatsLocked(uid);
15656                        }
15657                        mAppOpsService.uidRemoved(uid);
15658                    }
15659                } else {
15660                    // If resources are unavailable just force stop all
15661                    // those packages and flush the attribute cache as well.
15662                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15663                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15664                        if (list != null && (list.length > 0)) {
15665                            for (String pkg : list) {
15666                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15667                                        "storage unmount");
15668                            }
15669                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15670                            sendPackageBroadcastLocked(
15671                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15672                        }
15673                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15674                            intent.getAction())) {
15675                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15676                    } else {
15677                        Uri data = intent.getData();
15678                        String ssp;
15679                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15680                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15681                                    intent.getAction());
15682                            boolean fullUninstall = removed &&
15683                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15684                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15685                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15686                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15687                                        false, fullUninstall, userId,
15688                                        removed ? "pkg removed" : "pkg changed");
15689                            }
15690                            if (removed) {
15691                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15692                                        new String[] {ssp}, userId);
15693                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15694                                    mAppOpsService.packageRemoved(
15695                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15696
15697                                    // Remove all permissions granted from/to this package
15698                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15699                                }
15700                            }
15701                        }
15702                    }
15703                }
15704            } else {
15705                String msg = "Permission Denial: " + intent.getAction()
15706                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15707                        + ", uid=" + callingUid + ")"
15708                        + " requires "
15709                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15710                Slog.w(TAG, msg);
15711                throw new SecurityException(msg);
15712            }
15713
15714        // Special case for adding a package: by default turn on compatibility
15715        // mode.
15716        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15717            Uri data = intent.getData();
15718            String ssp;
15719            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15720                mCompatModePackages.handlePackageAddedLocked(ssp,
15721                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15722            }
15723        }
15724
15725        /*
15726         * If this is the time zone changed action, queue up a message that will reset the timezone
15727         * of all currently running processes. This message will get queued up before the broadcast
15728         * happens.
15729         */
15730        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15731            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15732        }
15733
15734        /*
15735         * If the user set the time, let all running processes know.
15736         */
15737        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15738            final int is24Hour = intent.getBooleanExtra(
15739                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15740            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15741            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15742            synchronized (stats) {
15743                stats.noteCurrentTimeChangedLocked();
15744            }
15745        }
15746
15747        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15748            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15749        }
15750
15751        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15752            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15753            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15754        }
15755
15756        // Add to the sticky list if requested.
15757        if (sticky) {
15758            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15759                    callingPid, callingUid)
15760                    != PackageManager.PERMISSION_GRANTED) {
15761                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15762                        + callingPid + ", uid=" + callingUid
15763                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15764                Slog.w(TAG, msg);
15765                throw new SecurityException(msg);
15766            }
15767            if (requiredPermission != null) {
15768                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15769                        + " and enforce permission " + requiredPermission);
15770                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15771            }
15772            if (intent.getComponent() != null) {
15773                throw new SecurityException(
15774                        "Sticky broadcasts can't target a specific component");
15775            }
15776            // We use userId directly here, since the "all" target is maintained
15777            // as a separate set of sticky broadcasts.
15778            if (userId != UserHandle.USER_ALL) {
15779                // But first, if this is not a broadcast to all users, then
15780                // make sure it doesn't conflict with an existing broadcast to
15781                // all users.
15782                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15783                        UserHandle.USER_ALL);
15784                if (stickies != null) {
15785                    ArrayList<Intent> list = stickies.get(intent.getAction());
15786                    if (list != null) {
15787                        int N = list.size();
15788                        int i;
15789                        for (i=0; i<N; i++) {
15790                            if (intent.filterEquals(list.get(i))) {
15791                                throw new IllegalArgumentException(
15792                                        "Sticky broadcast " + intent + " for user "
15793                                        + userId + " conflicts with existing global broadcast");
15794                            }
15795                        }
15796                    }
15797                }
15798            }
15799            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15800            if (stickies == null) {
15801                stickies = new ArrayMap<String, ArrayList<Intent>>();
15802                mStickyBroadcasts.put(userId, stickies);
15803            }
15804            ArrayList<Intent> list = stickies.get(intent.getAction());
15805            if (list == null) {
15806                list = new ArrayList<Intent>();
15807                stickies.put(intent.getAction(), list);
15808            }
15809            int N = list.size();
15810            int i;
15811            for (i=0; i<N; i++) {
15812                if (intent.filterEquals(list.get(i))) {
15813                    // This sticky already exists, replace it.
15814                    list.set(i, new Intent(intent));
15815                    break;
15816                }
15817            }
15818            if (i >= N) {
15819                list.add(new Intent(intent));
15820            }
15821        }
15822
15823        int[] users;
15824        if (userId == UserHandle.USER_ALL) {
15825            // Caller wants broadcast to go to all started users.
15826            users = mStartedUserArray;
15827        } else {
15828            // Caller wants broadcast to go to one specific user.
15829            users = new int[] {userId};
15830        }
15831
15832        // Figure out who all will receive this broadcast.
15833        List receivers = null;
15834        List<BroadcastFilter> registeredReceivers = null;
15835        // Need to resolve the intent to interested receivers...
15836        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15837                 == 0) {
15838            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15839        }
15840        if (intent.getComponent() == null) {
15841            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15842                // Query one target user at a time, excluding shell-restricted users
15843                UserManagerService ums = getUserManagerLocked();
15844                for (int i = 0; i < users.length; i++) {
15845                    if (ums.hasUserRestriction(
15846                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15847                        continue;
15848                    }
15849                    List<BroadcastFilter> registeredReceiversForUser =
15850                            mReceiverResolver.queryIntent(intent,
15851                                    resolvedType, false, users[i]);
15852                    if (registeredReceivers == null) {
15853                        registeredReceivers = registeredReceiversForUser;
15854                    } else if (registeredReceiversForUser != null) {
15855                        registeredReceivers.addAll(registeredReceiversForUser);
15856                    }
15857                }
15858            } else {
15859                registeredReceivers = mReceiverResolver.queryIntent(intent,
15860                        resolvedType, false, userId);
15861            }
15862        }
15863
15864        final boolean replacePending =
15865                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15866
15867        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15868                + " replacePending=" + replacePending);
15869
15870        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15871        if (!ordered && NR > 0) {
15872            // If we are not serializing this broadcast, then send the
15873            // registered receivers separately so they don't wait for the
15874            // components to be launched.
15875            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15876            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15877                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15878                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15879                    ordered, sticky, false, userId);
15880            if (DEBUG_BROADCAST) Slog.v(
15881                    TAG, "Enqueueing parallel broadcast " + r);
15882            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15883            if (!replaced) {
15884                queue.enqueueParallelBroadcastLocked(r);
15885                queue.scheduleBroadcastsLocked();
15886            }
15887            registeredReceivers = null;
15888            NR = 0;
15889        }
15890
15891        // Merge into one list.
15892        int ir = 0;
15893        if (receivers != null) {
15894            // A special case for PACKAGE_ADDED: do not allow the package
15895            // being added to see this broadcast.  This prevents them from
15896            // using this as a back door to get run as soon as they are
15897            // installed.  Maybe in the future we want to have a special install
15898            // broadcast or such for apps, but we'd like to deliberately make
15899            // this decision.
15900            String skipPackages[] = null;
15901            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15902                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15903                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15904                Uri data = intent.getData();
15905                if (data != null) {
15906                    String pkgName = data.getSchemeSpecificPart();
15907                    if (pkgName != null) {
15908                        skipPackages = new String[] { pkgName };
15909                    }
15910                }
15911            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15912                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15913            }
15914            if (skipPackages != null && (skipPackages.length > 0)) {
15915                for (String skipPackage : skipPackages) {
15916                    if (skipPackage != null) {
15917                        int NT = receivers.size();
15918                        for (int it=0; it<NT; it++) {
15919                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15920                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15921                                receivers.remove(it);
15922                                it--;
15923                                NT--;
15924                            }
15925                        }
15926                    }
15927                }
15928            }
15929
15930            int NT = receivers != null ? receivers.size() : 0;
15931            int it = 0;
15932            ResolveInfo curt = null;
15933            BroadcastFilter curr = null;
15934            while (it < NT && ir < NR) {
15935                if (curt == null) {
15936                    curt = (ResolveInfo)receivers.get(it);
15937                }
15938                if (curr == null) {
15939                    curr = registeredReceivers.get(ir);
15940                }
15941                if (curr.getPriority() >= curt.priority) {
15942                    // Insert this broadcast record into the final list.
15943                    receivers.add(it, curr);
15944                    ir++;
15945                    curr = null;
15946                    it++;
15947                    NT++;
15948                } else {
15949                    // Skip to the next ResolveInfo in the final list.
15950                    it++;
15951                    curt = null;
15952                }
15953            }
15954        }
15955        while (ir < NR) {
15956            if (receivers == null) {
15957                receivers = new ArrayList();
15958            }
15959            receivers.add(registeredReceivers.get(ir));
15960            ir++;
15961        }
15962
15963        if ((receivers != null && receivers.size() > 0)
15964                || resultTo != null) {
15965            BroadcastQueue queue = broadcastQueueForIntent(intent);
15966            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15967                    callerPackage, callingPid, callingUid, resolvedType,
15968                    requiredPermission, appOp, receivers, resultTo, resultCode,
15969                    resultData, map, ordered, sticky, false, userId);
15970            if (DEBUG_BROADCAST) Slog.v(
15971                    TAG, "Enqueueing ordered broadcast " + r
15972                    + ": prev had " + queue.mOrderedBroadcasts.size());
15973            if (DEBUG_BROADCAST) {
15974                int seq = r.intent.getIntExtra("seq", -1);
15975                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15976            }
15977            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15978            if (!replaced) {
15979                queue.enqueueOrderedBroadcastLocked(r);
15980                queue.scheduleBroadcastsLocked();
15981            }
15982        }
15983
15984        return ActivityManager.BROADCAST_SUCCESS;
15985    }
15986
15987    final Intent verifyBroadcastLocked(Intent intent) {
15988        // Refuse possible leaked file descriptors
15989        if (intent != null && intent.hasFileDescriptors() == true) {
15990            throw new IllegalArgumentException("File descriptors passed in Intent");
15991        }
15992
15993        int flags = intent.getFlags();
15994
15995        if (!mProcessesReady) {
15996            // if the caller really truly claims to know what they're doing, go
15997            // ahead and allow the broadcast without launching any receivers
15998            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15999                intent = new Intent(intent);
16000                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16001            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16002                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16003                        + " before boot completion");
16004                throw new IllegalStateException("Cannot broadcast before boot completed");
16005            }
16006        }
16007
16008        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16009            throw new IllegalArgumentException(
16010                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16011        }
16012
16013        return intent;
16014    }
16015
16016    public final int broadcastIntent(IApplicationThread caller,
16017            Intent intent, String resolvedType, IIntentReceiver resultTo,
16018            int resultCode, String resultData, Bundle map,
16019            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16020        enforceNotIsolatedCaller("broadcastIntent");
16021        synchronized(this) {
16022            intent = verifyBroadcastLocked(intent);
16023
16024            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16025            final int callingPid = Binder.getCallingPid();
16026            final int callingUid = Binder.getCallingUid();
16027            final long origId = Binder.clearCallingIdentity();
16028            int res = broadcastIntentLocked(callerApp,
16029                    callerApp != null ? callerApp.info.packageName : null,
16030                    intent, resolvedType, resultTo,
16031                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16032                    callingPid, callingUid, userId);
16033            Binder.restoreCallingIdentity(origId);
16034            return res;
16035        }
16036    }
16037
16038    int broadcastIntentInPackage(String packageName, int uid,
16039            Intent intent, String resolvedType, IIntentReceiver resultTo,
16040            int resultCode, String resultData, Bundle map,
16041            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16042        synchronized(this) {
16043            intent = verifyBroadcastLocked(intent);
16044
16045            final long origId = Binder.clearCallingIdentity();
16046            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16047                    resultTo, resultCode, resultData, map, requiredPermission,
16048                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16049            Binder.restoreCallingIdentity(origId);
16050            return res;
16051        }
16052    }
16053
16054    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16055        // Refuse possible leaked file descriptors
16056        if (intent != null && intent.hasFileDescriptors() == true) {
16057            throw new IllegalArgumentException("File descriptors passed in Intent");
16058        }
16059
16060        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16061                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16062
16063        synchronized(this) {
16064            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16065                    != PackageManager.PERMISSION_GRANTED) {
16066                String msg = "Permission Denial: unbroadcastIntent() from pid="
16067                        + Binder.getCallingPid()
16068                        + ", uid=" + Binder.getCallingUid()
16069                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16070                Slog.w(TAG, msg);
16071                throw new SecurityException(msg);
16072            }
16073            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16074            if (stickies != null) {
16075                ArrayList<Intent> list = stickies.get(intent.getAction());
16076                if (list != null) {
16077                    int N = list.size();
16078                    int i;
16079                    for (i=0; i<N; i++) {
16080                        if (intent.filterEquals(list.get(i))) {
16081                            list.remove(i);
16082                            break;
16083                        }
16084                    }
16085                    if (list.size() <= 0) {
16086                        stickies.remove(intent.getAction());
16087                    }
16088                }
16089                if (stickies.size() <= 0) {
16090                    mStickyBroadcasts.remove(userId);
16091                }
16092            }
16093        }
16094    }
16095
16096    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16097            String resultData, Bundle resultExtras, boolean resultAbort) {
16098        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16099        if (r == null) {
16100            Slog.w(TAG, "finishReceiver called but not found on queue");
16101            return false;
16102        }
16103
16104        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16105    }
16106
16107    void backgroundServicesFinishedLocked(int userId) {
16108        for (BroadcastQueue queue : mBroadcastQueues) {
16109            queue.backgroundServicesFinishedLocked(userId);
16110        }
16111    }
16112
16113    public void finishReceiver(IBinder who, int resultCode, String resultData,
16114            Bundle resultExtras, boolean resultAbort) {
16115        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16116
16117        // Refuse possible leaked file descriptors
16118        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16119            throw new IllegalArgumentException("File descriptors passed in Bundle");
16120        }
16121
16122        final long origId = Binder.clearCallingIdentity();
16123        try {
16124            boolean doNext = false;
16125            BroadcastRecord r;
16126
16127            synchronized(this) {
16128                r = broadcastRecordForReceiverLocked(who);
16129                if (r != null) {
16130                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16131                        resultData, resultExtras, resultAbort, true);
16132                }
16133            }
16134
16135            if (doNext) {
16136                r.queue.processNextBroadcast(false);
16137            }
16138            trimApplications();
16139        } finally {
16140            Binder.restoreCallingIdentity(origId);
16141        }
16142    }
16143
16144    // =========================================================
16145    // INSTRUMENTATION
16146    // =========================================================
16147
16148    public boolean startInstrumentation(ComponentName className,
16149            String profileFile, int flags, Bundle arguments,
16150            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16151            int userId, String abiOverride) {
16152        enforceNotIsolatedCaller("startInstrumentation");
16153        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16154                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16155        // Refuse possible leaked file descriptors
16156        if (arguments != null && arguments.hasFileDescriptors()) {
16157            throw new IllegalArgumentException("File descriptors passed in Bundle");
16158        }
16159
16160        synchronized(this) {
16161            InstrumentationInfo ii = null;
16162            ApplicationInfo ai = null;
16163            try {
16164                ii = mContext.getPackageManager().getInstrumentationInfo(
16165                    className, STOCK_PM_FLAGS);
16166                ai = AppGlobals.getPackageManager().getApplicationInfo(
16167                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16168            } catch (PackageManager.NameNotFoundException e) {
16169            } catch (RemoteException e) {
16170            }
16171            if (ii == null) {
16172                reportStartInstrumentationFailure(watcher, className,
16173                        "Unable to find instrumentation info for: " + className);
16174                return false;
16175            }
16176            if (ai == null) {
16177                reportStartInstrumentationFailure(watcher, className,
16178                        "Unable to find instrumentation target package: " + ii.targetPackage);
16179                return false;
16180            }
16181
16182            int match = mContext.getPackageManager().checkSignatures(
16183                    ii.targetPackage, ii.packageName);
16184            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16185                String msg = "Permission Denial: starting instrumentation "
16186                        + className + " from pid="
16187                        + Binder.getCallingPid()
16188                        + ", uid=" + Binder.getCallingPid()
16189                        + " not allowed because package " + ii.packageName
16190                        + " does not have a signature matching the target "
16191                        + ii.targetPackage;
16192                reportStartInstrumentationFailure(watcher, className, msg);
16193                throw new SecurityException(msg);
16194            }
16195
16196            final long origId = Binder.clearCallingIdentity();
16197            // Instrumentation can kill and relaunch even persistent processes
16198            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16199                    "start instr");
16200            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16201            app.instrumentationClass = className;
16202            app.instrumentationInfo = ai;
16203            app.instrumentationProfileFile = profileFile;
16204            app.instrumentationArguments = arguments;
16205            app.instrumentationWatcher = watcher;
16206            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16207            app.instrumentationResultClass = className;
16208            Binder.restoreCallingIdentity(origId);
16209        }
16210
16211        return true;
16212    }
16213
16214    /**
16215     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16216     * error to the logs, but if somebody is watching, send the report there too.  This enables
16217     * the "am" command to report errors with more information.
16218     *
16219     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16220     * @param cn The component name of the instrumentation.
16221     * @param report The error report.
16222     */
16223    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16224            ComponentName cn, String report) {
16225        Slog.w(TAG, report);
16226        try {
16227            if (watcher != null) {
16228                Bundle results = new Bundle();
16229                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16230                results.putString("Error", report);
16231                watcher.instrumentationStatus(cn, -1, results);
16232            }
16233        } catch (RemoteException e) {
16234            Slog.w(TAG, e);
16235        }
16236    }
16237
16238    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16239        if (app.instrumentationWatcher != null) {
16240            try {
16241                // NOTE:  IInstrumentationWatcher *must* be oneway here
16242                app.instrumentationWatcher.instrumentationFinished(
16243                    app.instrumentationClass,
16244                    resultCode,
16245                    results);
16246            } catch (RemoteException e) {
16247            }
16248        }
16249        if (app.instrumentationUiAutomationConnection != null) {
16250            try {
16251                app.instrumentationUiAutomationConnection.shutdown();
16252            } catch (RemoteException re) {
16253                /* ignore */
16254            }
16255            // Only a UiAutomation can set this flag and now that
16256            // it is finished we make sure it is reset to its default.
16257            mUserIsMonkey = false;
16258        }
16259        app.instrumentationWatcher = null;
16260        app.instrumentationUiAutomationConnection = null;
16261        app.instrumentationClass = null;
16262        app.instrumentationInfo = null;
16263        app.instrumentationProfileFile = null;
16264        app.instrumentationArguments = null;
16265
16266        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16267                "finished inst");
16268    }
16269
16270    public void finishInstrumentation(IApplicationThread target,
16271            int resultCode, Bundle results) {
16272        int userId = UserHandle.getCallingUserId();
16273        // Refuse possible leaked file descriptors
16274        if (results != null && results.hasFileDescriptors()) {
16275            throw new IllegalArgumentException("File descriptors passed in Intent");
16276        }
16277
16278        synchronized(this) {
16279            ProcessRecord app = getRecordForAppLocked(target);
16280            if (app == null) {
16281                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16282                return;
16283            }
16284            final long origId = Binder.clearCallingIdentity();
16285            finishInstrumentationLocked(app, resultCode, results);
16286            Binder.restoreCallingIdentity(origId);
16287        }
16288    }
16289
16290    // =========================================================
16291    // CONFIGURATION
16292    // =========================================================
16293
16294    public ConfigurationInfo getDeviceConfigurationInfo() {
16295        ConfigurationInfo config = new ConfigurationInfo();
16296        synchronized (this) {
16297            config.reqTouchScreen = mConfiguration.touchscreen;
16298            config.reqKeyboardType = mConfiguration.keyboard;
16299            config.reqNavigation = mConfiguration.navigation;
16300            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16301                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16302                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16303            }
16304            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16305                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16306                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16307            }
16308            config.reqGlEsVersion = GL_ES_VERSION;
16309        }
16310        return config;
16311    }
16312
16313    ActivityStack getFocusedStack() {
16314        return mStackSupervisor.getFocusedStack();
16315    }
16316
16317    public Configuration getConfiguration() {
16318        Configuration ci;
16319        synchronized(this) {
16320            ci = new Configuration(mConfiguration);
16321        }
16322        return ci;
16323    }
16324
16325    public void updatePersistentConfiguration(Configuration values) {
16326        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16327                "updateConfiguration()");
16328        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16329                "updateConfiguration()");
16330        if (values == null) {
16331            throw new NullPointerException("Configuration must not be null");
16332        }
16333
16334        synchronized(this) {
16335            final long origId = Binder.clearCallingIdentity();
16336            updateConfigurationLocked(values, null, true, false);
16337            Binder.restoreCallingIdentity(origId);
16338        }
16339    }
16340
16341    public void updateConfiguration(Configuration values) {
16342        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16343                "updateConfiguration()");
16344
16345        synchronized(this) {
16346            if (values == null && mWindowManager != null) {
16347                // sentinel: fetch the current configuration from the window manager
16348                values = mWindowManager.computeNewConfiguration();
16349            }
16350
16351            if (mWindowManager != null) {
16352                mProcessList.applyDisplaySize(mWindowManager);
16353            }
16354
16355            final long origId = Binder.clearCallingIdentity();
16356            if (values != null) {
16357                Settings.System.clearConfiguration(values);
16358            }
16359            updateConfigurationLocked(values, null, false, false);
16360            Binder.restoreCallingIdentity(origId);
16361        }
16362    }
16363
16364    /**
16365     * Do either or both things: (1) change the current configuration, and (2)
16366     * make sure the given activity is running with the (now) current
16367     * configuration.  Returns true if the activity has been left running, or
16368     * false if <var>starting</var> is being destroyed to match the new
16369     * configuration.
16370     * @param persistent TODO
16371     */
16372    boolean updateConfigurationLocked(Configuration values,
16373            ActivityRecord starting, boolean persistent, boolean initLocale) {
16374        int changes = 0;
16375
16376        if (values != null) {
16377            Configuration newConfig = new Configuration(mConfiguration);
16378            changes = newConfig.updateFrom(values);
16379            if (changes != 0) {
16380                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16381                    Slog.i(TAG, "Updating configuration to: " + values);
16382                }
16383
16384                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16385
16386                if (values.locale != null && !initLocale) {
16387                    saveLocaleLocked(values.locale,
16388                                     !values.locale.equals(mConfiguration.locale),
16389                                     values.userSetLocale);
16390                }
16391
16392                mConfigurationSeq++;
16393                if (mConfigurationSeq <= 0) {
16394                    mConfigurationSeq = 1;
16395                }
16396                newConfig.seq = mConfigurationSeq;
16397                mConfiguration = newConfig;
16398                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16399                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16400                //mUsageStatsService.noteStartConfig(newConfig);
16401
16402                final Configuration configCopy = new Configuration(mConfiguration);
16403
16404                // TODO: If our config changes, should we auto dismiss any currently
16405                // showing dialogs?
16406                mShowDialogs = shouldShowDialogs(newConfig);
16407
16408                AttributeCache ac = AttributeCache.instance();
16409                if (ac != null) {
16410                    ac.updateConfiguration(configCopy);
16411                }
16412
16413                // Make sure all resources in our process are updated
16414                // right now, so that anyone who is going to retrieve
16415                // resource values after we return will be sure to get
16416                // the new ones.  This is especially important during
16417                // boot, where the first config change needs to guarantee
16418                // all resources have that config before following boot
16419                // code is executed.
16420                mSystemThread.applyConfigurationToResources(configCopy);
16421
16422                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16423                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16424                    msg.obj = new Configuration(configCopy);
16425                    mHandler.sendMessage(msg);
16426                }
16427
16428                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16429                    ProcessRecord app = mLruProcesses.get(i);
16430                    try {
16431                        if (app.thread != null) {
16432                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16433                                    + app.processName + " new config " + mConfiguration);
16434                            app.thread.scheduleConfigurationChanged(configCopy);
16435                        }
16436                    } catch (Exception e) {
16437                    }
16438                }
16439                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16440                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16441                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16442                        | Intent.FLAG_RECEIVER_FOREGROUND);
16443                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16444                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16445                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16446                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16447                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16448                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16449                    broadcastIntentLocked(null, null, intent,
16450                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16451                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16452                }
16453            }
16454        }
16455
16456        boolean kept = true;
16457        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16458        // mainStack is null during startup.
16459        if (mainStack != null) {
16460            if (changes != 0 && starting == null) {
16461                // If the configuration changed, and the caller is not already
16462                // in the process of starting an activity, then find the top
16463                // activity to check if its configuration needs to change.
16464                starting = mainStack.topRunningActivityLocked(null);
16465            }
16466
16467            if (starting != null) {
16468                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16469                // And we need to make sure at this point that all other activities
16470                // are made visible with the correct configuration.
16471                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16472            }
16473        }
16474
16475        if (values != null && mWindowManager != null) {
16476            mWindowManager.setNewConfiguration(mConfiguration);
16477        }
16478
16479        return kept;
16480    }
16481
16482    /**
16483     * Decide based on the configuration whether we should shouw the ANR,
16484     * crash, etc dialogs.  The idea is that if there is no affordnace to
16485     * press the on-screen buttons, we shouldn't show the dialog.
16486     *
16487     * A thought: SystemUI might also want to get told about this, the Power
16488     * dialog / global actions also might want different behaviors.
16489     */
16490    private static final boolean shouldShowDialogs(Configuration config) {
16491        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16492                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16493    }
16494
16495    /**
16496     * Save the locale.  You must be inside a synchronized (this) block.
16497     */
16498    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16499        if(isDiff) {
16500            SystemProperties.set("user.language", l.getLanguage());
16501            SystemProperties.set("user.region", l.getCountry());
16502        }
16503
16504        if(isPersist) {
16505            SystemProperties.set("persist.sys.language", l.getLanguage());
16506            SystemProperties.set("persist.sys.country", l.getCountry());
16507            SystemProperties.set("persist.sys.localevar", l.getVariant());
16508
16509            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16510        }
16511    }
16512
16513    @Override
16514    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16515        synchronized (this) {
16516            ActivityRecord srec = ActivityRecord.forToken(token);
16517            if (srec.task != null && srec.task.stack != null) {
16518                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16519            }
16520        }
16521        return false;
16522    }
16523
16524    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16525            Intent resultData) {
16526
16527        synchronized (this) {
16528            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16529            if (stack != null) {
16530                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16531            }
16532            return false;
16533        }
16534    }
16535
16536    public int getLaunchedFromUid(IBinder activityToken) {
16537        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16538        if (srec == null) {
16539            return -1;
16540        }
16541        return srec.launchedFromUid;
16542    }
16543
16544    public String getLaunchedFromPackage(IBinder activityToken) {
16545        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16546        if (srec == null) {
16547            return null;
16548        }
16549        return srec.launchedFromPackage;
16550    }
16551
16552    // =========================================================
16553    // LIFETIME MANAGEMENT
16554    // =========================================================
16555
16556    // Returns which broadcast queue the app is the current [or imminent] receiver
16557    // on, or 'null' if the app is not an active broadcast recipient.
16558    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16559        BroadcastRecord r = app.curReceiver;
16560        if (r != null) {
16561            return r.queue;
16562        }
16563
16564        // It's not the current receiver, but it might be starting up to become one
16565        synchronized (this) {
16566            for (BroadcastQueue queue : mBroadcastQueues) {
16567                r = queue.mPendingBroadcast;
16568                if (r != null && r.curApp == app) {
16569                    // found it; report which queue it's in
16570                    return queue;
16571                }
16572            }
16573        }
16574
16575        return null;
16576    }
16577
16578    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16579            boolean doingAll, long now) {
16580        if (mAdjSeq == app.adjSeq) {
16581            // This adjustment has already been computed.
16582            return app.curRawAdj;
16583        }
16584
16585        if (app.thread == null) {
16586            app.adjSeq = mAdjSeq;
16587            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16588            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16589            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16590        }
16591
16592        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16593        app.adjSource = null;
16594        app.adjTarget = null;
16595        app.empty = false;
16596        app.cached = false;
16597
16598        final int activitiesSize = app.activities.size();
16599
16600        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16601            // The max adjustment doesn't allow this app to be anything
16602            // below foreground, so it is not worth doing work for it.
16603            app.adjType = "fixed";
16604            app.adjSeq = mAdjSeq;
16605            app.curRawAdj = app.maxAdj;
16606            app.foregroundActivities = false;
16607            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16608            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16609            // System processes can do UI, and when they do we want to have
16610            // them trim their memory after the user leaves the UI.  To
16611            // facilitate this, here we need to determine whether or not it
16612            // is currently showing UI.
16613            app.systemNoUi = true;
16614            if (app == TOP_APP) {
16615                app.systemNoUi = false;
16616            } else if (activitiesSize > 0) {
16617                for (int j = 0; j < activitiesSize; j++) {
16618                    final ActivityRecord r = app.activities.get(j);
16619                    if (r.visible) {
16620                        app.systemNoUi = false;
16621                    }
16622                }
16623            }
16624            if (!app.systemNoUi) {
16625                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16626            }
16627            return (app.curAdj=app.maxAdj);
16628        }
16629
16630        app.systemNoUi = false;
16631
16632        // Determine the importance of the process, starting with most
16633        // important to least, and assign an appropriate OOM adjustment.
16634        int adj;
16635        int schedGroup;
16636        int procState;
16637        boolean foregroundActivities = false;
16638        BroadcastQueue queue;
16639        if (app == TOP_APP) {
16640            // The last app on the list is the foreground app.
16641            adj = ProcessList.FOREGROUND_APP_ADJ;
16642            schedGroup = Process.THREAD_GROUP_DEFAULT;
16643            app.adjType = "top-activity";
16644            foregroundActivities = true;
16645            procState = ActivityManager.PROCESS_STATE_TOP;
16646        } else if (app.instrumentationClass != null) {
16647            // Don't want to kill running instrumentation.
16648            adj = ProcessList.FOREGROUND_APP_ADJ;
16649            schedGroup = Process.THREAD_GROUP_DEFAULT;
16650            app.adjType = "instrumentation";
16651            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16652        } else if ((queue = isReceivingBroadcast(app)) != null) {
16653            // An app that is currently receiving a broadcast also
16654            // counts as being in the foreground for OOM killer purposes.
16655            // It's placed in a sched group based on the nature of the
16656            // broadcast as reflected by which queue it's active in.
16657            adj = ProcessList.FOREGROUND_APP_ADJ;
16658            schedGroup = (queue == mFgBroadcastQueue)
16659                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16660            app.adjType = "broadcast";
16661            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16662        } else if (app.executingServices.size() > 0) {
16663            // An app that is currently executing a service callback also
16664            // counts as being in the foreground.
16665            adj = ProcessList.FOREGROUND_APP_ADJ;
16666            schedGroup = app.execServicesFg ?
16667                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16668            app.adjType = "exec-service";
16669            procState = ActivityManager.PROCESS_STATE_SERVICE;
16670            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16671        } else {
16672            // As far as we know the process is empty.  We may change our mind later.
16673            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16674            // At this point we don't actually know the adjustment.  Use the cached adj
16675            // value that the caller wants us to.
16676            adj = cachedAdj;
16677            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16678            app.cached = true;
16679            app.empty = true;
16680            app.adjType = "cch-empty";
16681        }
16682
16683        // Examine all activities if not already foreground.
16684        if (!foregroundActivities && activitiesSize > 0) {
16685            for (int j = 0; j < activitiesSize; j++) {
16686                final ActivityRecord r = app.activities.get(j);
16687                if (r.app != app) {
16688                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16689                            + app + "?!?");
16690                    continue;
16691                }
16692                if (r.visible) {
16693                    // App has a visible activity; only upgrade adjustment.
16694                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16695                        adj = ProcessList.VISIBLE_APP_ADJ;
16696                        app.adjType = "visible";
16697                    }
16698                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16699                        procState = ActivityManager.PROCESS_STATE_TOP;
16700                    }
16701                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16702                    app.cached = false;
16703                    app.empty = false;
16704                    foregroundActivities = true;
16705                    break;
16706                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16707                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16708                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16709                        app.adjType = "pausing";
16710                    }
16711                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16712                        procState = ActivityManager.PROCESS_STATE_TOP;
16713                    }
16714                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16715                    app.cached = false;
16716                    app.empty = false;
16717                    foregroundActivities = true;
16718                } else if (r.state == ActivityState.STOPPING) {
16719                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16720                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16721                        app.adjType = "stopping";
16722                    }
16723                    // For the process state, we will at this point consider the
16724                    // process to be cached.  It will be cached either as an activity
16725                    // or empty depending on whether the activity is finishing.  We do
16726                    // this so that we can treat the process as cached for purposes of
16727                    // memory trimming (determing current memory level, trim command to
16728                    // send to process) since there can be an arbitrary number of stopping
16729                    // processes and they should soon all go into the cached state.
16730                    if (!r.finishing) {
16731                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16732                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16733                        }
16734                    }
16735                    app.cached = false;
16736                    app.empty = false;
16737                    foregroundActivities = true;
16738                } else {
16739                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16740                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16741                        app.adjType = "cch-act";
16742                    }
16743                }
16744            }
16745        }
16746
16747        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16748            if (app.foregroundServices) {
16749                // The user is aware of this app, so make it visible.
16750                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16751                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16752                app.cached = false;
16753                app.adjType = "fg-service";
16754                schedGroup = Process.THREAD_GROUP_DEFAULT;
16755            } else if (app.forcingToForeground != null) {
16756                // The user is aware of this app, so make it visible.
16757                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16758                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16759                app.cached = false;
16760                app.adjType = "force-fg";
16761                app.adjSource = app.forcingToForeground;
16762                schedGroup = Process.THREAD_GROUP_DEFAULT;
16763            }
16764        }
16765
16766        if (app == mHeavyWeightProcess) {
16767            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16768                // We don't want to kill the current heavy-weight process.
16769                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16770                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16771                app.cached = false;
16772                app.adjType = "heavy";
16773            }
16774            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16775                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16776            }
16777        }
16778
16779        if (app == mHomeProcess) {
16780            if (adj > ProcessList.HOME_APP_ADJ) {
16781                // This process is hosting what we currently consider to be the
16782                // home app, so we don't want to let it go into the background.
16783                adj = ProcessList.HOME_APP_ADJ;
16784                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16785                app.cached = false;
16786                app.adjType = "home";
16787            }
16788            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16789                procState = ActivityManager.PROCESS_STATE_HOME;
16790            }
16791        }
16792
16793        if (app == mPreviousProcess && app.activities.size() > 0) {
16794            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16795                // This was the previous process that showed UI to the user.
16796                // We want to try to keep it around more aggressively, to give
16797                // a good experience around switching between two apps.
16798                adj = ProcessList.PREVIOUS_APP_ADJ;
16799                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16800                app.cached = false;
16801                app.adjType = "previous";
16802            }
16803            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16804                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16805            }
16806        }
16807
16808        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16809                + " reason=" + app.adjType);
16810
16811        // By default, we use the computed adjustment.  It may be changed if
16812        // there are applications dependent on our services or providers, but
16813        // this gives us a baseline and makes sure we don't get into an
16814        // infinite recursion.
16815        app.adjSeq = mAdjSeq;
16816        app.curRawAdj = adj;
16817        app.hasStartedServices = false;
16818
16819        if (mBackupTarget != null && app == mBackupTarget.app) {
16820            // If possible we want to avoid killing apps while they're being backed up
16821            if (adj > ProcessList.BACKUP_APP_ADJ) {
16822                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16823                adj = ProcessList.BACKUP_APP_ADJ;
16824                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16825                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16826                }
16827                app.adjType = "backup";
16828                app.cached = false;
16829            }
16830            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16831                procState = ActivityManager.PROCESS_STATE_BACKUP;
16832            }
16833        }
16834
16835        boolean mayBeTop = false;
16836
16837        for (int is = app.services.size()-1;
16838                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16839                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16840                        || procState > ActivityManager.PROCESS_STATE_TOP);
16841                is--) {
16842            ServiceRecord s = app.services.valueAt(is);
16843            if (s.startRequested) {
16844                app.hasStartedServices = true;
16845                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16846                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16847                }
16848                if (app.hasShownUi && app != mHomeProcess) {
16849                    // If this process has shown some UI, let it immediately
16850                    // go to the LRU list because it may be pretty heavy with
16851                    // UI stuff.  We'll tag it with a label just to help
16852                    // debug and understand what is going on.
16853                    if (adj > ProcessList.SERVICE_ADJ) {
16854                        app.adjType = "cch-started-ui-services";
16855                    }
16856                } else {
16857                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16858                        // This service has seen some activity within
16859                        // recent memory, so we will keep its process ahead
16860                        // of the background processes.
16861                        if (adj > ProcessList.SERVICE_ADJ) {
16862                            adj = ProcessList.SERVICE_ADJ;
16863                            app.adjType = "started-services";
16864                            app.cached = false;
16865                        }
16866                    }
16867                    // If we have let the service slide into the background
16868                    // state, still have some text describing what it is doing
16869                    // even though the service no longer has an impact.
16870                    if (adj > ProcessList.SERVICE_ADJ) {
16871                        app.adjType = "cch-started-services";
16872                    }
16873                }
16874            }
16875            for (int conni = s.connections.size()-1;
16876                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16877                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16878                            || procState > ActivityManager.PROCESS_STATE_TOP);
16879                    conni--) {
16880                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16881                for (int i = 0;
16882                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16883                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16884                                || procState > ActivityManager.PROCESS_STATE_TOP);
16885                        i++) {
16886                    // XXX should compute this based on the max of
16887                    // all connected clients.
16888                    ConnectionRecord cr = clist.get(i);
16889                    if (cr.binding.client == app) {
16890                        // Binding to ourself is not interesting.
16891                        continue;
16892                    }
16893                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16894                        ProcessRecord client = cr.binding.client;
16895                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16896                                TOP_APP, doingAll, now);
16897                        int clientProcState = client.curProcState;
16898                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16899                            // If the other app is cached for any reason, for purposes here
16900                            // we are going to consider it empty.  The specific cached state
16901                            // doesn't propagate except under certain conditions.
16902                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16903                        }
16904                        String adjType = null;
16905                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16906                            // Not doing bind OOM management, so treat
16907                            // this guy more like a started service.
16908                            if (app.hasShownUi && app != mHomeProcess) {
16909                                // If this process has shown some UI, let it immediately
16910                                // go to the LRU list because it may be pretty heavy with
16911                                // UI stuff.  We'll tag it with a label just to help
16912                                // debug and understand what is going on.
16913                                if (adj > clientAdj) {
16914                                    adjType = "cch-bound-ui-services";
16915                                }
16916                                app.cached = false;
16917                                clientAdj = adj;
16918                                clientProcState = procState;
16919                            } else {
16920                                if (now >= (s.lastActivity
16921                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16922                                    // This service has not seen activity within
16923                                    // recent memory, so allow it to drop to the
16924                                    // LRU list if there is no other reason to keep
16925                                    // it around.  We'll also tag it with a label just
16926                                    // to help debug and undertand what is going on.
16927                                    if (adj > clientAdj) {
16928                                        adjType = "cch-bound-services";
16929                                    }
16930                                    clientAdj = adj;
16931                                }
16932                            }
16933                        }
16934                        if (adj > clientAdj) {
16935                            // If this process has recently shown UI, and
16936                            // the process that is binding to it is less
16937                            // important than being visible, then we don't
16938                            // care about the binding as much as we care
16939                            // about letting this process get into the LRU
16940                            // list to be killed and restarted if needed for
16941                            // memory.
16942                            if (app.hasShownUi && app != mHomeProcess
16943                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16944                                adjType = "cch-bound-ui-services";
16945                            } else {
16946                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16947                                        |Context.BIND_IMPORTANT)) != 0) {
16948                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16949                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16950                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16951                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16952                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16953                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16954                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16955                                    adj = clientAdj;
16956                                } else {
16957                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16958                                        adj = ProcessList.VISIBLE_APP_ADJ;
16959                                    }
16960                                }
16961                                if (!client.cached) {
16962                                    app.cached = false;
16963                                }
16964                                adjType = "service";
16965                            }
16966                        }
16967                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16968                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16969                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16970                            }
16971                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16972                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16973                                    // Special handling of clients who are in the top state.
16974                                    // We *may* want to consider this process to be in the
16975                                    // top state as well, but only if there is not another
16976                                    // reason for it to be running.  Being on the top is a
16977                                    // special state, meaning you are specifically running
16978                                    // for the current top app.  If the process is already
16979                                    // running in the background for some other reason, it
16980                                    // is more important to continue considering it to be
16981                                    // in the background state.
16982                                    mayBeTop = true;
16983                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16984                                } else {
16985                                    // Special handling for above-top states (persistent
16986                                    // processes).  These should not bring the current process
16987                                    // into the top state, since they are not on top.  Instead
16988                                    // give them the best state after that.
16989                                    clientProcState =
16990                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16991                                }
16992                            }
16993                        } else {
16994                            if (clientProcState <
16995                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16996                                clientProcState =
16997                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16998                            }
16999                        }
17000                        if (procState > clientProcState) {
17001                            procState = clientProcState;
17002                        }
17003                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17004                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17005                            app.pendingUiClean = true;
17006                        }
17007                        if (adjType != null) {
17008                            app.adjType = adjType;
17009                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17010                                    .REASON_SERVICE_IN_USE;
17011                            app.adjSource = cr.binding.client;
17012                            app.adjSourceProcState = clientProcState;
17013                            app.adjTarget = s.name;
17014                        }
17015                    }
17016                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17017                        app.treatLikeActivity = true;
17018                    }
17019                    final ActivityRecord a = cr.activity;
17020                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17021                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17022                                (a.visible || a.state == ActivityState.RESUMED
17023                                 || a.state == ActivityState.PAUSING)) {
17024                            adj = ProcessList.FOREGROUND_APP_ADJ;
17025                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17026                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17027                            }
17028                            app.cached = false;
17029                            app.adjType = "service";
17030                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17031                                    .REASON_SERVICE_IN_USE;
17032                            app.adjSource = a;
17033                            app.adjSourceProcState = procState;
17034                            app.adjTarget = s.name;
17035                        }
17036                    }
17037                }
17038            }
17039        }
17040
17041        for (int provi = app.pubProviders.size()-1;
17042                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17043                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17044                        || procState > ActivityManager.PROCESS_STATE_TOP);
17045                provi--) {
17046            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17047            for (int i = cpr.connections.size()-1;
17048                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17049                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17050                            || procState > ActivityManager.PROCESS_STATE_TOP);
17051                    i--) {
17052                ContentProviderConnection conn = cpr.connections.get(i);
17053                ProcessRecord client = conn.client;
17054                if (client == app) {
17055                    // Being our own client is not interesting.
17056                    continue;
17057                }
17058                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17059                int clientProcState = client.curProcState;
17060                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17061                    // If the other app is cached for any reason, for purposes here
17062                    // we are going to consider it empty.
17063                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17064                }
17065                if (adj > clientAdj) {
17066                    if (app.hasShownUi && app != mHomeProcess
17067                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17068                        app.adjType = "cch-ui-provider";
17069                    } else {
17070                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17071                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17072                        app.adjType = "provider";
17073                    }
17074                    app.cached &= client.cached;
17075                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17076                            .REASON_PROVIDER_IN_USE;
17077                    app.adjSource = client;
17078                    app.adjSourceProcState = clientProcState;
17079                    app.adjTarget = cpr.name;
17080                }
17081                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17082                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17083                        // Special handling of clients who are in the top state.
17084                        // We *may* want to consider this process to be in the
17085                        // top state as well, but only if there is not another
17086                        // reason for it to be running.  Being on the top is a
17087                        // special state, meaning you are specifically running
17088                        // for the current top app.  If the process is already
17089                        // running in the background for some other reason, it
17090                        // is more important to continue considering it to be
17091                        // in the background state.
17092                        mayBeTop = true;
17093                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17094                    } else {
17095                        // Special handling for above-top states (persistent
17096                        // processes).  These should not bring the current process
17097                        // into the top state, since they are not on top.  Instead
17098                        // give them the best state after that.
17099                        clientProcState =
17100                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17101                    }
17102                }
17103                if (procState > clientProcState) {
17104                    procState = clientProcState;
17105                }
17106                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17107                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17108                }
17109            }
17110            // If the provider has external (non-framework) process
17111            // dependencies, ensure that its adjustment is at least
17112            // FOREGROUND_APP_ADJ.
17113            if (cpr.hasExternalProcessHandles()) {
17114                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17115                    adj = ProcessList.FOREGROUND_APP_ADJ;
17116                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17117                    app.cached = false;
17118                    app.adjType = "provider";
17119                    app.adjTarget = cpr.name;
17120                }
17121                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17122                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17123                }
17124            }
17125        }
17126
17127        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17128            // A client of one of our services or providers is in the top state.  We
17129            // *may* want to be in the top state, but not if we are already running in
17130            // the background for some other reason.  For the decision here, we are going
17131            // to pick out a few specific states that we want to remain in when a client
17132            // is top (states that tend to be longer-term) and otherwise allow it to go
17133            // to the top state.
17134            switch (procState) {
17135                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17136                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17137                case ActivityManager.PROCESS_STATE_SERVICE:
17138                    // These all are longer-term states, so pull them up to the top
17139                    // of the background states, but not all the way to the top state.
17140                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17141                    break;
17142                default:
17143                    // Otherwise, top is a better choice, so take it.
17144                    procState = ActivityManager.PROCESS_STATE_TOP;
17145                    break;
17146            }
17147        }
17148
17149        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17150            if (app.hasClientActivities) {
17151                // This is a cached process, but with client activities.  Mark it so.
17152                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17153                app.adjType = "cch-client-act";
17154            } else if (app.treatLikeActivity) {
17155                // This is a cached process, but somebody wants us to treat it like it has
17156                // an activity, okay!
17157                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17158                app.adjType = "cch-as-act";
17159            }
17160        }
17161
17162        if (adj == ProcessList.SERVICE_ADJ) {
17163            if (doingAll) {
17164                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17165                mNewNumServiceProcs++;
17166                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17167                if (!app.serviceb) {
17168                    // This service isn't far enough down on the LRU list to
17169                    // normally be a B service, but if we are low on RAM and it
17170                    // is large we want to force it down since we would prefer to
17171                    // keep launcher over it.
17172                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17173                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17174                        app.serviceHighRam = true;
17175                        app.serviceb = true;
17176                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17177                    } else {
17178                        mNewNumAServiceProcs++;
17179                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17180                    }
17181                } else {
17182                    app.serviceHighRam = false;
17183                }
17184            }
17185            if (app.serviceb) {
17186                adj = ProcessList.SERVICE_B_ADJ;
17187            }
17188        }
17189
17190        app.curRawAdj = adj;
17191
17192        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17193        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17194        if (adj > app.maxAdj) {
17195            adj = app.maxAdj;
17196            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17197                schedGroup = Process.THREAD_GROUP_DEFAULT;
17198            }
17199        }
17200
17201        // Do final modification to adj.  Everything we do between here and applying
17202        // the final setAdj must be done in this function, because we will also use
17203        // it when computing the final cached adj later.  Note that we don't need to
17204        // worry about this for max adj above, since max adj will always be used to
17205        // keep it out of the cached vaues.
17206        app.curAdj = app.modifyRawOomAdj(adj);
17207        app.curSchedGroup = schedGroup;
17208        app.curProcState = procState;
17209        app.foregroundActivities = foregroundActivities;
17210
17211        return app.curRawAdj;
17212    }
17213
17214    /**
17215     * Schedule PSS collection of a process.
17216     */
17217    void requestPssLocked(ProcessRecord proc, int procState) {
17218        if (mPendingPssProcesses.contains(proc)) {
17219            return;
17220        }
17221        if (mPendingPssProcesses.size() == 0) {
17222            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17223        }
17224        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17225        proc.pssProcState = procState;
17226        mPendingPssProcesses.add(proc);
17227    }
17228
17229    /**
17230     * Schedule PSS collection of all processes.
17231     */
17232    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17233        if (!always) {
17234            if (now < (mLastFullPssTime +
17235                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17236                return;
17237            }
17238        }
17239        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17240        mLastFullPssTime = now;
17241        mFullPssPending = true;
17242        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17243        mPendingPssProcesses.clear();
17244        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17245            ProcessRecord app = mLruProcesses.get(i);
17246            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17247                app.pssProcState = app.setProcState;
17248                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17249                        isSleeping(), now);
17250                mPendingPssProcesses.add(app);
17251            }
17252        }
17253        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17254    }
17255
17256    /**
17257     * Ask a given process to GC right now.
17258     */
17259    final void performAppGcLocked(ProcessRecord app) {
17260        try {
17261            app.lastRequestedGc = SystemClock.uptimeMillis();
17262            if (app.thread != null) {
17263                if (app.reportLowMemory) {
17264                    app.reportLowMemory = false;
17265                    app.thread.scheduleLowMemory();
17266                } else {
17267                    app.thread.processInBackground();
17268                }
17269            }
17270        } catch (Exception e) {
17271            // whatever.
17272        }
17273    }
17274
17275    /**
17276     * Returns true if things are idle enough to perform GCs.
17277     */
17278    private final boolean canGcNowLocked() {
17279        boolean processingBroadcasts = false;
17280        for (BroadcastQueue q : mBroadcastQueues) {
17281            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17282                processingBroadcasts = true;
17283            }
17284        }
17285        return !processingBroadcasts
17286                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17287    }
17288
17289    /**
17290     * Perform GCs on all processes that are waiting for it, but only
17291     * if things are idle.
17292     */
17293    final void performAppGcsLocked() {
17294        final int N = mProcessesToGc.size();
17295        if (N <= 0) {
17296            return;
17297        }
17298        if (canGcNowLocked()) {
17299            while (mProcessesToGc.size() > 0) {
17300                ProcessRecord proc = mProcessesToGc.remove(0);
17301                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17302                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17303                            <= SystemClock.uptimeMillis()) {
17304                        // To avoid spamming the system, we will GC processes one
17305                        // at a time, waiting a few seconds between each.
17306                        performAppGcLocked(proc);
17307                        scheduleAppGcsLocked();
17308                        return;
17309                    } else {
17310                        // It hasn't been long enough since we last GCed this
17311                        // process...  put it in the list to wait for its time.
17312                        addProcessToGcListLocked(proc);
17313                        break;
17314                    }
17315                }
17316            }
17317
17318            scheduleAppGcsLocked();
17319        }
17320    }
17321
17322    /**
17323     * If all looks good, perform GCs on all processes waiting for them.
17324     */
17325    final void performAppGcsIfAppropriateLocked() {
17326        if (canGcNowLocked()) {
17327            performAppGcsLocked();
17328            return;
17329        }
17330        // Still not idle, wait some more.
17331        scheduleAppGcsLocked();
17332    }
17333
17334    /**
17335     * Schedule the execution of all pending app GCs.
17336     */
17337    final void scheduleAppGcsLocked() {
17338        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17339
17340        if (mProcessesToGc.size() > 0) {
17341            // Schedule a GC for the time to the next process.
17342            ProcessRecord proc = mProcessesToGc.get(0);
17343            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17344
17345            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17346            long now = SystemClock.uptimeMillis();
17347            if (when < (now+GC_TIMEOUT)) {
17348                when = now + GC_TIMEOUT;
17349            }
17350            mHandler.sendMessageAtTime(msg, when);
17351        }
17352    }
17353
17354    /**
17355     * Add a process to the array of processes waiting to be GCed.  Keeps the
17356     * list in sorted order by the last GC time.  The process can't already be
17357     * on the list.
17358     */
17359    final void addProcessToGcListLocked(ProcessRecord proc) {
17360        boolean added = false;
17361        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17362            if (mProcessesToGc.get(i).lastRequestedGc <
17363                    proc.lastRequestedGc) {
17364                added = true;
17365                mProcessesToGc.add(i+1, proc);
17366                break;
17367            }
17368        }
17369        if (!added) {
17370            mProcessesToGc.add(0, proc);
17371        }
17372    }
17373
17374    /**
17375     * Set up to ask a process to GC itself.  This will either do it
17376     * immediately, or put it on the list of processes to gc the next
17377     * time things are idle.
17378     */
17379    final void scheduleAppGcLocked(ProcessRecord app) {
17380        long now = SystemClock.uptimeMillis();
17381        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17382            return;
17383        }
17384        if (!mProcessesToGc.contains(app)) {
17385            addProcessToGcListLocked(app);
17386            scheduleAppGcsLocked();
17387        }
17388    }
17389
17390    final void checkExcessivePowerUsageLocked(boolean doKills) {
17391        updateCpuStatsNow();
17392
17393        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17394        boolean doWakeKills = doKills;
17395        boolean doCpuKills = doKills;
17396        if (mLastPowerCheckRealtime == 0) {
17397            doWakeKills = false;
17398        }
17399        if (mLastPowerCheckUptime == 0) {
17400            doCpuKills = false;
17401        }
17402        if (stats.isScreenOn()) {
17403            doWakeKills = false;
17404        }
17405        final long curRealtime = SystemClock.elapsedRealtime();
17406        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17407        final long curUptime = SystemClock.uptimeMillis();
17408        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17409        mLastPowerCheckRealtime = curRealtime;
17410        mLastPowerCheckUptime = curUptime;
17411        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17412            doWakeKills = false;
17413        }
17414        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17415            doCpuKills = false;
17416        }
17417        int i = mLruProcesses.size();
17418        while (i > 0) {
17419            i--;
17420            ProcessRecord app = mLruProcesses.get(i);
17421            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17422                long wtime;
17423                synchronized (stats) {
17424                    wtime = stats.getProcessWakeTime(app.info.uid,
17425                            app.pid, curRealtime);
17426                }
17427                long wtimeUsed = wtime - app.lastWakeTime;
17428                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17429                if (DEBUG_POWER) {
17430                    StringBuilder sb = new StringBuilder(128);
17431                    sb.append("Wake for ");
17432                    app.toShortString(sb);
17433                    sb.append(": over ");
17434                    TimeUtils.formatDuration(realtimeSince, sb);
17435                    sb.append(" used ");
17436                    TimeUtils.formatDuration(wtimeUsed, sb);
17437                    sb.append(" (");
17438                    sb.append((wtimeUsed*100)/realtimeSince);
17439                    sb.append("%)");
17440                    Slog.i(TAG, sb.toString());
17441                    sb.setLength(0);
17442                    sb.append("CPU for ");
17443                    app.toShortString(sb);
17444                    sb.append(": over ");
17445                    TimeUtils.formatDuration(uptimeSince, sb);
17446                    sb.append(" used ");
17447                    TimeUtils.formatDuration(cputimeUsed, sb);
17448                    sb.append(" (");
17449                    sb.append((cputimeUsed*100)/uptimeSince);
17450                    sb.append("%)");
17451                    Slog.i(TAG, sb.toString());
17452                }
17453                // If a process has held a wake lock for more
17454                // than 50% of the time during this period,
17455                // that sounds bad.  Kill!
17456                if (doWakeKills && realtimeSince > 0
17457                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17458                    synchronized (stats) {
17459                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17460                                realtimeSince, wtimeUsed);
17461                    }
17462                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17463                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17464                } else if (doCpuKills && uptimeSince > 0
17465                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17466                    synchronized (stats) {
17467                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17468                                uptimeSince, cputimeUsed);
17469                    }
17470                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17471                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17472                } else {
17473                    app.lastWakeTime = wtime;
17474                    app.lastCpuTime = app.curCpuTime;
17475                }
17476            }
17477        }
17478    }
17479
17480    private final boolean applyOomAdjLocked(ProcessRecord app,
17481            ProcessRecord TOP_APP, boolean doingAll, long now) {
17482        boolean success = true;
17483
17484        if (app.curRawAdj != app.setRawAdj) {
17485            app.setRawAdj = app.curRawAdj;
17486        }
17487
17488        int changes = 0;
17489
17490        if (app.curAdj != app.setAdj) {
17491            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17492            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17493                TAG, "Set " + app.pid + " " + app.processName +
17494                " adj " + app.curAdj + ": " + app.adjType);
17495            app.setAdj = app.curAdj;
17496        }
17497
17498        if (app.setSchedGroup != app.curSchedGroup) {
17499            app.setSchedGroup = app.curSchedGroup;
17500            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17501                    "Setting process group of " + app.processName
17502                    + " to " + app.curSchedGroup);
17503            if (app.waitingToKill != null &&
17504                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17505                app.kill(app.waitingToKill, true);
17506                success = false;
17507            } else {
17508                if (true) {
17509                    long oldId = Binder.clearCallingIdentity();
17510                    try {
17511                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17512                    } catch (Exception e) {
17513                        Slog.w(TAG, "Failed setting process group of " + app.pid
17514                                + " to " + app.curSchedGroup);
17515                        e.printStackTrace();
17516                    } finally {
17517                        Binder.restoreCallingIdentity(oldId);
17518                    }
17519                } else {
17520                    if (app.thread != null) {
17521                        try {
17522                            app.thread.setSchedulingGroup(app.curSchedGroup);
17523                        } catch (RemoteException e) {
17524                        }
17525                    }
17526                }
17527                Process.setSwappiness(app.pid,
17528                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17529            }
17530        }
17531        if (app.repForegroundActivities != app.foregroundActivities) {
17532            app.repForegroundActivities = app.foregroundActivities;
17533            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17534        }
17535        if (app.repProcState != app.curProcState) {
17536            app.repProcState = app.curProcState;
17537            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17538            if (app.thread != null) {
17539                try {
17540                    if (false) {
17541                        //RuntimeException h = new RuntimeException("here");
17542                        Slog.i(TAG, "Sending new process state " + app.repProcState
17543                                + " to " + app /*, h*/);
17544                    }
17545                    app.thread.setProcessState(app.repProcState);
17546                } catch (RemoteException e) {
17547                }
17548            }
17549        }
17550        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17551                app.setProcState)) {
17552            app.lastStateTime = now;
17553            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17554                    isSleeping(), now);
17555            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17556                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17557                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17558                    + (app.nextPssTime-now) + ": " + app);
17559        } else {
17560            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17561                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17562                requestPssLocked(app, app.setProcState);
17563                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17564                        isSleeping(), now);
17565            } else if (false && DEBUG_PSS) {
17566                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17567            }
17568        }
17569        if (app.setProcState != app.curProcState) {
17570            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17571                    "Proc state change of " + app.processName
17572                    + " to " + app.curProcState);
17573            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17574            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17575            if (setImportant && !curImportant) {
17576                // This app is no longer something we consider important enough to allow to
17577                // use arbitrary amounts of battery power.  Note
17578                // its current wake lock time to later know to kill it if
17579                // it is not behaving well.
17580                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17581                synchronized (stats) {
17582                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17583                            app.pid, SystemClock.elapsedRealtime());
17584                }
17585                app.lastCpuTime = app.curCpuTime;
17586
17587            }
17588            app.setProcState = app.curProcState;
17589            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17590                app.notCachedSinceIdle = false;
17591            }
17592            if (!doingAll) {
17593                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17594            } else {
17595                app.procStateChanged = true;
17596            }
17597        }
17598
17599        if (changes != 0) {
17600            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17601            int i = mPendingProcessChanges.size()-1;
17602            ProcessChangeItem item = null;
17603            while (i >= 0) {
17604                item = mPendingProcessChanges.get(i);
17605                if (item.pid == app.pid) {
17606                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17607                    break;
17608                }
17609                i--;
17610            }
17611            if (i < 0) {
17612                // No existing item in pending changes; need a new one.
17613                final int NA = mAvailProcessChanges.size();
17614                if (NA > 0) {
17615                    item = mAvailProcessChanges.remove(NA-1);
17616                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17617                } else {
17618                    item = new ProcessChangeItem();
17619                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17620                }
17621                item.changes = 0;
17622                item.pid = app.pid;
17623                item.uid = app.info.uid;
17624                if (mPendingProcessChanges.size() == 0) {
17625                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17626                            "*** Enqueueing dispatch processes changed!");
17627                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17628                }
17629                mPendingProcessChanges.add(item);
17630            }
17631            item.changes |= changes;
17632            item.processState = app.repProcState;
17633            item.foregroundActivities = app.repForegroundActivities;
17634            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17635                    + Integer.toHexString(System.identityHashCode(item))
17636                    + " " + app.toShortString() + ": changes=" + item.changes
17637                    + " procState=" + item.processState
17638                    + " foreground=" + item.foregroundActivities
17639                    + " type=" + app.adjType + " source=" + app.adjSource
17640                    + " target=" + app.adjTarget);
17641        }
17642
17643        return success;
17644    }
17645
17646    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17647        if (proc.thread != null) {
17648            if (proc.baseProcessTracker != null) {
17649                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17650            }
17651            if (proc.repProcState >= 0) {
17652                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17653                        proc.repProcState);
17654            }
17655        }
17656    }
17657
17658    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17659            ProcessRecord TOP_APP, boolean doingAll, long now) {
17660        if (app.thread == null) {
17661            return false;
17662        }
17663
17664        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17665
17666        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17667    }
17668
17669    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17670            boolean oomAdj) {
17671        if (isForeground != proc.foregroundServices) {
17672            proc.foregroundServices = isForeground;
17673            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17674                    proc.info.uid);
17675            if (isForeground) {
17676                if (curProcs == null) {
17677                    curProcs = new ArrayList<ProcessRecord>();
17678                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17679                }
17680                if (!curProcs.contains(proc)) {
17681                    curProcs.add(proc);
17682                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17683                            proc.info.packageName, proc.info.uid);
17684                }
17685            } else {
17686                if (curProcs != null) {
17687                    if (curProcs.remove(proc)) {
17688                        mBatteryStatsService.noteEvent(
17689                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17690                                proc.info.packageName, proc.info.uid);
17691                        if (curProcs.size() <= 0) {
17692                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17693                        }
17694                    }
17695                }
17696            }
17697            if (oomAdj) {
17698                updateOomAdjLocked();
17699            }
17700        }
17701    }
17702
17703    private final ActivityRecord resumedAppLocked() {
17704        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17705        String pkg;
17706        int uid;
17707        if (act != null) {
17708            pkg = act.packageName;
17709            uid = act.info.applicationInfo.uid;
17710        } else {
17711            pkg = null;
17712            uid = -1;
17713        }
17714        // Has the UID or resumed package name changed?
17715        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17716                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17717            if (mCurResumedPackage != null) {
17718                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17719                        mCurResumedPackage, mCurResumedUid);
17720            }
17721            mCurResumedPackage = pkg;
17722            mCurResumedUid = uid;
17723            if (mCurResumedPackage != null) {
17724                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17725                        mCurResumedPackage, mCurResumedUid);
17726            }
17727        }
17728        return act;
17729    }
17730
17731    final boolean updateOomAdjLocked(ProcessRecord app) {
17732        final ActivityRecord TOP_ACT = resumedAppLocked();
17733        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17734        final boolean wasCached = app.cached;
17735
17736        mAdjSeq++;
17737
17738        // This is the desired cached adjusment we want to tell it to use.
17739        // If our app is currently cached, we know it, and that is it.  Otherwise,
17740        // we don't know it yet, and it needs to now be cached we will then
17741        // need to do a complete oom adj.
17742        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17743                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17744        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17745                SystemClock.uptimeMillis());
17746        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17747            // Changed to/from cached state, so apps after it in the LRU
17748            // list may also be changed.
17749            updateOomAdjLocked();
17750        }
17751        return success;
17752    }
17753
17754    final void updateOomAdjLocked() {
17755        final ActivityRecord TOP_ACT = resumedAppLocked();
17756        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17757        final long now = SystemClock.uptimeMillis();
17758        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17759        final int N = mLruProcesses.size();
17760
17761        if (false) {
17762            RuntimeException e = new RuntimeException();
17763            e.fillInStackTrace();
17764            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17765        }
17766
17767        mAdjSeq++;
17768        mNewNumServiceProcs = 0;
17769        mNewNumAServiceProcs = 0;
17770
17771        final int emptyProcessLimit;
17772        final int cachedProcessLimit;
17773        if (mProcessLimit <= 0) {
17774            emptyProcessLimit = cachedProcessLimit = 0;
17775        } else if (mProcessLimit == 1) {
17776            emptyProcessLimit = 1;
17777            cachedProcessLimit = 0;
17778        } else {
17779            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17780            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17781        }
17782
17783        // Let's determine how many processes we have running vs.
17784        // how many slots we have for background processes; we may want
17785        // to put multiple processes in a slot of there are enough of
17786        // them.
17787        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17788                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17789        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17790        if (numEmptyProcs > cachedProcessLimit) {
17791            // If there are more empty processes than our limit on cached
17792            // processes, then use the cached process limit for the factor.
17793            // This ensures that the really old empty processes get pushed
17794            // down to the bottom, so if we are running low on memory we will
17795            // have a better chance at keeping around more cached processes
17796            // instead of a gazillion empty processes.
17797            numEmptyProcs = cachedProcessLimit;
17798        }
17799        int emptyFactor = numEmptyProcs/numSlots;
17800        if (emptyFactor < 1) emptyFactor = 1;
17801        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17802        if (cachedFactor < 1) cachedFactor = 1;
17803        int stepCached = 0;
17804        int stepEmpty = 0;
17805        int numCached = 0;
17806        int numEmpty = 0;
17807        int numTrimming = 0;
17808
17809        mNumNonCachedProcs = 0;
17810        mNumCachedHiddenProcs = 0;
17811
17812        // First update the OOM adjustment for each of the
17813        // application processes based on their current state.
17814        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17815        int nextCachedAdj = curCachedAdj+1;
17816        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17817        int nextEmptyAdj = curEmptyAdj+2;
17818        for (int i=N-1; i>=0; i--) {
17819            ProcessRecord app = mLruProcesses.get(i);
17820            if (!app.killedByAm && app.thread != null) {
17821                app.procStateChanged = false;
17822                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17823
17824                // If we haven't yet assigned the final cached adj
17825                // to the process, do that now.
17826                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17827                    switch (app.curProcState) {
17828                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17829                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17830                            // This process is a cached process holding activities...
17831                            // assign it the next cached value for that type, and then
17832                            // step that cached level.
17833                            app.curRawAdj = curCachedAdj;
17834                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17835                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17836                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17837                                    + ")");
17838                            if (curCachedAdj != nextCachedAdj) {
17839                                stepCached++;
17840                                if (stepCached >= cachedFactor) {
17841                                    stepCached = 0;
17842                                    curCachedAdj = nextCachedAdj;
17843                                    nextCachedAdj += 2;
17844                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17845                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17846                                    }
17847                                }
17848                            }
17849                            break;
17850                        default:
17851                            // For everything else, assign next empty cached process
17852                            // level and bump that up.  Note that this means that
17853                            // long-running services that have dropped down to the
17854                            // cached level will be treated as empty (since their process
17855                            // state is still as a service), which is what we want.
17856                            app.curRawAdj = curEmptyAdj;
17857                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17858                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17859                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17860                                    + ")");
17861                            if (curEmptyAdj != nextEmptyAdj) {
17862                                stepEmpty++;
17863                                if (stepEmpty >= emptyFactor) {
17864                                    stepEmpty = 0;
17865                                    curEmptyAdj = nextEmptyAdj;
17866                                    nextEmptyAdj += 2;
17867                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17868                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17869                                    }
17870                                }
17871                            }
17872                            break;
17873                    }
17874                }
17875
17876                applyOomAdjLocked(app, TOP_APP, true, now);
17877
17878                // Count the number of process types.
17879                switch (app.curProcState) {
17880                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17881                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17882                        mNumCachedHiddenProcs++;
17883                        numCached++;
17884                        if (numCached > cachedProcessLimit) {
17885                            app.kill("cached #" + numCached, true);
17886                        }
17887                        break;
17888                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17889                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17890                                && app.lastActivityTime < oldTime) {
17891                            app.kill("empty for "
17892                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17893                                    / 1000) + "s", true);
17894                        } else {
17895                            numEmpty++;
17896                            if (numEmpty > emptyProcessLimit) {
17897                                app.kill("empty #" + numEmpty, true);
17898                            }
17899                        }
17900                        break;
17901                    default:
17902                        mNumNonCachedProcs++;
17903                        break;
17904                }
17905
17906                if (app.isolated && app.services.size() <= 0) {
17907                    // If this is an isolated process, and there are no
17908                    // services running in it, then the process is no longer
17909                    // needed.  We agressively kill these because we can by
17910                    // definition not re-use the same process again, and it is
17911                    // good to avoid having whatever code was running in them
17912                    // left sitting around after no longer needed.
17913                    app.kill("isolated not needed", true);
17914                }
17915
17916                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17917                        && !app.killedByAm) {
17918                    numTrimming++;
17919                }
17920            }
17921        }
17922
17923        mNumServiceProcs = mNewNumServiceProcs;
17924
17925        // Now determine the memory trimming level of background processes.
17926        // Unfortunately we need to start at the back of the list to do this
17927        // properly.  We only do this if the number of background apps we
17928        // are managing to keep around is less than half the maximum we desire;
17929        // if we are keeping a good number around, we'll let them use whatever
17930        // memory they want.
17931        final int numCachedAndEmpty = numCached + numEmpty;
17932        int memFactor;
17933        if (numCached <= ProcessList.TRIM_CACHED_APPS
17934                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17935            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17936                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17937            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17938                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17939            } else {
17940                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17941            }
17942        } else {
17943            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17944        }
17945        // We always allow the memory level to go up (better).  We only allow it to go
17946        // down if we are in a state where that is allowed, *and* the total number of processes
17947        // has gone down since last time.
17948        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17949                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17950                + " last=" + mLastNumProcesses);
17951        if (memFactor > mLastMemoryLevel) {
17952            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17953                memFactor = mLastMemoryLevel;
17954                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17955            }
17956        }
17957        mLastMemoryLevel = memFactor;
17958        mLastNumProcesses = mLruProcesses.size();
17959        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17960        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17961        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17962            if (mLowRamStartTime == 0) {
17963                mLowRamStartTime = now;
17964            }
17965            int step = 0;
17966            int fgTrimLevel;
17967            switch (memFactor) {
17968                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17969                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17970                    break;
17971                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17972                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17973                    break;
17974                default:
17975                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17976                    break;
17977            }
17978            int factor = numTrimming/3;
17979            int minFactor = 2;
17980            if (mHomeProcess != null) minFactor++;
17981            if (mPreviousProcess != null) minFactor++;
17982            if (factor < minFactor) factor = minFactor;
17983            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17984            for (int i=N-1; i>=0; i--) {
17985                ProcessRecord app = mLruProcesses.get(i);
17986                if (allChanged || app.procStateChanged) {
17987                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17988                    app.procStateChanged = false;
17989                }
17990                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17991                        && !app.killedByAm) {
17992                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17993                        try {
17994                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17995                                    "Trimming memory of " + app.processName
17996                                    + " to " + curLevel);
17997                            app.thread.scheduleTrimMemory(curLevel);
17998                        } catch (RemoteException e) {
17999                        }
18000                        if (false) {
18001                            // For now we won't do this; our memory trimming seems
18002                            // to be good enough at this point that destroying
18003                            // activities causes more harm than good.
18004                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18005                                    && app != mHomeProcess && app != mPreviousProcess) {
18006                                // Need to do this on its own message because the stack may not
18007                                // be in a consistent state at this point.
18008                                // For these apps we will also finish their activities
18009                                // to help them free memory.
18010                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18011                            }
18012                        }
18013                    }
18014                    app.trimMemoryLevel = curLevel;
18015                    step++;
18016                    if (step >= factor) {
18017                        step = 0;
18018                        switch (curLevel) {
18019                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18020                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18021                                break;
18022                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18023                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18024                                break;
18025                        }
18026                    }
18027                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18028                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18029                            && app.thread != null) {
18030                        try {
18031                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18032                                    "Trimming memory of heavy-weight " + app.processName
18033                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18034                            app.thread.scheduleTrimMemory(
18035                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18036                        } catch (RemoteException e) {
18037                        }
18038                    }
18039                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18040                } else {
18041                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18042                            || app.systemNoUi) && app.pendingUiClean) {
18043                        // If this application is now in the background and it
18044                        // had done UI, then give it the special trim level to
18045                        // have it free UI resources.
18046                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18047                        if (app.trimMemoryLevel < level && app.thread != null) {
18048                            try {
18049                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18050                                        "Trimming memory of bg-ui " + app.processName
18051                                        + " to " + level);
18052                                app.thread.scheduleTrimMemory(level);
18053                            } catch (RemoteException e) {
18054                            }
18055                        }
18056                        app.pendingUiClean = false;
18057                    }
18058                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18059                        try {
18060                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18061                                    "Trimming memory of fg " + app.processName
18062                                    + " to " + fgTrimLevel);
18063                            app.thread.scheduleTrimMemory(fgTrimLevel);
18064                        } catch (RemoteException e) {
18065                        }
18066                    }
18067                    app.trimMemoryLevel = fgTrimLevel;
18068                }
18069            }
18070        } else {
18071            if (mLowRamStartTime != 0) {
18072                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18073                mLowRamStartTime = 0;
18074            }
18075            for (int i=N-1; i>=0; i--) {
18076                ProcessRecord app = mLruProcesses.get(i);
18077                if (allChanged || app.procStateChanged) {
18078                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18079                    app.procStateChanged = false;
18080                }
18081                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18082                        || app.systemNoUi) && app.pendingUiClean) {
18083                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18084                            && app.thread != null) {
18085                        try {
18086                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18087                                    "Trimming memory of ui hidden " + app.processName
18088                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18089                            app.thread.scheduleTrimMemory(
18090                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18091                        } catch (RemoteException e) {
18092                        }
18093                    }
18094                    app.pendingUiClean = false;
18095                }
18096                app.trimMemoryLevel = 0;
18097            }
18098        }
18099
18100        if (mAlwaysFinishActivities) {
18101            // Need to do this on its own message because the stack may not
18102            // be in a consistent state at this point.
18103            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18104        }
18105
18106        if (allChanged) {
18107            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18108        }
18109
18110        if (mProcessStats.shouldWriteNowLocked(now)) {
18111            mHandler.post(new Runnable() {
18112                @Override public void run() {
18113                    synchronized (ActivityManagerService.this) {
18114                        mProcessStats.writeStateAsyncLocked();
18115                    }
18116                }
18117            });
18118        }
18119
18120        if (DEBUG_OOM_ADJ) {
18121            if (false) {
18122                RuntimeException here = new RuntimeException("here");
18123                here.fillInStackTrace();
18124                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18125            } else {
18126                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18127            }
18128        }
18129    }
18130
18131    final void trimApplications() {
18132        synchronized (this) {
18133            int i;
18134
18135            // First remove any unused application processes whose package
18136            // has been removed.
18137            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18138                final ProcessRecord app = mRemovedProcesses.get(i);
18139                if (app.activities.size() == 0
18140                        && app.curReceiver == null && app.services.size() == 0) {
18141                    Slog.i(
18142                        TAG, "Exiting empty application process "
18143                        + app.processName + " ("
18144                        + (app.thread != null ? app.thread.asBinder() : null)
18145                        + ")\n");
18146                    if (app.pid > 0 && app.pid != MY_PID) {
18147                        app.kill("empty", false);
18148                    } else {
18149                        try {
18150                            app.thread.scheduleExit();
18151                        } catch (Exception e) {
18152                            // Ignore exceptions.
18153                        }
18154                    }
18155                    cleanUpApplicationRecordLocked(app, false, true, -1);
18156                    mRemovedProcesses.remove(i);
18157
18158                    if (app.persistent) {
18159                        addAppLocked(app.info, false, null /* ABI override */);
18160                    }
18161                }
18162            }
18163
18164            // Now update the oom adj for all processes.
18165            updateOomAdjLocked();
18166        }
18167    }
18168
18169    /** This method sends the specified signal to each of the persistent apps */
18170    public void signalPersistentProcesses(int sig) throws RemoteException {
18171        if (sig != Process.SIGNAL_USR1) {
18172            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18173        }
18174
18175        synchronized (this) {
18176            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18177                    != PackageManager.PERMISSION_GRANTED) {
18178                throw new SecurityException("Requires permission "
18179                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18180            }
18181
18182            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18183                ProcessRecord r = mLruProcesses.get(i);
18184                if (r.thread != null && r.persistent) {
18185                    Process.sendSignal(r.pid, sig);
18186                }
18187            }
18188        }
18189    }
18190
18191    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18192        if (proc == null || proc == mProfileProc) {
18193            proc = mProfileProc;
18194            profileType = mProfileType;
18195            clearProfilerLocked();
18196        }
18197        if (proc == null) {
18198            return;
18199        }
18200        try {
18201            proc.thread.profilerControl(false, null, profileType);
18202        } catch (RemoteException e) {
18203            throw new IllegalStateException("Process disappeared");
18204        }
18205    }
18206
18207    private void clearProfilerLocked() {
18208        if (mProfileFd != null) {
18209            try {
18210                mProfileFd.close();
18211            } catch (IOException e) {
18212            }
18213        }
18214        mProfileApp = null;
18215        mProfileProc = null;
18216        mProfileFile = null;
18217        mProfileType = 0;
18218        mAutoStopProfiler = false;
18219        mSamplingInterval = 0;
18220    }
18221
18222    public boolean profileControl(String process, int userId, boolean start,
18223            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18224
18225        try {
18226            synchronized (this) {
18227                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18228                // its own permission.
18229                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18230                        != PackageManager.PERMISSION_GRANTED) {
18231                    throw new SecurityException("Requires permission "
18232                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18233                }
18234
18235                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18236                    throw new IllegalArgumentException("null profile info or fd");
18237                }
18238
18239                ProcessRecord proc = null;
18240                if (process != null) {
18241                    proc = findProcessLocked(process, userId, "profileControl");
18242                }
18243
18244                if (start && (proc == null || proc.thread == null)) {
18245                    throw new IllegalArgumentException("Unknown process: " + process);
18246                }
18247
18248                if (start) {
18249                    stopProfilerLocked(null, 0);
18250                    setProfileApp(proc.info, proc.processName, profilerInfo);
18251                    mProfileProc = proc;
18252                    mProfileType = profileType;
18253                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18254                    try {
18255                        fd = fd.dup();
18256                    } catch (IOException e) {
18257                        fd = null;
18258                    }
18259                    profilerInfo.profileFd = fd;
18260                    proc.thread.profilerControl(start, profilerInfo, profileType);
18261                    fd = null;
18262                    mProfileFd = null;
18263                } else {
18264                    stopProfilerLocked(proc, profileType);
18265                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18266                        try {
18267                            profilerInfo.profileFd.close();
18268                        } catch (IOException e) {
18269                        }
18270                    }
18271                }
18272
18273                return true;
18274            }
18275        } catch (RemoteException e) {
18276            throw new IllegalStateException("Process disappeared");
18277        } finally {
18278            if (profilerInfo != null && profilerInfo.profileFd != null) {
18279                try {
18280                    profilerInfo.profileFd.close();
18281                } catch (IOException e) {
18282                }
18283            }
18284        }
18285    }
18286
18287    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18288        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18289                userId, true, ALLOW_FULL_ONLY, callName, null);
18290        ProcessRecord proc = null;
18291        try {
18292            int pid = Integer.parseInt(process);
18293            synchronized (mPidsSelfLocked) {
18294                proc = mPidsSelfLocked.get(pid);
18295            }
18296        } catch (NumberFormatException e) {
18297        }
18298
18299        if (proc == null) {
18300            ArrayMap<String, SparseArray<ProcessRecord>> all
18301                    = mProcessNames.getMap();
18302            SparseArray<ProcessRecord> procs = all.get(process);
18303            if (procs != null && procs.size() > 0) {
18304                proc = procs.valueAt(0);
18305                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18306                    for (int i=1; i<procs.size(); i++) {
18307                        ProcessRecord thisProc = procs.valueAt(i);
18308                        if (thisProc.userId == userId) {
18309                            proc = thisProc;
18310                            break;
18311                        }
18312                    }
18313                }
18314            }
18315        }
18316
18317        return proc;
18318    }
18319
18320    public boolean dumpHeap(String process, int userId, boolean managed,
18321            String path, ParcelFileDescriptor fd) throws RemoteException {
18322
18323        try {
18324            synchronized (this) {
18325                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18326                // its own permission (same as profileControl).
18327                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18328                        != PackageManager.PERMISSION_GRANTED) {
18329                    throw new SecurityException("Requires permission "
18330                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18331                }
18332
18333                if (fd == null) {
18334                    throw new IllegalArgumentException("null fd");
18335                }
18336
18337                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18338                if (proc == null || proc.thread == null) {
18339                    throw new IllegalArgumentException("Unknown process: " + process);
18340                }
18341
18342                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18343                if (!isDebuggable) {
18344                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18345                        throw new SecurityException("Process not debuggable: " + proc);
18346                    }
18347                }
18348
18349                proc.thread.dumpHeap(managed, path, fd);
18350                fd = null;
18351                return true;
18352            }
18353        } catch (RemoteException e) {
18354            throw new IllegalStateException("Process disappeared");
18355        } finally {
18356            if (fd != null) {
18357                try {
18358                    fd.close();
18359                } catch (IOException e) {
18360                }
18361            }
18362        }
18363    }
18364
18365    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18366    public void monitor() {
18367        synchronized (this) { }
18368    }
18369
18370    void onCoreSettingsChange(Bundle settings) {
18371        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18372            ProcessRecord processRecord = mLruProcesses.get(i);
18373            try {
18374                if (processRecord.thread != null) {
18375                    processRecord.thread.setCoreSettings(settings);
18376                }
18377            } catch (RemoteException re) {
18378                /* ignore */
18379            }
18380        }
18381    }
18382
18383    // Multi-user methods
18384
18385    /**
18386     * Start user, if its not already running, but don't bring it to foreground.
18387     */
18388    @Override
18389    public boolean startUserInBackground(final int userId) {
18390        return startUser(userId, /* foreground */ false);
18391    }
18392
18393    /**
18394     * Start user, if its not already running, and bring it to foreground.
18395     */
18396    boolean startUserInForeground(final int userId, Dialog dlg) {
18397        boolean result = startUser(userId, /* foreground */ true);
18398        dlg.dismiss();
18399        return result;
18400    }
18401
18402    /**
18403     * Refreshes the list of users related to the current user when either a
18404     * user switch happens or when a new related user is started in the
18405     * background.
18406     */
18407    private void updateCurrentProfileIdsLocked() {
18408        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18409                mCurrentUserId, false /* enabledOnly */);
18410        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18411        for (int i = 0; i < currentProfileIds.length; i++) {
18412            currentProfileIds[i] = profiles.get(i).id;
18413        }
18414        mCurrentProfileIds = currentProfileIds;
18415
18416        synchronized (mUserProfileGroupIdsSelfLocked) {
18417            mUserProfileGroupIdsSelfLocked.clear();
18418            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18419            for (int i = 0; i < users.size(); i++) {
18420                UserInfo user = users.get(i);
18421                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18422                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18423                }
18424            }
18425        }
18426    }
18427
18428    private Set getProfileIdsLocked(int userId) {
18429        Set userIds = new HashSet<Integer>();
18430        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18431                userId, false /* enabledOnly */);
18432        for (UserInfo user : profiles) {
18433            userIds.add(Integer.valueOf(user.id));
18434        }
18435        return userIds;
18436    }
18437
18438    @Override
18439    public boolean switchUser(final int userId) {
18440        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18441        String userName;
18442        synchronized (this) {
18443            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18444            if (userInfo == null) {
18445                Slog.w(TAG, "No user info for user #" + userId);
18446                return false;
18447            }
18448            if (userInfo.isManagedProfile()) {
18449                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18450                return false;
18451            }
18452            userName = userInfo.name;
18453            mTargetUserId = userId;
18454        }
18455        mHandler.removeMessages(START_USER_SWITCH_MSG);
18456        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18457        return true;
18458    }
18459
18460    private void showUserSwitchDialog(int userId, String userName) {
18461        // The dialog will show and then initiate the user switch by calling startUserInForeground
18462        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18463                true /* above system */);
18464        d.show();
18465    }
18466
18467    private boolean startUser(final int userId, final boolean foreground) {
18468        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18469                != PackageManager.PERMISSION_GRANTED) {
18470            String msg = "Permission Denial: switchUser() from pid="
18471                    + Binder.getCallingPid()
18472                    + ", uid=" + Binder.getCallingUid()
18473                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18474            Slog.w(TAG, msg);
18475            throw new SecurityException(msg);
18476        }
18477
18478        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18479
18480        final long ident = Binder.clearCallingIdentity();
18481        try {
18482            synchronized (this) {
18483                final int oldUserId = mCurrentUserId;
18484                if (oldUserId == userId) {
18485                    return true;
18486                }
18487
18488                mStackSupervisor.setLockTaskModeLocked(null, false);
18489
18490                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18491                if (userInfo == null) {
18492                    Slog.w(TAG, "No user info for user #" + userId);
18493                    return false;
18494                }
18495                if (foreground && userInfo.isManagedProfile()) {
18496                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18497                    return false;
18498                }
18499
18500                if (foreground) {
18501                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18502                            R.anim.screen_user_enter);
18503                }
18504
18505                boolean needStart = false;
18506
18507                // If the user we are switching to is not currently started, then
18508                // we need to start it now.
18509                if (mStartedUsers.get(userId) == null) {
18510                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18511                    updateStartedUserArrayLocked();
18512                    needStart = true;
18513                }
18514
18515                final Integer userIdInt = Integer.valueOf(userId);
18516                mUserLru.remove(userIdInt);
18517                mUserLru.add(userIdInt);
18518
18519                if (foreground) {
18520                    mCurrentUserId = userId;
18521                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18522                    updateCurrentProfileIdsLocked();
18523                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18524                    // Once the internal notion of the active user has switched, we lock the device
18525                    // with the option to show the user switcher on the keyguard.
18526                    mWindowManager.lockNow(null);
18527                } else {
18528                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18529                    updateCurrentProfileIdsLocked();
18530                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18531                    mUserLru.remove(currentUserIdInt);
18532                    mUserLru.add(currentUserIdInt);
18533                }
18534
18535                final UserStartedState uss = mStartedUsers.get(userId);
18536
18537                // Make sure user is in the started state.  If it is currently
18538                // stopping, we need to knock that off.
18539                if (uss.mState == UserStartedState.STATE_STOPPING) {
18540                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18541                    // so we can just fairly silently bring the user back from
18542                    // the almost-dead.
18543                    uss.mState = UserStartedState.STATE_RUNNING;
18544                    updateStartedUserArrayLocked();
18545                    needStart = true;
18546                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18547                    // This means ACTION_SHUTDOWN has been sent, so we will
18548                    // need to treat this as a new boot of the user.
18549                    uss.mState = UserStartedState.STATE_BOOTING;
18550                    updateStartedUserArrayLocked();
18551                    needStart = true;
18552                }
18553
18554                if (uss.mState == UserStartedState.STATE_BOOTING) {
18555                    // Booting up a new user, need to tell system services about it.
18556                    // Note that this is on the same handler as scheduling of broadcasts,
18557                    // which is important because it needs to go first.
18558                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18559                }
18560
18561                if (foreground) {
18562                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18563                            oldUserId));
18564                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18565                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18566                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18567                            oldUserId, userId, uss));
18568                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18569                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18570                }
18571
18572                if (needStart) {
18573                    // Send USER_STARTED broadcast
18574                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18575                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18576                            | Intent.FLAG_RECEIVER_FOREGROUND);
18577                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18578                    broadcastIntentLocked(null, null, intent,
18579                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18580                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18581                }
18582
18583                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18584                    if (userId != UserHandle.USER_OWNER) {
18585                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18586                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18587                        broadcastIntentLocked(null, null, intent, null,
18588                                new IIntentReceiver.Stub() {
18589                                    public void performReceive(Intent intent, int resultCode,
18590                                            String data, Bundle extras, boolean ordered,
18591                                            boolean sticky, int sendingUser) {
18592                                        onUserInitialized(uss, foreground, oldUserId, userId);
18593                                    }
18594                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18595                                true, false, MY_PID, Process.SYSTEM_UID,
18596                                userId);
18597                        uss.initializing = true;
18598                    } else {
18599                        getUserManagerLocked().makeInitialized(userInfo.id);
18600                    }
18601                }
18602
18603                if (foreground) {
18604                    if (!uss.initializing) {
18605                        moveUserToForeground(uss, oldUserId, userId);
18606                    }
18607                } else {
18608                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18609                }
18610
18611                if (needStart) {
18612                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18613                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18614                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18615                    broadcastIntentLocked(null, null, intent,
18616                            null, new IIntentReceiver.Stub() {
18617                                @Override
18618                                public void performReceive(Intent intent, int resultCode, String data,
18619                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18620                                        throws RemoteException {
18621                                }
18622                            }, 0, null, null,
18623                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18624                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18625                }
18626            }
18627        } finally {
18628            Binder.restoreCallingIdentity(ident);
18629        }
18630
18631        return true;
18632    }
18633
18634    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18635        long ident = Binder.clearCallingIdentity();
18636        try {
18637            Intent intent;
18638            if (oldUserId >= 0) {
18639                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18640                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18641                int count = profiles.size();
18642                for (int i = 0; i < count; i++) {
18643                    int profileUserId = profiles.get(i).id;
18644                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18645                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18646                            | Intent.FLAG_RECEIVER_FOREGROUND);
18647                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18648                    broadcastIntentLocked(null, null, intent,
18649                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18650                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18651                }
18652            }
18653            if (newUserId >= 0) {
18654                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18655                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18656                int count = profiles.size();
18657                for (int i = 0; i < count; i++) {
18658                    int profileUserId = profiles.get(i).id;
18659                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18660                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18661                            | Intent.FLAG_RECEIVER_FOREGROUND);
18662                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18663                    broadcastIntentLocked(null, null, intent,
18664                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18665                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18666                }
18667                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18668                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18669                        | Intent.FLAG_RECEIVER_FOREGROUND);
18670                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18671                broadcastIntentLocked(null, null, intent,
18672                        null, null, 0, null, null,
18673                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18674                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18675            }
18676        } finally {
18677            Binder.restoreCallingIdentity(ident);
18678        }
18679    }
18680
18681    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18682            final int newUserId) {
18683        final int N = mUserSwitchObservers.beginBroadcast();
18684        if (N > 0) {
18685            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18686                int mCount = 0;
18687                @Override
18688                public void sendResult(Bundle data) throws RemoteException {
18689                    synchronized (ActivityManagerService.this) {
18690                        if (mCurUserSwitchCallback == this) {
18691                            mCount++;
18692                            if (mCount == N) {
18693                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18694                            }
18695                        }
18696                    }
18697                }
18698            };
18699            synchronized (this) {
18700                uss.switching = true;
18701                mCurUserSwitchCallback = callback;
18702            }
18703            for (int i=0; i<N; i++) {
18704                try {
18705                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18706                            newUserId, callback);
18707                } catch (RemoteException e) {
18708                }
18709            }
18710        } else {
18711            synchronized (this) {
18712                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18713            }
18714        }
18715        mUserSwitchObservers.finishBroadcast();
18716    }
18717
18718    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18719        synchronized (this) {
18720            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18721            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18722        }
18723    }
18724
18725    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18726        mCurUserSwitchCallback = null;
18727        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18728        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18729                oldUserId, newUserId, uss));
18730    }
18731
18732    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18733        synchronized (this) {
18734            if (foreground) {
18735                moveUserToForeground(uss, oldUserId, newUserId);
18736            }
18737        }
18738
18739        completeSwitchAndInitalize(uss, newUserId, true, false);
18740    }
18741
18742    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18743        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18744        if (homeInFront) {
18745            startHomeActivityLocked(newUserId);
18746        } else {
18747            mStackSupervisor.resumeTopActivitiesLocked();
18748        }
18749        EventLogTags.writeAmSwitchUser(newUserId);
18750        getUserManagerLocked().userForeground(newUserId);
18751        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18752    }
18753
18754    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18755        completeSwitchAndInitalize(uss, newUserId, false, true);
18756    }
18757
18758    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18759            boolean clearInitializing, boolean clearSwitching) {
18760        boolean unfrozen = false;
18761        synchronized (this) {
18762            if (clearInitializing) {
18763                uss.initializing = false;
18764                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18765            }
18766            if (clearSwitching) {
18767                uss.switching = false;
18768            }
18769            if (!uss.switching && !uss.initializing) {
18770                mWindowManager.stopFreezingScreen();
18771                unfrozen = true;
18772            }
18773        }
18774        if (unfrozen) {
18775            final int N = mUserSwitchObservers.beginBroadcast();
18776            for (int i=0; i<N; i++) {
18777                try {
18778                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18779                } catch (RemoteException e) {
18780                }
18781            }
18782            mUserSwitchObservers.finishBroadcast();
18783        }
18784    }
18785
18786    void scheduleStartProfilesLocked() {
18787        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18788            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18789                    DateUtils.SECOND_IN_MILLIS);
18790        }
18791    }
18792
18793    void startProfilesLocked() {
18794        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18795        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18796                mCurrentUserId, false /* enabledOnly */);
18797        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18798        for (UserInfo user : profiles) {
18799            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18800                    && user.id != mCurrentUserId) {
18801                toStart.add(user);
18802            }
18803        }
18804        final int n = toStart.size();
18805        int i = 0;
18806        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18807            startUserInBackground(toStart.get(i).id);
18808        }
18809        if (i < n) {
18810            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18811        }
18812    }
18813
18814    void finishUserBoot(UserStartedState uss) {
18815        synchronized (this) {
18816            if (uss.mState == UserStartedState.STATE_BOOTING
18817                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18818                uss.mState = UserStartedState.STATE_RUNNING;
18819                final int userId = uss.mHandle.getIdentifier();
18820                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18821                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18822                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18823                broadcastIntentLocked(null, null, intent,
18824                        null, null, 0, null, null,
18825                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18826                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18827            }
18828        }
18829    }
18830
18831    void finishUserSwitch(UserStartedState uss) {
18832        synchronized (this) {
18833            finishUserBoot(uss);
18834
18835            startProfilesLocked();
18836
18837            int num = mUserLru.size();
18838            int i = 0;
18839            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18840                Integer oldUserId = mUserLru.get(i);
18841                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18842                if (oldUss == null) {
18843                    // Shouldn't happen, but be sane if it does.
18844                    mUserLru.remove(i);
18845                    num--;
18846                    continue;
18847                }
18848                if (oldUss.mState == UserStartedState.STATE_STOPPING
18849                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18850                    // This user is already stopping, doesn't count.
18851                    num--;
18852                    i++;
18853                    continue;
18854                }
18855                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18856                    // Owner and current can't be stopped, but count as running.
18857                    i++;
18858                    continue;
18859                }
18860                // This is a user to be stopped.
18861                stopUserLocked(oldUserId, null);
18862                num--;
18863                i++;
18864            }
18865        }
18866    }
18867
18868    @Override
18869    public int stopUser(final int userId, final IStopUserCallback callback) {
18870        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18871                != PackageManager.PERMISSION_GRANTED) {
18872            String msg = "Permission Denial: switchUser() from pid="
18873                    + Binder.getCallingPid()
18874                    + ", uid=" + Binder.getCallingUid()
18875                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18876            Slog.w(TAG, msg);
18877            throw new SecurityException(msg);
18878        }
18879        if (userId <= 0) {
18880            throw new IllegalArgumentException("Can't stop primary user " + userId);
18881        }
18882        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18883        synchronized (this) {
18884            return stopUserLocked(userId, callback);
18885        }
18886    }
18887
18888    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18889        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18890        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18891            return ActivityManager.USER_OP_IS_CURRENT;
18892        }
18893
18894        final UserStartedState uss = mStartedUsers.get(userId);
18895        if (uss == null) {
18896            // User is not started, nothing to do...  but we do need to
18897            // callback if requested.
18898            if (callback != null) {
18899                mHandler.post(new Runnable() {
18900                    @Override
18901                    public void run() {
18902                        try {
18903                            callback.userStopped(userId);
18904                        } catch (RemoteException e) {
18905                        }
18906                    }
18907                });
18908            }
18909            return ActivityManager.USER_OP_SUCCESS;
18910        }
18911
18912        if (callback != null) {
18913            uss.mStopCallbacks.add(callback);
18914        }
18915
18916        if (uss.mState != UserStartedState.STATE_STOPPING
18917                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18918            uss.mState = UserStartedState.STATE_STOPPING;
18919            updateStartedUserArrayLocked();
18920
18921            long ident = Binder.clearCallingIdentity();
18922            try {
18923                // We are going to broadcast ACTION_USER_STOPPING and then
18924                // once that is done send a final ACTION_SHUTDOWN and then
18925                // stop the user.
18926                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18927                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18928                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18929                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18930                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18931                // This is the result receiver for the final shutdown broadcast.
18932                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18933                    @Override
18934                    public void performReceive(Intent intent, int resultCode, String data,
18935                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18936                        finishUserStop(uss);
18937                    }
18938                };
18939                // This is the result receiver for the initial stopping broadcast.
18940                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18941                    @Override
18942                    public void performReceive(Intent intent, int resultCode, String data,
18943                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18944                        // On to the next.
18945                        synchronized (ActivityManagerService.this) {
18946                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18947                                // Whoops, we are being started back up.  Abort, abort!
18948                                return;
18949                            }
18950                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18951                        }
18952                        mBatteryStatsService.noteEvent(
18953                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18954                                Integer.toString(userId), userId);
18955                        mSystemServiceManager.stopUser(userId);
18956                        broadcastIntentLocked(null, null, shutdownIntent,
18957                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18958                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18959                    }
18960                };
18961                // Kick things off.
18962                broadcastIntentLocked(null, null, stoppingIntent,
18963                        null, stoppingReceiver, 0, null, null,
18964                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18965                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18966            } finally {
18967                Binder.restoreCallingIdentity(ident);
18968            }
18969        }
18970
18971        return ActivityManager.USER_OP_SUCCESS;
18972    }
18973
18974    void finishUserStop(UserStartedState uss) {
18975        final int userId = uss.mHandle.getIdentifier();
18976        boolean stopped;
18977        ArrayList<IStopUserCallback> callbacks;
18978        synchronized (this) {
18979            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18980            if (mStartedUsers.get(userId) != uss) {
18981                stopped = false;
18982            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18983                stopped = false;
18984            } else {
18985                stopped = true;
18986                // User can no longer run.
18987                mStartedUsers.remove(userId);
18988                mUserLru.remove(Integer.valueOf(userId));
18989                updateStartedUserArrayLocked();
18990
18991                // Clean up all state and processes associated with the user.
18992                // Kill all the processes for the user.
18993                forceStopUserLocked(userId, "finish user");
18994            }
18995
18996            // Explicitly remove the old information in mRecentTasks.
18997            removeRecentTasksForUserLocked(userId);
18998        }
18999
19000        for (int i=0; i<callbacks.size(); i++) {
19001            try {
19002                if (stopped) callbacks.get(i).userStopped(userId);
19003                else callbacks.get(i).userStopAborted(userId);
19004            } catch (RemoteException e) {
19005            }
19006        }
19007
19008        if (stopped) {
19009            mSystemServiceManager.cleanupUser(userId);
19010            synchronized (this) {
19011                mStackSupervisor.removeUserLocked(userId);
19012            }
19013        }
19014    }
19015
19016    @Override
19017    public UserInfo getCurrentUser() {
19018        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19019                != PackageManager.PERMISSION_GRANTED) && (
19020                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19021                != PackageManager.PERMISSION_GRANTED)) {
19022            String msg = "Permission Denial: getCurrentUser() from pid="
19023                    + Binder.getCallingPid()
19024                    + ", uid=" + Binder.getCallingUid()
19025                    + " requires " + INTERACT_ACROSS_USERS;
19026            Slog.w(TAG, msg);
19027            throw new SecurityException(msg);
19028        }
19029        synchronized (this) {
19030            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19031            return getUserManagerLocked().getUserInfo(userId);
19032        }
19033    }
19034
19035    int getCurrentUserIdLocked() {
19036        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19037    }
19038
19039    @Override
19040    public boolean isUserRunning(int userId, boolean orStopped) {
19041        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19042                != PackageManager.PERMISSION_GRANTED) {
19043            String msg = "Permission Denial: isUserRunning() from pid="
19044                    + Binder.getCallingPid()
19045                    + ", uid=" + Binder.getCallingUid()
19046                    + " requires " + INTERACT_ACROSS_USERS;
19047            Slog.w(TAG, msg);
19048            throw new SecurityException(msg);
19049        }
19050        synchronized (this) {
19051            return isUserRunningLocked(userId, orStopped);
19052        }
19053    }
19054
19055    boolean isUserRunningLocked(int userId, boolean orStopped) {
19056        UserStartedState state = mStartedUsers.get(userId);
19057        if (state == null) {
19058            return false;
19059        }
19060        if (orStopped) {
19061            return true;
19062        }
19063        return state.mState != UserStartedState.STATE_STOPPING
19064                && state.mState != UserStartedState.STATE_SHUTDOWN;
19065    }
19066
19067    @Override
19068    public int[] getRunningUserIds() {
19069        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19070                != PackageManager.PERMISSION_GRANTED) {
19071            String msg = "Permission Denial: isUserRunning() from pid="
19072                    + Binder.getCallingPid()
19073                    + ", uid=" + Binder.getCallingUid()
19074                    + " requires " + INTERACT_ACROSS_USERS;
19075            Slog.w(TAG, msg);
19076            throw new SecurityException(msg);
19077        }
19078        synchronized (this) {
19079            return mStartedUserArray;
19080        }
19081    }
19082
19083    private void updateStartedUserArrayLocked() {
19084        int num = 0;
19085        for (int i=0; i<mStartedUsers.size();  i++) {
19086            UserStartedState uss = mStartedUsers.valueAt(i);
19087            // This list does not include stopping users.
19088            if (uss.mState != UserStartedState.STATE_STOPPING
19089                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19090                num++;
19091            }
19092        }
19093        mStartedUserArray = new int[num];
19094        num = 0;
19095        for (int i=0; i<mStartedUsers.size();  i++) {
19096            UserStartedState uss = mStartedUsers.valueAt(i);
19097            if (uss.mState != UserStartedState.STATE_STOPPING
19098                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19099                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19100                num++;
19101            }
19102        }
19103    }
19104
19105    @Override
19106    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19107        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19108                != PackageManager.PERMISSION_GRANTED) {
19109            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19110                    + Binder.getCallingPid()
19111                    + ", uid=" + Binder.getCallingUid()
19112                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19113            Slog.w(TAG, msg);
19114            throw new SecurityException(msg);
19115        }
19116
19117        mUserSwitchObservers.register(observer);
19118    }
19119
19120    @Override
19121    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19122        mUserSwitchObservers.unregister(observer);
19123    }
19124
19125    private boolean userExists(int userId) {
19126        if (userId == 0) {
19127            return true;
19128        }
19129        UserManagerService ums = getUserManagerLocked();
19130        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19131    }
19132
19133    int[] getUsersLocked() {
19134        UserManagerService ums = getUserManagerLocked();
19135        return ums != null ? ums.getUserIds() : new int[] { 0 };
19136    }
19137
19138    UserManagerService getUserManagerLocked() {
19139        if (mUserManager == null) {
19140            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19141            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19142        }
19143        return mUserManager;
19144    }
19145
19146    private int applyUserId(int uid, int userId) {
19147        return UserHandle.getUid(userId, uid);
19148    }
19149
19150    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19151        if (info == null) return null;
19152        ApplicationInfo newInfo = new ApplicationInfo(info);
19153        newInfo.uid = applyUserId(info.uid, userId);
19154        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19155                + info.packageName;
19156        return newInfo;
19157    }
19158
19159    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19160        if (aInfo == null
19161                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19162            return aInfo;
19163        }
19164
19165        ActivityInfo info = new ActivityInfo(aInfo);
19166        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19167        return info;
19168    }
19169
19170    private final class LocalService extends ActivityManagerInternal {
19171        @Override
19172        public void goingToSleep() {
19173            ActivityManagerService.this.goingToSleep();
19174        }
19175
19176        @Override
19177        public void wakingUp() {
19178            ActivityManagerService.this.wakingUp();
19179        }
19180
19181        @Override
19182        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19183                String processName, String abiOverride, int uid, Runnable crashHandler) {
19184            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19185                    processName, abiOverride, uid, crashHandler);
19186        }
19187    }
19188
19189    /**
19190     * An implementation of IAppTask, that allows an app to manage its own tasks via
19191     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19192     * only the process that calls getAppTasks() can call the AppTask methods.
19193     */
19194    class AppTaskImpl extends IAppTask.Stub {
19195        private int mTaskId;
19196        private int mCallingUid;
19197
19198        public AppTaskImpl(int taskId, int callingUid) {
19199            mTaskId = taskId;
19200            mCallingUid = callingUid;
19201        }
19202
19203        private void checkCaller() {
19204            if (mCallingUid != Binder.getCallingUid()) {
19205                throw new SecurityException("Caller " + mCallingUid
19206                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19207            }
19208        }
19209
19210        @Override
19211        public void finishAndRemoveTask() {
19212            checkCaller();
19213
19214            synchronized (ActivityManagerService.this) {
19215                long origId = Binder.clearCallingIdentity();
19216                try {
19217                    if (!removeTaskByIdLocked(mTaskId, false)) {
19218                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19219                    }
19220                } finally {
19221                    Binder.restoreCallingIdentity(origId);
19222                }
19223            }
19224        }
19225
19226        @Override
19227        public ActivityManager.RecentTaskInfo getTaskInfo() {
19228            checkCaller();
19229
19230            synchronized (ActivityManagerService.this) {
19231                long origId = Binder.clearCallingIdentity();
19232                try {
19233                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19234                    if (tr == null) {
19235                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19236                    }
19237                    return createRecentTaskInfoFromTaskRecord(tr);
19238                } finally {
19239                    Binder.restoreCallingIdentity(origId);
19240                }
19241            }
19242        }
19243
19244        @Override
19245        public void moveToFront() {
19246            checkCaller();
19247
19248            final TaskRecord tr;
19249            synchronized (ActivityManagerService.this) {
19250                tr = recentTaskForIdLocked(mTaskId);
19251                if (tr == null) {
19252                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19253                }
19254                if (tr.getRootActivity() != null) {
19255                    moveTaskToFrontLocked(tr.taskId, 0, null);
19256                    return;
19257                }
19258            }
19259
19260            startActivityFromRecentsInner(tr.taskId, null);
19261        }
19262
19263        @Override
19264        public int startActivity(IBinder whoThread, String callingPackage,
19265                Intent intent, String resolvedType, Bundle options) {
19266            checkCaller();
19267
19268            int callingUser = UserHandle.getCallingUserId();
19269            TaskRecord tr;
19270            IApplicationThread appThread;
19271            synchronized (ActivityManagerService.this) {
19272                tr = recentTaskForIdLocked(mTaskId);
19273                if (tr == null) {
19274                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19275                }
19276                appThread = ApplicationThreadNative.asInterface(whoThread);
19277                if (appThread == null) {
19278                    throw new IllegalArgumentException("Bad app thread " + appThread);
19279                }
19280            }
19281            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19282                    resolvedType, null, null, null, null, 0, 0, null, null,
19283                    null, options, callingUser, null, tr);
19284        }
19285
19286        @Override
19287        public void setExcludeFromRecents(boolean exclude) {
19288            checkCaller();
19289
19290            synchronized (ActivityManagerService.this) {
19291                long origId = Binder.clearCallingIdentity();
19292                try {
19293                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19294                    if (tr == null) {
19295                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19296                    }
19297                    Intent intent = tr.getBaseIntent();
19298                    if (exclude) {
19299                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19300                    } else {
19301                        intent.setFlags(intent.getFlags()
19302                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19303                    }
19304                } finally {
19305                    Binder.restoreCallingIdentity(origId);
19306                }
19307            }
19308        }
19309    }
19310}
19311