ActivityManagerService.java revision 044d52934e57a337665f707aa4be1d423ee3fb29
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.UserManagerService;
85import com.android.server.wm.AppTransition;
86import com.android.server.wm.WindowManagerService;
87import com.google.android.collect.Lists;
88import com.google.android.collect.Maps;
89
90import libcore.io.IoUtils;
91
92import org.xmlpull.v1.XmlPullParser;
93import org.xmlpull.v1.XmlPullParserException;
94import org.xmlpull.v1.XmlSerializer;
95
96import android.app.Activity;
97import android.app.ActivityManager;
98import android.app.ActivityManager.RunningTaskInfo;
99import android.app.ActivityManager.StackInfo;
100import android.app.ActivityManagerInternal;
101import android.app.ActivityManagerNative;
102import android.app.ActivityOptions;
103import android.app.ActivityThread;
104import android.app.AlertDialog;
105import android.app.AppGlobals;
106import android.app.ApplicationErrorReport;
107import android.app.Dialog;
108import android.app.IActivityController;
109import android.app.IApplicationThread;
110import android.app.IInstrumentationWatcher;
111import android.app.INotificationManager;
112import android.app.IProcessObserver;
113import android.app.IServiceConnection;
114import android.app.IStopUserCallback;
115import android.app.IUiAutomationConnection;
116import android.app.IUserSwitchObserver;
117import android.app.Instrumentation;
118import android.app.Notification;
119import android.app.NotificationManager;
120import android.app.PendingIntent;
121import android.app.backup.IBackupManager;
122import android.content.ActivityNotFoundException;
123import android.content.BroadcastReceiver;
124import android.content.ClipData;
125import android.content.ComponentCallbacks2;
126import android.content.ComponentName;
127import android.content.ContentProvider;
128import android.content.ContentResolver;
129import android.content.Context;
130import android.content.DialogInterface;
131import android.content.IContentProvider;
132import android.content.IIntentReceiver;
133import android.content.IIntentSender;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.ConfigurationInfo;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageManager;
142import android.content.pm.InstrumentationInfo;
143import android.content.pm.PackageInfo;
144import android.content.pm.PackageManager;
145import android.content.pm.ParceledListSlice;
146import android.content.pm.UserInfo;
147import android.content.pm.PackageManager.NameNotFoundException;
148import android.content.pm.PathPermission;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.res.CompatibilityInfo;
153import android.content.res.Configuration;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IRemoteCallback;
170import android.os.IUserManager;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.Process;
176import android.os.RemoteCallbackList;
177import android.os.RemoteException;
178import android.os.SELinux;
179import android.os.ServiceManager;
180import android.os.StrictMode;
181import android.os.SystemClock;
182import android.os.SystemProperties;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.provider.Settings;
187import android.text.format.DateUtils;
188import android.text.format.Time;
189import android.util.AtomicFile;
190import android.util.EventLog;
191import android.util.Log;
192import android.util.Pair;
193import android.util.PrintWriterPrinter;
194import android.util.Slog;
195import android.util.SparseArray;
196import android.util.TimeUtils;
197import android.util.Xml;
198import android.view.Gravity;
199import android.view.LayoutInflater;
200import android.view.View;
201import android.view.WindowManager;
202import dalvik.system.VMRuntime;
203
204import java.io.BufferedInputStream;
205import java.io.BufferedOutputStream;
206import java.io.DataInputStream;
207import java.io.DataOutputStream;
208import java.io.File;
209import java.io.FileDescriptor;
210import java.io.FileInputStream;
211import java.io.FileNotFoundException;
212import java.io.FileOutputStream;
213import java.io.IOException;
214import java.io.InputStreamReader;
215import java.io.PrintWriter;
216import java.io.StringWriter;
217import java.lang.ref.WeakReference;
218import java.util.ArrayList;
219import java.util.Arrays;
220import java.util.Collections;
221import java.util.Comparator;
222import java.util.HashMap;
223import java.util.HashSet;
224import java.util.Iterator;
225import java.util.List;
226import java.util.Locale;
227import java.util.Map;
228import java.util.Set;
229import java.util.concurrent.atomic.AtomicBoolean;
230import java.util.concurrent.atomic.AtomicLong;
231
232public final class ActivityManagerService extends ActivityManagerNative
233        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
234
235    private static final String USER_DATA_DIR = "/data/user/";
236    // File that stores last updated system version and called preboot receivers
237    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
238
239    static final String TAG = "ActivityManager";
240    static final String TAG_MU = "ActivityManagerServiceMU";
241    static final boolean DEBUG = false;
242    static final boolean localLOGV = DEBUG;
243    static final boolean DEBUG_BACKUP = localLOGV || false;
244    static final boolean DEBUG_BROADCAST = localLOGV || false;
245    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
246    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_CLEANUP = localLOGV || false;
248    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
249    static final boolean DEBUG_FOCUS = false;
250    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
251    static final boolean DEBUG_MU = localLOGV || false;
252    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
253    static final boolean DEBUG_LRU = localLOGV || false;
254    static final boolean DEBUG_PAUSE = localLOGV || false;
255    static final boolean DEBUG_POWER = localLOGV || false;
256    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
257    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
258    static final boolean DEBUG_PROCESSES = localLOGV || false;
259    static final boolean DEBUG_PROVIDER = localLOGV || false;
260    static final boolean DEBUG_RESULTS = localLOGV || false;
261    static final boolean DEBUG_SERVICE = localLOGV || false;
262    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
263    static final boolean DEBUG_STACK = localLOGV || false;
264    static final boolean DEBUG_SWITCH = localLOGV || false;
265    static final boolean DEBUG_TASKS = localLOGV || false;
266    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
267    static final boolean DEBUG_TRANSITION = localLOGV || false;
268    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
269    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
270    static final boolean DEBUG_VISBILITY = localLOGV || false;
271    static final boolean DEBUG_PSS = localLOGV || false;
272    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
273    static final boolean DEBUG_RECENTS = localLOGV || false;
274    static final boolean VALIDATE_TOKENS = false;
275    static final boolean SHOW_ACTIVITY_START_TIME = true;
276
277    // Control over CPU and battery monitoring.
278    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
279    static final boolean MONITOR_CPU_USAGE = true;
280    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
281    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
282    static final boolean MONITOR_THREAD_CPU_USAGE = false;
283
284    // The flags that are set for all calls we make to the package manager.
285    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
286
287    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
288
289    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
290
291    // Maximum number recent bitmaps to keep in memory.
292    static final int MAX_RECENT_BITMAPS = 5;
293
294    // Amount of time after a call to stopAppSwitches() during which we will
295    // prevent further untrusted switches from happening.
296    static final long APP_SWITCH_DELAY_TIME = 5*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real.
300    static final int PROC_START_TIMEOUT = 10*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real, when the process was
304    // started with a wrapper for instrumentation (such as Valgrind) because it
305    // could take much longer than usual.
306    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
307
308    // How long to wait after going idle before forcing apps to GC.
309    static final int GC_TIMEOUT = 5*1000;
310
311    // The minimum amount of time between successive GC requests for a process.
312    static final int GC_MIN_INTERVAL = 60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process.
315    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process
318    // when the request is due to the memory state being lowered.
319    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
320
321    // The rate at which we check for apps using excessive power -- 15 mins.
322    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on wake locks to start killing things.
326    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on CPU usage to start killing things.
330    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // How long we allow a receiver to run before giving up on it.
333    static final int BROADCAST_FG_TIMEOUT = 10*1000;
334    static final int BROADCAST_BG_TIMEOUT = 60*1000;
335
336    // How long we wait until we timeout on key dispatching.
337    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
338
339    // How long we wait until we timeout on key dispatching during instrumentation.
340    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
341
342    // Amount of time we wait for observers to handle a user switch before
343    // giving up on them and unfreezing the screen.
344    static final int USER_SWITCH_TIMEOUT = 2*1000;
345
346    // Maximum number of users we allow to be running at a time.
347    static final int MAX_RUNNING_USERS = 3;
348
349    // How long to wait in getAssistContextExtras for the activity and foreground services
350    // to respond with the result.
351    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
352
353    // Maximum number of persisted Uri grants a package is allowed
354    static final int MAX_PERSISTED_URI_GRANTS = 128;
355
356    static final int MY_PID = Process.myPid();
357
358    static final String[] EMPTY_STRING_ARRAY = new String[0];
359
360    // How many bytes to write into the dropbox log before truncating
361    static final int DROPBOX_MAX_SIZE = 256 * 1024;
362
363    // Access modes for handleIncomingUser.
364    static final int ALLOW_NON_FULL = 0;
365    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
366    static final int ALLOW_FULL_ONLY = 2;
367
368    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
369
370    /** All system services */
371    SystemServiceManager mSystemServiceManager;
372
373    /** Run all ActivityStacks through this */
374    ActivityStackSupervisor mStackSupervisor;
375
376    public IntentFirewall mIntentFirewall;
377
378    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
379    // default actuion automatically.  Important for devices without direct input
380    // devices.
381    private boolean mShowDialogs = true;
382
383    BroadcastQueue mFgBroadcastQueue;
384    BroadcastQueue mBgBroadcastQueue;
385    // Convenient for easy iteration over the queues. Foreground is first
386    // so that dispatch of foreground broadcasts gets precedence.
387    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
388
389    BroadcastQueue broadcastQueueForIntent(Intent intent) {
390        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
391        if (DEBUG_BACKGROUND_BROADCAST) {
392            Slog.i(TAG, "Broadcast intent " + intent + " on "
393                    + (isFg ? "foreground" : "background")
394                    + " queue");
395        }
396        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
397    }
398
399    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
400        for (BroadcastQueue queue : mBroadcastQueues) {
401            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
402            if (r != null) {
403                return r;
404            }
405        }
406        return null;
407    }
408
409    /**
410     * Activity we have told the window manager to have key focus.
411     */
412    ActivityRecord mFocusedActivity = null;
413
414    /**
415     * List of intents that were used to start the most recent tasks.
416     */
417    ArrayList<TaskRecord> mRecentTasks;
418    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    public class PendingAssistExtras extends Binder implements Runnable {
436        public final ActivityRecord activity;
437        public final Bundle extras;
438        public final Intent intent;
439        public final String hint;
440        public final int userHandle;
441        public boolean haveResult = false;
442        public Bundle result = null;
443        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
444                String _hint, int _userHandle) {
445            activity = _activity;
446            extras = _extras;
447            intent = _intent;
448            hint = _hint;
449            userHandle = _userHandle;
450        }
451        @Override
452        public void run() {
453            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
454            synchronized (this) {
455                haveResult = true;
456                notifyAll();
457            }
458        }
459    }
460
461    final ArrayList<PendingAssistExtras> mPendingAssistExtras
462            = new ArrayList<PendingAssistExtras>();
463
464    /**
465     * Process management.
466     */
467    final ProcessList mProcessList = new ProcessList();
468
469    /**
470     * All of the applications we currently have running organized by name.
471     * The keys are strings of the application package name (as
472     * returned by the package manager), and the keys are ApplicationRecord
473     * objects.
474     */
475    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
476
477    /**
478     * Tracking long-term execution of processes to look for abuse and other
479     * bad app behavior.
480     */
481    final ProcessStatsService mProcessStats;
482
483    /**
484     * The currently running isolated processes.
485     */
486    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
487
488    /**
489     * Counter for assigning isolated process uids, to avoid frequently reusing the
490     * same ones.
491     */
492    int mNextIsolatedProcessUid = 0;
493
494    /**
495     * The currently running heavy-weight process, if any.
496     */
497    ProcessRecord mHeavyWeightProcess = null;
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Information about a process that is currently marked as bad.
506     */
507    static final class BadProcessInfo {
508        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
509            this.time = time;
510            this.shortMsg = shortMsg;
511            this.longMsg = longMsg;
512            this.stack = stack;
513        }
514
515        final long time;
516        final String shortMsg;
517        final String longMsg;
518        final String stack;
519    }
520
521    /**
522     * Set of applications that we consider to be bad, and will reject
523     * incoming broadcasts from (which the user has no control over).
524     * Processes are added to this set when they have crashed twice within
525     * a minimum amount of time; they are removed from it when they are
526     * later restarted (hopefully due to some user action).  The value is the
527     * time it was added to the list.
528     */
529    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
530
531    /**
532     * All of the processes we currently have running organized by pid.
533     * The keys are the pid running the application.
534     *
535     * <p>NOTE: This object is protected by its own lock, NOT the global
536     * activity manager lock!
537     */
538    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
539
540    /**
541     * All of the processes that have been forced to be foreground.  The key
542     * is the pid of the caller who requested it (we hold a death
543     * link on it).
544     */
545    abstract class ForegroundToken implements IBinder.DeathRecipient {
546        int pid;
547        IBinder token;
548    }
549    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
550
551    /**
552     * List of records for processes that someone had tried to start before the
553     * system was ready.  We don't start them at that point, but ensure they
554     * are started by the time booting is complete.
555     */
556    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of persistent applications that are in the process
560     * of being started.
561     */
562    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes that are being forcibly torn down.
566     */
567    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * List of running applications, sorted by recent usage.
571     * The first entry in the list is the least recently used.
572     */
573    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Where in mLruProcesses that the processes hosting activities start.
577     */
578    int mLruProcessActivityStart = 0;
579
580    /**
581     * Where in mLruProcesses that the processes hosting services start.
582     * This is after (lower index) than mLruProcessesActivityStart.
583     */
584    int mLruProcessServiceStart = 0;
585
586    /**
587     * List of processes that should gc as soon as things are idle.
588     */
589    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
590
591    /**
592     * Processes we want to collect PSS data from.
593     */
594    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Last time we requested PSS data of all processes.
598     */
599    long mLastFullPssTime = SystemClock.uptimeMillis();
600
601    /**
602     * If set, the next time we collect PSS data we should do a full collection
603     * with data from native processes and the kernel.
604     */
605    boolean mFullPssPending = false;
606
607    /**
608     * This is the process holding what we currently consider to be
609     * the "home" activity.
610     */
611    ProcessRecord mHomeProcess;
612
613    /**
614     * This is the process holding the activity the user last visited that
615     * is in a different process from the one they are currently in.
616     */
617    ProcessRecord mPreviousProcess;
618
619    /**
620     * The time at which the previous process was last visible.
621     */
622    long mPreviousProcessVisibleTime;
623
624    /**
625     * Which uses have been started, so are allowed to run code.
626     */
627    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
628
629    /**
630     * LRU list of history of current users.  Most recently current is at the end.
631     */
632    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
633
634    /**
635     * Constant array of the users that are currently started.
636     */
637    int[] mStartedUserArray = new int[] { 0 };
638
639    /**
640     * Registered observers of the user switching mechanics.
641     */
642    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
643            = new RemoteCallbackList<IUserSwitchObserver>();
644
645    /**
646     * Currently active user switch.
647     */
648    Object mCurUserSwitchCallback;
649
650    /**
651     * Packages that the user has asked to have run in screen size
652     * compatibility mode instead of filling the screen.
653     */
654    final CompatModePackages mCompatModePackages;
655
656    /**
657     * Set of IntentSenderRecord objects that are currently active.
658     */
659    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
660            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
661
662    /**
663     * Fingerprints (hashCode()) of stack traces that we've
664     * already logged DropBox entries for.  Guarded by itself.  If
665     * something (rogue user app) forces this over
666     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
667     */
668    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
669    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
670
671    /**
672     * Strict Mode background batched logging state.
673     *
674     * The string buffer is guarded by itself, and its lock is also
675     * used to determine if another batched write is already
676     * in-flight.
677     */
678    private final StringBuilder mStrictModeBuffer = new StringBuilder();
679
680    /**
681     * Keeps track of all IIntentReceivers that have been registered for
682     * broadcasts.  Hash keys are the receiver IBinder, hash value is
683     * a ReceiverList.
684     */
685    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
686            new HashMap<IBinder, ReceiverList>();
687
688    /**
689     * Resolver for broadcast intents to registered receivers.
690     * Holds BroadcastFilter (subclass of IntentFilter).
691     */
692    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
693            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
694        @Override
695        protected boolean allowFilterResult(
696                BroadcastFilter filter, List<BroadcastFilter> dest) {
697            IBinder target = filter.receiverList.receiver.asBinder();
698            for (int i=dest.size()-1; i>=0; i--) {
699                if (dest.get(i).receiverList.receiver.asBinder() == target) {
700                    return false;
701                }
702            }
703            return true;
704        }
705
706        @Override
707        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
708            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
709                    || userId == filter.owningUserId) {
710                return super.newResult(filter, match, userId);
711            }
712            return null;
713        }
714
715        @Override
716        protected BroadcastFilter[] newArray(int size) {
717            return new BroadcastFilter[size];
718        }
719
720        @Override
721        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
722            return packageName.equals(filter.packageName);
723        }
724    };
725
726    /**
727     * State of all active sticky broadcasts per user.  Keys are the action of the
728     * sticky Intent, values are an ArrayList of all broadcasted intents with
729     * that action (which should usually be one).  The SparseArray is keyed
730     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
731     * for stickies that are sent to all users.
732     */
733    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
734            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
735
736    final ActiveServices mServices;
737
738    /**
739     * Backup/restore process management
740     */
741    String mBackupAppName = null;
742    BackupRecord mBackupTarget = null;
743
744    final ProviderMap mProviderMap;
745
746    /**
747     * List of content providers who have clients waiting for them.  The
748     * application is currently being launched and the provider will be
749     * removed from this list once it is published.
750     */
751    final ArrayList<ContentProviderRecord> mLaunchingProviders
752            = new ArrayList<ContentProviderRecord>();
753
754    /**
755     * File storing persisted {@link #mGrantedUriPermissions}.
756     */
757    private final AtomicFile mGrantFile;
758
759    /** XML constants used in {@link #mGrantFile} */
760    private static final String TAG_URI_GRANTS = "uri-grants";
761    private static final String TAG_URI_GRANT = "uri-grant";
762    private static final String ATTR_USER_HANDLE = "userHandle";
763    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
764    private static final String ATTR_TARGET_USER_ID = "targetUserId";
765    private static final String ATTR_SOURCE_PKG = "sourcePkg";
766    private static final String ATTR_TARGET_PKG = "targetPkg";
767    private static final String ATTR_URI = "uri";
768    private static final String ATTR_MODE_FLAGS = "modeFlags";
769    private static final String ATTR_CREATED_TIME = "createdTime";
770    private static final String ATTR_PREFIX = "prefix";
771
772    /**
773     * Global set of specific {@link Uri} permissions that have been granted.
774     * This optimized lookup structure maps from {@link UriPermission#targetUid}
775     * to {@link UriPermission#uri} to {@link UriPermission}.
776     */
777    @GuardedBy("this")
778    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
779            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
780
781    public static class GrantUri {
782        public final int sourceUserId;
783        public final Uri uri;
784        public boolean prefix;
785
786        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
787            this.sourceUserId = sourceUserId;
788            this.uri = uri;
789            this.prefix = prefix;
790        }
791
792        @Override
793        public int hashCode() {
794            return toString().hashCode();
795        }
796
797        @Override
798        public boolean equals(Object o) {
799            if (o instanceof GrantUri) {
800                GrantUri other = (GrantUri) o;
801                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
802                        && prefix == other.prefix;
803            }
804            return false;
805        }
806
807        @Override
808        public String toString() {
809            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
810            if (prefix) result += " [prefix]";
811            return result;
812        }
813
814        public String toSafeString() {
815            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
816            if (prefix) result += " [prefix]";
817            return result;
818        }
819
820        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
821            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
822                    ContentProvider.getUriWithoutUserId(uri), false);
823        }
824    }
825
826    CoreSettingsObserver mCoreSettingsObserver;
827
828    /**
829     * Thread-local storage used to carry caller permissions over through
830     * indirect content-provider access.
831     */
832    private class Identity {
833        public int pid;
834        public int uid;
835
836        Identity(int _pid, int _uid) {
837            pid = _pid;
838            uid = _uid;
839        }
840    }
841
842    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
843
844    /**
845     * All information we have collected about the runtime performance of
846     * any user id that can impact battery performance.
847     */
848    final BatteryStatsService mBatteryStatsService;
849
850    /**
851     * Information about component usage
852     */
853    UsageStatsManagerInternal mUsageStatsService;
854
855    /**
856     * Information about and control over application operations
857     */
858    final AppOpsService mAppOpsService;
859
860    /**
861     * Save recent tasks information across reboots.
862     */
863    final TaskPersister mTaskPersister;
864
865    /**
866     * Current configuration information.  HistoryRecord objects are given
867     * a reference to this object to indicate which configuration they are
868     * currently running in, so this object must be kept immutable.
869     */
870    Configuration mConfiguration = new Configuration();
871
872    /**
873     * Current sequencing integer of the configuration, for skipping old
874     * configurations.
875     */
876    int mConfigurationSeq = 0;
877
878    /**
879     * Hardware-reported OpenGLES version.
880     */
881    final int GL_ES_VERSION;
882
883    /**
884     * List of initialization arguments to pass to all processes when binding applications to them.
885     * For example, references to the commonly used services.
886     */
887    HashMap<String, IBinder> mAppBindArgs;
888
889    /**
890     * Temporary to avoid allocations.  Protected by main lock.
891     */
892    final StringBuilder mStringBuilder = new StringBuilder(256);
893
894    /**
895     * Used to control how we initialize the service.
896     */
897    ComponentName mTopComponent;
898    String mTopAction = Intent.ACTION_MAIN;
899    String mTopData;
900    boolean mProcessesReady = false;
901    boolean mSystemReady = false;
902    boolean mBooting = false;
903    boolean mCallFinishBooting = false;
904    boolean mBootAnimationComplete = false;
905    boolean mWaitingUpdate = false;
906    boolean mDidUpdate = false;
907    boolean mOnBattery = false;
908    boolean mLaunchWarningShown = false;
909
910    Context mContext;
911
912    int mFactoryTest;
913
914    boolean mCheckedForSetup;
915
916    /**
917     * The time at which we will allow normal application switches again,
918     * after a call to {@link #stopAppSwitches()}.
919     */
920    long mAppSwitchesAllowedTime;
921
922    /**
923     * This is set to true after the first switch after mAppSwitchesAllowedTime
924     * is set; any switches after that will clear the time.
925     */
926    boolean mDidAppSwitch;
927
928    /**
929     * Last time (in realtime) at which we checked for power usage.
930     */
931    long mLastPowerCheckRealtime;
932
933    /**
934     * Last time (in uptime) at which we checked for power usage.
935     */
936    long mLastPowerCheckUptime;
937
938    /**
939     * Set while we are wanting to sleep, to prevent any
940     * activities from being started/resumed.
941     */
942    private boolean mSleeping = false;
943
944    /**
945     * Set while we are running a voice interaction.  This overrides
946     * sleeping while it is active.
947     */
948    private boolean mRunningVoice = false;
949
950    /**
951     * State of external calls telling us if the device is asleep.
952     */
953    private boolean mWentToSleep = false;
954
955    /**
956     * State of external call telling us if the lock screen is shown.
957     */
958    private boolean mLockScreenShown = false;
959
960    /**
961     * Set if we are shutting down the system, similar to sleeping.
962     */
963    boolean mShuttingDown = false;
964
965    /**
966     * Current sequence id for oom_adj computation traversal.
967     */
968    int mAdjSeq = 0;
969
970    /**
971     * Current sequence id for process LRU updating.
972     */
973    int mLruSeq = 0;
974
975    /**
976     * Keep track of the non-cached/empty process we last found, to help
977     * determine how to distribute cached/empty processes next time.
978     */
979    int mNumNonCachedProcs = 0;
980
981    /**
982     * Keep track of the number of cached hidden procs, to balance oom adj
983     * distribution between those and empty procs.
984     */
985    int mNumCachedHiddenProcs = 0;
986
987    /**
988     * Keep track of the number of service processes we last found, to
989     * determine on the next iteration which should be B services.
990     */
991    int mNumServiceProcs = 0;
992    int mNewNumAServiceProcs = 0;
993    int mNewNumServiceProcs = 0;
994
995    /**
996     * Allow the current computed overall memory level of the system to go down?
997     * This is set to false when we are killing processes for reasons other than
998     * memory management, so that the now smaller process list will not be taken as
999     * an indication that memory is tighter.
1000     */
1001    boolean mAllowLowerMemLevel = false;
1002
1003    /**
1004     * The last computed memory level, for holding when we are in a state that
1005     * processes are going away for other reasons.
1006     */
1007    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1008
1009    /**
1010     * The last total number of process we have, to determine if changes actually look
1011     * like a shrinking number of process due to lower RAM.
1012     */
1013    int mLastNumProcesses;
1014
1015    /**
1016     * The uptime of the last time we performed idle maintenance.
1017     */
1018    long mLastIdleTime = SystemClock.uptimeMillis();
1019
1020    /**
1021     * Total time spent with RAM that has been added in the past since the last idle time.
1022     */
1023    long mLowRamTimeSinceLastIdle = 0;
1024
1025    /**
1026     * If RAM is currently low, when that horrible situation started.
1027     */
1028    long mLowRamStartTime = 0;
1029
1030    /**
1031     * For reporting to battery stats the current top application.
1032     */
1033    private String mCurResumedPackage = null;
1034    private int mCurResumedUid = -1;
1035
1036    /**
1037     * For reporting to battery stats the apps currently running foreground
1038     * service.  The ProcessMap is package/uid tuples; each of these contain
1039     * an array of the currently foreground processes.
1040     */
1041    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1042            = new ProcessMap<ArrayList<ProcessRecord>>();
1043
1044    /**
1045     * This is set if we had to do a delayed dexopt of an app before launching
1046     * it, to increase the ANR timeouts in that case.
1047     */
1048    boolean mDidDexOpt;
1049
1050    /**
1051     * Set if the systemServer made a call to enterSafeMode.
1052     */
1053    boolean mSafeMode;
1054
1055    String mDebugApp = null;
1056    boolean mWaitForDebugger = false;
1057    boolean mDebugTransient = false;
1058    String mOrigDebugApp = null;
1059    boolean mOrigWaitForDebugger = false;
1060    boolean mAlwaysFinishActivities = false;
1061    IActivityController mController = null;
1062    String mProfileApp = null;
1063    ProcessRecord mProfileProc = null;
1064    String mProfileFile;
1065    ParcelFileDescriptor mProfileFd;
1066    int mSamplingInterval = 0;
1067    boolean mAutoStopProfiler = false;
1068    int mProfileType = 0;
1069    String mOpenGlTraceApp = null;
1070
1071    static class ProcessChangeItem {
1072        static final int CHANGE_ACTIVITIES = 1<<0;
1073        static final int CHANGE_PROCESS_STATE = 1<<1;
1074        int changes;
1075        int uid;
1076        int pid;
1077        int processState;
1078        boolean foregroundActivities;
1079    }
1080
1081    final RemoteCallbackList<IProcessObserver> mProcessObservers
1082            = new RemoteCallbackList<IProcessObserver>();
1083    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1084
1085    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1086            = new ArrayList<ProcessChangeItem>();
1087    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1088            = new ArrayList<ProcessChangeItem>();
1089
1090    /**
1091     * Runtime CPU use collection thread.  This object's lock is used to
1092     * perform synchronization with the thread (notifying it to run).
1093     */
1094    final Thread mProcessCpuThread;
1095
1096    /**
1097     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1098     * Must acquire this object's lock when accessing it.
1099     * NOTE: this lock will be held while doing long operations (trawling
1100     * through all processes in /proc), so it should never be acquired by
1101     * any critical paths such as when holding the main activity manager lock.
1102     */
1103    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1104            MONITOR_THREAD_CPU_USAGE);
1105    final AtomicLong mLastCpuTime = new AtomicLong(0);
1106    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1107
1108    long mLastWriteTime = 0;
1109
1110    /**
1111     * Used to retain an update lock when the foreground activity is in
1112     * immersive mode.
1113     */
1114    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1115
1116    /**
1117     * Set to true after the system has finished booting.
1118     */
1119    boolean mBooted = false;
1120
1121    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1122    int mProcessLimitOverride = -1;
1123
1124    WindowManagerService mWindowManager;
1125
1126    final ActivityThread mSystemThread;
1127
1128    // Holds the current foreground user's id
1129    int mCurrentUserId = 0;
1130    // Holds the target user's id during a user switch
1131    int mTargetUserId = UserHandle.USER_NULL;
1132    // If there are multiple profiles for the current user, their ids are here
1133    // Currently only the primary user can have managed profiles
1134    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1135
1136    /**
1137     * Mapping from each known user ID to the profile group ID it is associated with.
1138     */
1139    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1140
1141    private UserManagerService mUserManager;
1142
1143    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1144        final ProcessRecord mApp;
1145        final int mPid;
1146        final IApplicationThread mAppThread;
1147
1148        AppDeathRecipient(ProcessRecord app, int pid,
1149                IApplicationThread thread) {
1150            if (localLOGV) Slog.v(
1151                TAG, "New death recipient " + this
1152                + " for thread " + thread.asBinder());
1153            mApp = app;
1154            mPid = pid;
1155            mAppThread = thread;
1156        }
1157
1158        @Override
1159        public void binderDied() {
1160            if (localLOGV) Slog.v(
1161                TAG, "Death received in " + this
1162                + " for thread " + mAppThread.asBinder());
1163            synchronized(ActivityManagerService.this) {
1164                appDiedLocked(mApp, mPid, mAppThread);
1165            }
1166        }
1167    }
1168
1169    static final int SHOW_ERROR_MSG = 1;
1170    static final int SHOW_NOT_RESPONDING_MSG = 2;
1171    static final int SHOW_FACTORY_ERROR_MSG = 3;
1172    static final int UPDATE_CONFIGURATION_MSG = 4;
1173    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1174    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1175    static final int SERVICE_TIMEOUT_MSG = 12;
1176    static final int UPDATE_TIME_ZONE = 13;
1177    static final int SHOW_UID_ERROR_MSG = 14;
1178    static final int IM_FEELING_LUCKY_MSG = 15;
1179    static final int PROC_START_TIMEOUT_MSG = 20;
1180    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1181    static final int KILL_APPLICATION_MSG = 22;
1182    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1183    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1184    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1185    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1186    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1187    static final int CLEAR_DNS_CACHE_MSG = 28;
1188    static final int UPDATE_HTTP_PROXY_MSG = 29;
1189    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1190    static final int DISPATCH_PROCESSES_CHANGED = 31;
1191    static final int DISPATCH_PROCESS_DIED = 32;
1192    static final int REPORT_MEM_USAGE_MSG = 33;
1193    static final int REPORT_USER_SWITCH_MSG = 34;
1194    static final int CONTINUE_USER_SWITCH_MSG = 35;
1195    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1196    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1197    static final int PERSIST_URI_GRANTS_MSG = 38;
1198    static final int REQUEST_ALL_PSS_MSG = 39;
1199    static final int START_PROFILES_MSG = 40;
1200    static final int UPDATE_TIME = 41;
1201    static final int SYSTEM_USER_START_MSG = 42;
1202    static final int SYSTEM_USER_CURRENT_MSG = 43;
1203    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1204    static final int FINISH_BOOTING_MSG = 45;
1205    static final int START_USER_SWITCH_MSG = 46;
1206    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1207
1208    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1209    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1210    static final int FIRST_COMPAT_MODE_MSG = 300;
1211    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1212
1213    AlertDialog mUidAlert;
1214    CompatModeDialog mCompatModeDialog;
1215    long mLastMemUsageReportTime = 0;
1216
1217    private LockToAppRequestDialog mLockToAppRequest;
1218
1219    /**
1220     * Flag whether the current user is a "monkey", i.e. whether
1221     * the UI is driven by a UI automation tool.
1222     */
1223    private boolean mUserIsMonkey;
1224
1225    /** Flag whether the device has a Recents UI */
1226    boolean mHasRecents;
1227
1228    /** The dimensions of the thumbnails in the Recents UI. */
1229    int mThumbnailWidth;
1230    int mThumbnailHeight;
1231
1232    final ServiceThread mHandlerThread;
1233    final MainHandler mHandler;
1234
1235    final class MainHandler extends Handler {
1236        public MainHandler(Looper looper) {
1237            super(looper, null, true);
1238        }
1239
1240        @Override
1241        public void handleMessage(Message msg) {
1242            switch (msg.what) {
1243            case SHOW_ERROR_MSG: {
1244                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1246                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1247                synchronized (ActivityManagerService.this) {
1248                    ProcessRecord proc = (ProcessRecord)data.get("app");
1249                    AppErrorResult res = (AppErrorResult) data.get("result");
1250                    if (proc != null && proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has crash dialog: " + proc);
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                        return;
1256                    }
1257                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1258                            >= Process.FIRST_APPLICATION_UID
1259                            && proc.pid != MY_PID);
1260                    for (int userId : mCurrentProfileIds) {
1261                        isBackground &= (proc.userId != userId);
1262                    }
1263                    if (isBackground && !showBackground) {
1264                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1265                        if (res != null) {
1266                            res.set(0);
1267                        }
1268                        return;
1269                    }
1270                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1271                        Dialog d = new AppErrorDialog(mContext,
1272                                ActivityManagerService.this, res, proc);
1273                        d.show();
1274                        proc.crashDialog = d;
1275                    } else {
1276                        // The device is asleep, so just pretend that the user
1277                        // saw a crash dialog and hit "force quit".
1278                        if (res != null) {
1279                            res.set(0);
1280                        }
1281                    }
1282                }
1283
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_NOT_RESPONDING_MSG: {
1287                synchronized (ActivityManagerService.this) {
1288                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1289                    ProcessRecord proc = (ProcessRecord)data.get("app");
1290                    if (proc != null && proc.anrDialog != null) {
1291                        Slog.e(TAG, "App already has anr dialog: " + proc);
1292                        return;
1293                    }
1294
1295                    Intent intent = new Intent("android.intent.action.ANR");
1296                    if (!mProcessesReady) {
1297                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1298                                | Intent.FLAG_RECEIVER_FOREGROUND);
1299                    }
1300                    broadcastIntentLocked(null, null, intent,
1301                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1302                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1303
1304                    if (mShowDialogs) {
1305                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1306                                mContext, proc, (ActivityRecord)data.get("activity"),
1307                                msg.arg1 != 0);
1308                        d.show();
1309                        proc.anrDialog = d;
1310                    } else {
1311                        // Just kill the app if there is no dialog to be shown.
1312                        killAppAtUsersRequest(proc, null);
1313                    }
1314                }
1315
1316                ensureBootCompleted();
1317            } break;
1318            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1319                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                synchronized (ActivityManagerService.this) {
1321                    ProcessRecord proc = (ProcessRecord) data.get("app");
1322                    if (proc == null) {
1323                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1324                        break;
1325                    }
1326                    if (proc.crashDialog != null) {
1327                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1328                        return;
1329                    }
1330                    AppErrorResult res = (AppErrorResult) data.get("result");
1331                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1332                        Dialog d = new StrictModeViolationDialog(mContext,
1333                                ActivityManagerService.this, res, proc);
1334                        d.show();
1335                        proc.crashDialog = d;
1336                    } else {
1337                        // The device is asleep, so just pretend that the user
1338                        // saw a crash dialog and hit "force quit".
1339                        res.set(0);
1340                    }
1341                }
1342                ensureBootCompleted();
1343            } break;
1344            case SHOW_FACTORY_ERROR_MSG: {
1345                Dialog d = new FactoryErrorDialog(
1346                    mContext, msg.getData().getCharSequence("msg"));
1347                d.show();
1348                ensureBootCompleted();
1349            } break;
1350            case UPDATE_CONFIGURATION_MSG: {
1351                final ContentResolver resolver = mContext.getContentResolver();
1352                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1353            } break;
1354            case GC_BACKGROUND_PROCESSES_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    performAppGcsIfAppropriateLocked();
1357                }
1358            } break;
1359            case WAIT_FOR_DEBUGGER_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    ProcessRecord app = (ProcessRecord)msg.obj;
1362                    if (msg.arg1 != 0) {
1363                        if (!app.waitedForDebugger) {
1364                            Dialog d = new AppWaitingForDebuggerDialog(
1365                                    ActivityManagerService.this,
1366                                    mContext, app);
1367                            app.waitDialog = d;
1368                            app.waitedForDebugger = true;
1369                            d.show();
1370                        }
1371                    } else {
1372                        if (app.waitDialog != null) {
1373                            app.waitDialog.dismiss();
1374                            app.waitDialog = null;
1375                        }
1376                    }
1377                }
1378            } break;
1379            case SERVICE_TIMEOUT_MSG: {
1380                if (mDidDexOpt) {
1381                    mDidDexOpt = false;
1382                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1383                    nmsg.obj = msg.obj;
1384                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1385                    return;
1386                }
1387                mServices.serviceTimeout((ProcessRecord)msg.obj);
1388            } break;
1389            case UPDATE_TIME_ZONE: {
1390                synchronized (ActivityManagerService.this) {
1391                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1392                        ProcessRecord r = mLruProcesses.get(i);
1393                        if (r.thread != null) {
1394                            try {
1395                                r.thread.updateTimeZone();
1396                            } catch (RemoteException ex) {
1397                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1398                            }
1399                        }
1400                    }
1401                }
1402            } break;
1403            case CLEAR_DNS_CACHE_MSG: {
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.clearDnsCache();
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1412                            }
1413                        }
1414                    }
1415                }
1416            } break;
1417            case UPDATE_HTTP_PROXY_MSG: {
1418                ProxyInfo proxy = (ProxyInfo)msg.obj;
1419                String host = "";
1420                String port = "";
1421                String exclList = "";
1422                Uri pacFileUrl = Uri.EMPTY;
1423                if (proxy != null) {
1424                    host = proxy.getHost();
1425                    port = Integer.toString(proxy.getPort());
1426                    exclList = proxy.getExclusionListAsString();
1427                    pacFileUrl = proxy.getPacFileUrl();
1428                }
1429                synchronized (ActivityManagerService.this) {
1430                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1431                        ProcessRecord r = mLruProcesses.get(i);
1432                        if (r.thread != null) {
1433                            try {
1434                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1435                            } catch (RemoteException ex) {
1436                                Slog.w(TAG, "Failed to update http proxy for: " +
1437                                        r.info.processName);
1438                            }
1439                        }
1440                    }
1441                }
1442            } break;
1443            case SHOW_UID_ERROR_MSG: {
1444                String title = "System UIDs Inconsistent";
1445                String text = "UIDs on the system are inconsistent, you need to wipe your"
1446                        + " data partition or your device will be unstable.";
1447                Log.e(TAG, title + ": " + text);
1448                if (mShowDialogs) {
1449                    // XXX This is a temporary dialog, no need to localize.
1450                    AlertDialog d = new BaseErrorDialog(mContext);
1451                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1452                    d.setCancelable(false);
1453                    d.setTitle(title);
1454                    d.setMessage(text);
1455                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1456                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1457                    mUidAlert = d;
1458                    d.show();
1459                }
1460            } break;
1461            case IM_FEELING_LUCKY_MSG: {
1462                if (mUidAlert != null) {
1463                    mUidAlert.dismiss();
1464                    mUidAlert = null;
1465                }
1466            } break;
1467            case PROC_START_TIMEOUT_MSG: {
1468                if (mDidDexOpt) {
1469                    mDidDexOpt = false;
1470                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1471                    nmsg.obj = msg.obj;
1472                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1473                    return;
1474                }
1475                ProcessRecord app = (ProcessRecord)msg.obj;
1476                synchronized (ActivityManagerService.this) {
1477                    processStartTimedOutLocked(app);
1478                }
1479            } break;
1480            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1483                }
1484            } break;
1485            case KILL_APPLICATION_MSG: {
1486                synchronized (ActivityManagerService.this) {
1487                    int appid = msg.arg1;
1488                    boolean restart = (msg.arg2 == 1);
1489                    Bundle bundle = (Bundle)msg.obj;
1490                    String pkg = bundle.getString("pkg");
1491                    String reason = bundle.getString("reason");
1492                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1493                            false, UserHandle.USER_ALL, reason);
1494                }
1495            } break;
1496            case FINALIZE_PENDING_INTENT_MSG: {
1497                ((PendingIntentRecord)msg.obj).completeFinalize();
1498            } break;
1499            case POST_HEAVY_NOTIFICATION_MSG: {
1500                INotificationManager inm = NotificationManager.getService();
1501                if (inm == null) {
1502                    return;
1503                }
1504
1505                ActivityRecord root = (ActivityRecord)msg.obj;
1506                ProcessRecord process = root.app;
1507                if (process == null) {
1508                    return;
1509                }
1510
1511                try {
1512                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1513                    String text = mContext.getString(R.string.heavy_weight_notification,
1514                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1515                    Notification notification = new Notification();
1516                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1517                    notification.when = 0;
1518                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1519                    notification.tickerText = text;
1520                    notification.defaults = 0; // please be quiet
1521                    notification.sound = null;
1522                    notification.vibrate = null;
1523                    notification.color = mContext.getResources().getColor(
1524                            com.android.internal.R.color.system_notification_accent_color);
1525                    notification.setLatestEventInfo(context, text,
1526                            mContext.getText(R.string.heavy_weight_notification_detail),
1527                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1528                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1529                                    new UserHandle(root.userId)));
1530
1531                    try {
1532                        int[] outId = new int[1];
1533                        inm.enqueueNotificationWithTag("android", "android", null,
1534                                R.string.heavy_weight_notification,
1535                                notification, outId, root.userId);
1536                    } catch (RuntimeException e) {
1537                        Slog.w(ActivityManagerService.TAG,
1538                                "Error showing notification for heavy-weight app", e);
1539                    } catch (RemoteException e) {
1540                    }
1541                } catch (NameNotFoundException e) {
1542                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1543                }
1544            } break;
1545            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1546                INotificationManager inm = NotificationManager.getService();
1547                if (inm == null) {
1548                    return;
1549                }
1550                try {
1551                    inm.cancelNotificationWithTag("android", null,
1552                            R.string.heavy_weight_notification,  msg.arg1);
1553                } catch (RuntimeException e) {
1554                    Slog.w(ActivityManagerService.TAG,
1555                            "Error canceling notification for service", e);
1556                } catch (RemoteException e) {
1557                }
1558            } break;
1559            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    checkExcessivePowerUsageLocked(true);
1562                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1563                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1564                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1565                }
1566            } break;
1567            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1568                synchronized (ActivityManagerService.this) {
1569                    ActivityRecord ar = (ActivityRecord)msg.obj;
1570                    if (mCompatModeDialog != null) {
1571                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1572                                ar.info.applicationInfo.packageName)) {
1573                            return;
1574                        }
1575                        mCompatModeDialog.dismiss();
1576                        mCompatModeDialog = null;
1577                    }
1578                    if (ar != null && false) {
1579                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1580                                ar.packageName)) {
1581                            int mode = mCompatModePackages.computeCompatModeLocked(
1582                                    ar.info.applicationInfo);
1583                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1584                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1585                                mCompatModeDialog = new CompatModeDialog(
1586                                        ActivityManagerService.this, mContext,
1587                                        ar.info.applicationInfo);
1588                                mCompatModeDialog.show();
1589                            }
1590                        }
1591                    }
1592                }
1593                break;
1594            }
1595            case DISPATCH_PROCESSES_CHANGED: {
1596                dispatchProcessesChanged();
1597                break;
1598            }
1599            case DISPATCH_PROCESS_DIED: {
1600                final int pid = msg.arg1;
1601                final int uid = msg.arg2;
1602                dispatchProcessDied(pid, uid);
1603                break;
1604            }
1605            case REPORT_MEM_USAGE_MSG: {
1606                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1607                Thread thread = new Thread() {
1608                    @Override public void run() {
1609                        reportMemUsage(memInfos);
1610                    }
1611                };
1612                thread.start();
1613                break;
1614            }
1615            case START_USER_SWITCH_MSG: {
1616                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1617                break;
1618            }
1619            case REPORT_USER_SWITCH_MSG: {
1620                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1621                break;
1622            }
1623            case CONTINUE_USER_SWITCH_MSG: {
1624                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1625                break;
1626            }
1627            case USER_SWITCH_TIMEOUT_MSG: {
1628                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1629                break;
1630            }
1631            case IMMERSIVE_MODE_LOCK_MSG: {
1632                final boolean nextState = (msg.arg1 != 0);
1633                if (mUpdateLock.isHeld() != nextState) {
1634                    if (DEBUG_IMMERSIVE) {
1635                        final ActivityRecord r = (ActivityRecord) msg.obj;
1636                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1637                    }
1638                    if (nextState) {
1639                        mUpdateLock.acquire();
1640                    } else {
1641                        mUpdateLock.release();
1642                    }
1643                }
1644                break;
1645            }
1646            case PERSIST_URI_GRANTS_MSG: {
1647                writeGrantedUriPermissions();
1648                break;
1649            }
1650            case REQUEST_ALL_PSS_MSG: {
1651                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1652                break;
1653            }
1654            case START_PROFILES_MSG: {
1655                synchronized (ActivityManagerService.this) {
1656                    startProfilesLocked();
1657                }
1658                break;
1659            }
1660            case UPDATE_TIME: {
1661                synchronized (ActivityManagerService.this) {
1662                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1663                        ProcessRecord r = mLruProcesses.get(i);
1664                        if (r.thread != null) {
1665                            try {
1666                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1667                            } catch (RemoteException ex) {
1668                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1669                            }
1670                        }
1671                    }
1672                }
1673                break;
1674            }
1675            case SYSTEM_USER_START_MSG: {
1676                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1677                        Integer.toString(msg.arg1), msg.arg1);
1678                mSystemServiceManager.startUser(msg.arg1);
1679                break;
1680            }
1681            case SYSTEM_USER_CURRENT_MSG: {
1682                mBatteryStatsService.noteEvent(
1683                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1684                        Integer.toString(msg.arg2), msg.arg2);
1685                mBatteryStatsService.noteEvent(
1686                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1687                        Integer.toString(msg.arg1), msg.arg1);
1688                mSystemServiceManager.switchUser(msg.arg1);
1689                mLockToAppRequest.clearPrompt();
1690                break;
1691            }
1692            case ENTER_ANIMATION_COMPLETE_MSG: {
1693                synchronized (ActivityManagerService.this) {
1694                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1695                    if (r != null && r.app != null && r.app.thread != null) {
1696                        try {
1697                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1698                        } catch (RemoteException e) {
1699                        }
1700                    }
1701                }
1702                break;
1703            }
1704            case FINISH_BOOTING_MSG: {
1705                if (msg.arg1 != 0) {
1706                    finishBooting();
1707                }
1708                if (msg.arg2 != 0) {
1709                    enableScreenAfterBoot();
1710                }
1711                break;
1712            }
1713            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1714                try {
1715                    Locale l = (Locale) msg.obj;
1716                    IBinder service = ServiceManager.getService("mount");
1717                    IMountService mountService = IMountService.Stub.asInterface(service);
1718                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1719                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1720                } catch (RemoteException e) {
1721                    Log.e(TAG, "Error storing locale for decryption UI", e);
1722                }
1723                break;
1724            }
1725            }
1726        }
1727    };
1728
1729    static final int COLLECT_PSS_BG_MSG = 1;
1730
1731    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1732        @Override
1733        public void handleMessage(Message msg) {
1734            switch (msg.what) {
1735            case COLLECT_PSS_BG_MSG: {
1736                long start = SystemClock.uptimeMillis();
1737                MemInfoReader memInfo = null;
1738                synchronized (ActivityManagerService.this) {
1739                    if (mFullPssPending) {
1740                        mFullPssPending = false;
1741                        memInfo = new MemInfoReader();
1742                    }
1743                }
1744                if (memInfo != null) {
1745                    updateCpuStatsNow();
1746                    long nativeTotalPss = 0;
1747                    synchronized (mProcessCpuTracker) {
1748                        final int N = mProcessCpuTracker.countStats();
1749                        for (int j=0; j<N; j++) {
1750                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1751                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1752                                // This is definitely an application process; skip it.
1753                                continue;
1754                            }
1755                            synchronized (mPidsSelfLocked) {
1756                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1757                                    // This is one of our own processes; skip it.
1758                                    continue;
1759                                }
1760                            }
1761                            nativeTotalPss += Debug.getPss(st.pid, null);
1762                        }
1763                    }
1764                    memInfo.readMemInfo();
1765                    synchronized (ActivityManagerService.this) {
1766                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1767                                + (SystemClock.uptimeMillis()-start) + "ms");
1768                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1769                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1770                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1771                    }
1772                }
1773
1774                int i=0, num=0;
1775                long[] tmp = new long[1];
1776                do {
1777                    ProcessRecord proc;
1778                    int procState;
1779                    int pid;
1780                    synchronized (ActivityManagerService.this) {
1781                        if (i >= mPendingPssProcesses.size()) {
1782                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1783                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1784                            mPendingPssProcesses.clear();
1785                            return;
1786                        }
1787                        proc = mPendingPssProcesses.get(i);
1788                        procState = proc.pssProcState;
1789                        if (proc.thread != null && procState == proc.setProcState) {
1790                            pid = proc.pid;
1791                        } else {
1792                            proc = null;
1793                            pid = 0;
1794                        }
1795                        i++;
1796                    }
1797                    if (proc != null) {
1798                        long pss = Debug.getPss(pid, tmp);
1799                        synchronized (ActivityManagerService.this) {
1800                            if (proc.thread != null && proc.setProcState == procState
1801                                    && proc.pid == pid) {
1802                                num++;
1803                                proc.lastPssTime = SystemClock.uptimeMillis();
1804                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1805                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1806                                        + ": " + pss + " lastPss=" + proc.lastPss
1807                                        + " state=" + ProcessList.makeProcStateString(procState));
1808                                if (proc.initialIdlePss == 0) {
1809                                    proc.initialIdlePss = pss;
1810                                }
1811                                proc.lastPss = pss;
1812                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1813                                    proc.lastCachedPss = pss;
1814                                }
1815                            }
1816                        }
1817                    }
1818                } while (true);
1819            }
1820            }
1821        }
1822    };
1823
1824    /**
1825     * Monitor for package changes and update our internal state.
1826     */
1827    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1828        @Override
1829        public void onPackageRemoved(String packageName, int uid) {
1830            // Remove all tasks with activities in the specified package from the list of recent tasks
1831            final int eventUserId = getChangingUserId();
1832            synchronized (ActivityManagerService.this) {
1833                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1834                    TaskRecord tr = mRecentTasks.get(i);
1835                    if (tr.userId != eventUserId) continue;
1836
1837                    ComponentName cn = tr.intent.getComponent();
1838                    if (cn != null && cn.getPackageName().equals(packageName)) {
1839                        // If the package name matches, remove the task
1840                        removeTaskByIdLocked(tr.taskId, true);
1841                    }
1842                }
1843            }
1844        }
1845
1846        @Override
1847        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1848            onPackageModified(packageName);
1849            return true;
1850        }
1851
1852        @Override
1853        public void onPackageModified(String packageName) {
1854            final int eventUserId = getChangingUserId();
1855            final IPackageManager pm = AppGlobals.getPackageManager();
1856            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1857                    new ArrayList<Pair<Intent, Integer>>();
1858            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
1859            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1860            // Copy the list of recent tasks so that we don't hold onto the lock on
1861            // ActivityManagerService for long periods while checking if components exist.
1862            synchronized (ActivityManagerService.this) {
1863                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1864                    TaskRecord tr = mRecentTasks.get(i);
1865                    if (tr.userId != eventUserId) continue;
1866
1867                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1868                }
1869            }
1870            // Check the recent tasks and filter out all tasks with components that no longer exist.
1871            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1872                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1873                ComponentName cn = p.first.getComponent();
1874                if (cn != null && cn.getPackageName().equals(packageName)) {
1875                    if (componentsKnownToExist.contains(cn)) {
1876                        // If we know that the component still exists in the package, then skip
1877                        continue;
1878                    }
1879                    try {
1880                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
1881                        if (info != null) {
1882                            componentsKnownToExist.add(cn);
1883                        } else {
1884                            tasksToRemove.add(p.second);
1885                        }
1886                    } catch (RemoteException e) {
1887                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
1888                    }
1889                }
1890            }
1891            // Prune all the tasks with removed components from the list of recent tasks
1892            synchronized (ActivityManagerService.this) {
1893                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1894                    removeTaskByIdLocked(tasksToRemove.get(i), false);
1895                }
1896            }
1897        }
1898
1899        @Override
1900        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1901            // Force stop the specified packages
1902            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
1903            if (packages != null) {
1904                for (String pkg : packages) {
1905                    synchronized (ActivityManagerService.this) {
1906                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
1907                                userId, "finished booting")) {
1908                            return true;
1909                        }
1910                    }
1911                }
1912            }
1913            return false;
1914        }
1915    };
1916
1917    public void setSystemProcess() {
1918        try {
1919            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1920            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1921            ServiceManager.addService("meminfo", new MemBinder(this));
1922            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1923            ServiceManager.addService("dbinfo", new DbBinder(this));
1924            if (MONITOR_CPU_USAGE) {
1925                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1926            }
1927            ServiceManager.addService("permission", new PermissionController(this));
1928
1929            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1930                    "android", STOCK_PM_FLAGS);
1931            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1932
1933            synchronized (this) {
1934                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1935                app.persistent = true;
1936                app.pid = MY_PID;
1937                app.maxAdj = ProcessList.SYSTEM_ADJ;
1938                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1939                mProcessNames.put(app.processName, app.uid, app);
1940                synchronized (mPidsSelfLocked) {
1941                    mPidsSelfLocked.put(app.pid, app);
1942                }
1943                updateLruProcessLocked(app, false, null);
1944                updateOomAdjLocked();
1945            }
1946        } catch (PackageManager.NameNotFoundException e) {
1947            throw new RuntimeException(
1948                    "Unable to find android system package", e);
1949        }
1950    }
1951
1952    public void setWindowManager(WindowManagerService wm) {
1953        mWindowManager = wm;
1954        mStackSupervisor.setWindowManager(wm);
1955    }
1956
1957    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1958        mUsageStatsService = usageStatsManager;
1959    }
1960
1961    public void startObservingNativeCrashes() {
1962        final NativeCrashListener ncl = new NativeCrashListener(this);
1963        ncl.start();
1964    }
1965
1966    public IAppOpsService getAppOpsService() {
1967        return mAppOpsService;
1968    }
1969
1970    static class MemBinder extends Binder {
1971        ActivityManagerService mActivityManagerService;
1972        MemBinder(ActivityManagerService activityManagerService) {
1973            mActivityManagerService = activityManagerService;
1974        }
1975
1976        @Override
1977        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1978            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1979                    != PackageManager.PERMISSION_GRANTED) {
1980                pw.println("Permission Denial: can't dump meminfo from from pid="
1981                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1982                        + " without permission " + android.Manifest.permission.DUMP);
1983                return;
1984            }
1985
1986            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1987        }
1988    }
1989
1990    static class GraphicsBinder extends Binder {
1991        ActivityManagerService mActivityManagerService;
1992        GraphicsBinder(ActivityManagerService activityManagerService) {
1993            mActivityManagerService = activityManagerService;
1994        }
1995
1996        @Override
1997        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1998            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1999                    != PackageManager.PERMISSION_GRANTED) {
2000                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2001                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2002                        + " without permission " + android.Manifest.permission.DUMP);
2003                return;
2004            }
2005
2006            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2007        }
2008    }
2009
2010    static class DbBinder extends Binder {
2011        ActivityManagerService mActivityManagerService;
2012        DbBinder(ActivityManagerService activityManagerService) {
2013            mActivityManagerService = activityManagerService;
2014        }
2015
2016        @Override
2017        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2018            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2019                    != PackageManager.PERMISSION_GRANTED) {
2020                pw.println("Permission Denial: can't dump dbinfo from from pid="
2021                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2022                        + " without permission " + android.Manifest.permission.DUMP);
2023                return;
2024            }
2025
2026            mActivityManagerService.dumpDbInfo(fd, pw, args);
2027        }
2028    }
2029
2030    static class CpuBinder extends Binder {
2031        ActivityManagerService mActivityManagerService;
2032        CpuBinder(ActivityManagerService activityManagerService) {
2033            mActivityManagerService = activityManagerService;
2034        }
2035
2036        @Override
2037        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2038            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2039                    != PackageManager.PERMISSION_GRANTED) {
2040                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2041                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2042                        + " without permission " + android.Manifest.permission.DUMP);
2043                return;
2044            }
2045
2046            synchronized (mActivityManagerService.mProcessCpuTracker) {
2047                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2048                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2049                        SystemClock.uptimeMillis()));
2050            }
2051        }
2052    }
2053
2054    public static final class Lifecycle extends SystemService {
2055        private final ActivityManagerService mService;
2056
2057        public Lifecycle(Context context) {
2058            super(context);
2059            mService = new ActivityManagerService(context);
2060        }
2061
2062        @Override
2063        public void onStart() {
2064            mService.start();
2065        }
2066
2067        public ActivityManagerService getService() {
2068            return mService;
2069        }
2070    }
2071
2072    // Note: This method is invoked on the main thread but may need to attach various
2073    // handlers to other threads.  So take care to be explicit about the looper.
2074    public ActivityManagerService(Context systemContext) {
2075        mContext = systemContext;
2076        mFactoryTest = FactoryTest.getMode();
2077        mSystemThread = ActivityThread.currentActivityThread();
2078
2079        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2080
2081        mHandlerThread = new ServiceThread(TAG,
2082                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2083        mHandlerThread.start();
2084        mHandler = new MainHandler(mHandlerThread.getLooper());
2085
2086        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2087                "foreground", BROADCAST_FG_TIMEOUT, false);
2088        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2089                "background", BROADCAST_BG_TIMEOUT, true);
2090        mBroadcastQueues[0] = mFgBroadcastQueue;
2091        mBroadcastQueues[1] = mBgBroadcastQueue;
2092
2093        mServices = new ActiveServices(this);
2094        mProviderMap = new ProviderMap(this);
2095
2096        // TODO: Move creation of battery stats service outside of activity manager service.
2097        File dataDir = Environment.getDataDirectory();
2098        File systemDir = new File(dataDir, "system");
2099        systemDir.mkdirs();
2100        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2101        mBatteryStatsService.getActiveStatistics().readLocked();
2102        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2103        mOnBattery = DEBUG_POWER ? true
2104                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2105        mBatteryStatsService.getActiveStatistics().setCallback(this);
2106
2107        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2108
2109        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2110
2111        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2112
2113        // User 0 is the first and only user that runs at boot.
2114        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2115        mUserLru.add(Integer.valueOf(0));
2116        updateStartedUserArrayLocked();
2117
2118        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2119            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2120
2121        mConfiguration.setToDefaults();
2122        mConfiguration.setLocale(Locale.getDefault());
2123
2124        mConfigurationSeq = mConfiguration.seq = 1;
2125        mProcessCpuTracker.init();
2126
2127        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2128        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2129        mStackSupervisor = new ActivityStackSupervisor(this);
2130        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2131
2132        mProcessCpuThread = new Thread("CpuTracker") {
2133            @Override
2134            public void run() {
2135                while (true) {
2136                    try {
2137                        try {
2138                            synchronized(this) {
2139                                final long now = SystemClock.uptimeMillis();
2140                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2141                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2142                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2143                                //        + ", write delay=" + nextWriteDelay);
2144                                if (nextWriteDelay < nextCpuDelay) {
2145                                    nextCpuDelay = nextWriteDelay;
2146                                }
2147                                if (nextCpuDelay > 0) {
2148                                    mProcessCpuMutexFree.set(true);
2149                                    this.wait(nextCpuDelay);
2150                                }
2151                            }
2152                        } catch (InterruptedException e) {
2153                        }
2154                        updateCpuStatsNow();
2155                    } catch (Exception e) {
2156                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2157                    }
2158                }
2159            }
2160        };
2161
2162        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2163
2164        Watchdog.getInstance().addMonitor(this);
2165        Watchdog.getInstance().addThread(mHandler);
2166    }
2167
2168    public void setSystemServiceManager(SystemServiceManager mgr) {
2169        mSystemServiceManager = mgr;
2170    }
2171
2172    private void start() {
2173        Process.removeAllProcessGroups();
2174        mProcessCpuThread.start();
2175
2176        mBatteryStatsService.publish(mContext);
2177        mAppOpsService.publish(mContext);
2178        Slog.d("AppOps", "AppOpsService published");
2179        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2180    }
2181
2182    public void initPowerManagement() {
2183        mStackSupervisor.initPowerManagement();
2184        mBatteryStatsService.initPowerManagement();
2185    }
2186
2187    @Override
2188    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2189            throws RemoteException {
2190        if (code == SYSPROPS_TRANSACTION) {
2191            // We need to tell all apps about the system property change.
2192            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2193            synchronized(this) {
2194                final int NP = mProcessNames.getMap().size();
2195                for (int ip=0; ip<NP; ip++) {
2196                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2197                    final int NA = apps.size();
2198                    for (int ia=0; ia<NA; ia++) {
2199                        ProcessRecord app = apps.valueAt(ia);
2200                        if (app.thread != null) {
2201                            procs.add(app.thread.asBinder());
2202                        }
2203                    }
2204                }
2205            }
2206
2207            int N = procs.size();
2208            for (int i=0; i<N; i++) {
2209                Parcel data2 = Parcel.obtain();
2210                try {
2211                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2212                } catch (RemoteException e) {
2213                }
2214                data2.recycle();
2215            }
2216        }
2217        try {
2218            return super.onTransact(code, data, reply, flags);
2219        } catch (RuntimeException e) {
2220            // The activity manager only throws security exceptions, so let's
2221            // log all others.
2222            if (!(e instanceof SecurityException)) {
2223                Slog.wtf(TAG, "Activity Manager Crash", e);
2224            }
2225            throw e;
2226        }
2227    }
2228
2229    void updateCpuStats() {
2230        final long now = SystemClock.uptimeMillis();
2231        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2232            return;
2233        }
2234        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2235            synchronized (mProcessCpuThread) {
2236                mProcessCpuThread.notify();
2237            }
2238        }
2239    }
2240
2241    void updateCpuStatsNow() {
2242        synchronized (mProcessCpuTracker) {
2243            mProcessCpuMutexFree.set(false);
2244            final long now = SystemClock.uptimeMillis();
2245            boolean haveNewCpuStats = false;
2246
2247            if (MONITOR_CPU_USAGE &&
2248                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2249                mLastCpuTime.set(now);
2250                haveNewCpuStats = true;
2251                mProcessCpuTracker.update();
2252                //Slog.i(TAG, mProcessCpu.printCurrentState());
2253                //Slog.i(TAG, "Total CPU usage: "
2254                //        + mProcessCpu.getTotalCpuPercent() + "%");
2255
2256                // Slog the cpu usage if the property is set.
2257                if ("true".equals(SystemProperties.get("events.cpu"))) {
2258                    int user = mProcessCpuTracker.getLastUserTime();
2259                    int system = mProcessCpuTracker.getLastSystemTime();
2260                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2261                    int irq = mProcessCpuTracker.getLastIrqTime();
2262                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2263                    int idle = mProcessCpuTracker.getLastIdleTime();
2264
2265                    int total = user + system + iowait + irq + softIrq + idle;
2266                    if (total == 0) total = 1;
2267
2268                    EventLog.writeEvent(EventLogTags.CPU,
2269                            ((user+system+iowait+irq+softIrq) * 100) / total,
2270                            (user * 100) / total,
2271                            (system * 100) / total,
2272                            (iowait * 100) / total,
2273                            (irq * 100) / total,
2274                            (softIrq * 100) / total);
2275                }
2276            }
2277
2278            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2279            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2280            synchronized(bstats) {
2281                synchronized(mPidsSelfLocked) {
2282                    if (haveNewCpuStats) {
2283                        if (mOnBattery) {
2284                            int perc = bstats.startAddingCpuLocked();
2285                            int totalUTime = 0;
2286                            int totalSTime = 0;
2287                            final int N = mProcessCpuTracker.countStats();
2288                            for (int i=0; i<N; i++) {
2289                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2290                                if (!st.working) {
2291                                    continue;
2292                                }
2293                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2294                                int otherUTime = (st.rel_utime*perc)/100;
2295                                int otherSTime = (st.rel_stime*perc)/100;
2296                                totalUTime += otherUTime;
2297                                totalSTime += otherSTime;
2298                                if (pr != null) {
2299                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2300                                    if (ps == null || !ps.isActive()) {
2301                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2302                                                pr.info.uid, pr.processName);
2303                                    }
2304                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2305                                            st.rel_stime-otherSTime);
2306                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2307                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2308                                } else {
2309                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2310                                    if (ps == null || !ps.isActive()) {
2311                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2312                                                bstats.mapUid(st.uid), st.name);
2313                                    }
2314                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2315                                            st.rel_stime-otherSTime);
2316                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2317                                }
2318                            }
2319                            bstats.finishAddingCpuLocked(perc, totalUTime,
2320                                    totalSTime, cpuSpeedTimes);
2321                        }
2322                    }
2323                }
2324
2325                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2326                    mLastWriteTime = now;
2327                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2328                }
2329            }
2330        }
2331    }
2332
2333    @Override
2334    public void batteryNeedsCpuUpdate() {
2335        updateCpuStatsNow();
2336    }
2337
2338    @Override
2339    public void batteryPowerChanged(boolean onBattery) {
2340        // When plugging in, update the CPU stats first before changing
2341        // the plug state.
2342        updateCpuStatsNow();
2343        synchronized (this) {
2344            synchronized(mPidsSelfLocked) {
2345                mOnBattery = DEBUG_POWER ? true : onBattery;
2346            }
2347        }
2348    }
2349
2350    /**
2351     * Initialize the application bind args. These are passed to each
2352     * process when the bindApplication() IPC is sent to the process. They're
2353     * lazily setup to make sure the services are running when they're asked for.
2354     */
2355    private HashMap<String, IBinder> getCommonServicesLocked() {
2356        if (mAppBindArgs == null) {
2357            mAppBindArgs = new HashMap<String, IBinder>();
2358
2359            // Setup the application init args
2360            mAppBindArgs.put("package", ServiceManager.getService("package"));
2361            mAppBindArgs.put("window", ServiceManager.getService("window"));
2362            mAppBindArgs.put(Context.ALARM_SERVICE,
2363                    ServiceManager.getService(Context.ALARM_SERVICE));
2364        }
2365        return mAppBindArgs;
2366    }
2367
2368    final void setFocusedActivityLocked(ActivityRecord r) {
2369        if (mFocusedActivity != r) {
2370            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2371            mFocusedActivity = r;
2372            if (r.task != null && r.task.voiceInteractor != null) {
2373                startRunningVoiceLocked();
2374            } else {
2375                finishRunningVoiceLocked();
2376            }
2377            mStackSupervisor.setFocusedStack(r);
2378            if (r != null) {
2379                mWindowManager.setFocusedApp(r.appToken, true);
2380            }
2381            applyUpdateLockStateLocked(r);
2382        }
2383    }
2384
2385    final void clearFocusedActivity(ActivityRecord r) {
2386        if (mFocusedActivity == r) {
2387            mFocusedActivity = null;
2388        }
2389    }
2390
2391    @Override
2392    public void setFocusedStack(int stackId) {
2393        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2394        synchronized (ActivityManagerService.this) {
2395            ActivityStack stack = mStackSupervisor.getStack(stackId);
2396            if (stack != null) {
2397                ActivityRecord r = stack.topRunningActivityLocked(null);
2398                if (r != null) {
2399                    setFocusedActivityLocked(r);
2400                }
2401            }
2402        }
2403    }
2404
2405    @Override
2406    public void notifyActivityDrawn(IBinder token) {
2407        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2408        synchronized (this) {
2409            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2410            if (r != null) {
2411                r.task.stack.notifyActivityDrawnLocked(r);
2412            }
2413        }
2414    }
2415
2416    final void applyUpdateLockStateLocked(ActivityRecord r) {
2417        // Modifications to the UpdateLock state are done on our handler, outside
2418        // the activity manager's locks.  The new state is determined based on the
2419        // state *now* of the relevant activity record.  The object is passed to
2420        // the handler solely for logging detail, not to be consulted/modified.
2421        final boolean nextState = r != null && r.immersive;
2422        mHandler.sendMessage(
2423                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2424    }
2425
2426    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2427        Message msg = Message.obtain();
2428        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2429        msg.obj = r.task.askedCompatMode ? null : r;
2430        mHandler.sendMessage(msg);
2431    }
2432
2433    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2434            String what, Object obj, ProcessRecord srcApp) {
2435        app.lastActivityTime = now;
2436
2437        if (app.activities.size() > 0) {
2438            // Don't want to touch dependent processes that are hosting activities.
2439            return index;
2440        }
2441
2442        int lrui = mLruProcesses.lastIndexOf(app);
2443        if (lrui < 0) {
2444            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2445                    + what + " " + obj + " from " + srcApp);
2446            return index;
2447        }
2448
2449        if (lrui >= index) {
2450            // Don't want to cause this to move dependent processes *back* in the
2451            // list as if they were less frequently used.
2452            return index;
2453        }
2454
2455        if (lrui >= mLruProcessActivityStart) {
2456            // Don't want to touch dependent processes that are hosting activities.
2457            return index;
2458        }
2459
2460        mLruProcesses.remove(lrui);
2461        if (index > 0) {
2462            index--;
2463        }
2464        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2465                + " in LRU list: " + app);
2466        mLruProcesses.add(index, app);
2467        return index;
2468    }
2469
2470    final void removeLruProcessLocked(ProcessRecord app) {
2471        int lrui = mLruProcesses.lastIndexOf(app);
2472        if (lrui >= 0) {
2473            if (!app.killed) {
2474                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2475                Process.killProcessQuiet(app.pid);
2476                Process.killProcessGroup(app.info.uid, app.pid);
2477            }
2478            if (lrui <= mLruProcessActivityStart) {
2479                mLruProcessActivityStart--;
2480            }
2481            if (lrui <= mLruProcessServiceStart) {
2482                mLruProcessServiceStart--;
2483            }
2484            mLruProcesses.remove(lrui);
2485        }
2486    }
2487
2488    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2489            ProcessRecord client) {
2490        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2491                || app.treatLikeActivity;
2492        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2493        if (!activityChange && hasActivity) {
2494            // The process has activities, so we are only allowing activity-based adjustments
2495            // to move it.  It should be kept in the front of the list with other
2496            // processes that have activities, and we don't want those to change their
2497            // order except due to activity operations.
2498            return;
2499        }
2500
2501        mLruSeq++;
2502        final long now = SystemClock.uptimeMillis();
2503        app.lastActivityTime = now;
2504
2505        // First a quick reject: if the app is already at the position we will
2506        // put it, then there is nothing to do.
2507        if (hasActivity) {
2508            final int N = mLruProcesses.size();
2509            if (N > 0 && mLruProcesses.get(N-1) == app) {
2510                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2511                return;
2512            }
2513        } else {
2514            if (mLruProcessServiceStart > 0
2515                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2516                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2517                return;
2518            }
2519        }
2520
2521        int lrui = mLruProcesses.lastIndexOf(app);
2522
2523        if (app.persistent && lrui >= 0) {
2524            // We don't care about the position of persistent processes, as long as
2525            // they are in the list.
2526            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2527            return;
2528        }
2529
2530        /* In progress: compute new position first, so we can avoid doing work
2531           if the process is not actually going to move.  Not yet working.
2532        int addIndex;
2533        int nextIndex;
2534        boolean inActivity = false, inService = false;
2535        if (hasActivity) {
2536            // Process has activities, put it at the very tipsy-top.
2537            addIndex = mLruProcesses.size();
2538            nextIndex = mLruProcessServiceStart;
2539            inActivity = true;
2540        } else if (hasService) {
2541            // Process has services, put it at the top of the service list.
2542            addIndex = mLruProcessActivityStart;
2543            nextIndex = mLruProcessServiceStart;
2544            inActivity = true;
2545            inService = true;
2546        } else  {
2547            // Process not otherwise of interest, it goes to the top of the non-service area.
2548            addIndex = mLruProcessServiceStart;
2549            if (client != null) {
2550                int clientIndex = mLruProcesses.lastIndexOf(client);
2551                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2552                        + app);
2553                if (clientIndex >= 0 && addIndex > clientIndex) {
2554                    addIndex = clientIndex;
2555                }
2556            }
2557            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2558        }
2559
2560        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2561                + mLruProcessActivityStart + "): " + app);
2562        */
2563
2564        if (lrui >= 0) {
2565            if (lrui < mLruProcessActivityStart) {
2566                mLruProcessActivityStart--;
2567            }
2568            if (lrui < mLruProcessServiceStart) {
2569                mLruProcessServiceStart--;
2570            }
2571            /*
2572            if (addIndex > lrui) {
2573                addIndex--;
2574            }
2575            if (nextIndex > lrui) {
2576                nextIndex--;
2577            }
2578            */
2579            mLruProcesses.remove(lrui);
2580        }
2581
2582        /*
2583        mLruProcesses.add(addIndex, app);
2584        if (inActivity) {
2585            mLruProcessActivityStart++;
2586        }
2587        if (inService) {
2588            mLruProcessActivityStart++;
2589        }
2590        */
2591
2592        int nextIndex;
2593        if (hasActivity) {
2594            final int N = mLruProcesses.size();
2595            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2596                // Process doesn't have activities, but has clients with
2597                // activities...  move it up, but one below the top (the top
2598                // should always have a real activity).
2599                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2600                mLruProcesses.add(N-1, app);
2601                // To keep it from spamming the LRU list (by making a bunch of clients),
2602                // we will push down any other entries owned by the app.
2603                final int uid = app.info.uid;
2604                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2605                    ProcessRecord subProc = mLruProcesses.get(i);
2606                    if (subProc.info.uid == uid) {
2607                        // We want to push this one down the list.  If the process after
2608                        // it is for the same uid, however, don't do so, because we don't
2609                        // want them internally to be re-ordered.
2610                        if (mLruProcesses.get(i-1).info.uid != uid) {
2611                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2612                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2613                            ProcessRecord tmp = mLruProcesses.get(i);
2614                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2615                            mLruProcesses.set(i-1, tmp);
2616                            i--;
2617                        }
2618                    } else {
2619                        // A gap, we can stop here.
2620                        break;
2621                    }
2622                }
2623            } else {
2624                // Process has activities, put it at the very tipsy-top.
2625                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2626                mLruProcesses.add(app);
2627            }
2628            nextIndex = mLruProcessServiceStart;
2629        } else if (hasService) {
2630            // Process has services, put it at the top of the service list.
2631            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2632            mLruProcesses.add(mLruProcessActivityStart, app);
2633            nextIndex = mLruProcessServiceStart;
2634            mLruProcessActivityStart++;
2635        } else  {
2636            // Process not otherwise of interest, it goes to the top of the non-service area.
2637            int index = mLruProcessServiceStart;
2638            if (client != null) {
2639                // If there is a client, don't allow the process to be moved up higher
2640                // in the list than that client.
2641                int clientIndex = mLruProcesses.lastIndexOf(client);
2642                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2643                        + " when updating " + app);
2644                if (clientIndex <= lrui) {
2645                    // Don't allow the client index restriction to push it down farther in the
2646                    // list than it already is.
2647                    clientIndex = lrui;
2648                }
2649                if (clientIndex >= 0 && index > clientIndex) {
2650                    index = clientIndex;
2651                }
2652            }
2653            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2654            mLruProcesses.add(index, app);
2655            nextIndex = index-1;
2656            mLruProcessActivityStart++;
2657            mLruProcessServiceStart++;
2658        }
2659
2660        // If the app is currently using a content provider or service,
2661        // bump those processes as well.
2662        for (int j=app.connections.size()-1; j>=0; j--) {
2663            ConnectionRecord cr = app.connections.valueAt(j);
2664            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2665                    && cr.binding.service.app != null
2666                    && cr.binding.service.app.lruSeq != mLruSeq
2667                    && !cr.binding.service.app.persistent) {
2668                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2669                        "service connection", cr, app);
2670            }
2671        }
2672        for (int j=app.conProviders.size()-1; j>=0; j--) {
2673            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2674            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2675                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2676                        "provider reference", cpr, app);
2677            }
2678        }
2679    }
2680
2681    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2682        if (uid == Process.SYSTEM_UID) {
2683            // The system gets to run in any process.  If there are multiple
2684            // processes with the same uid, just pick the first (this
2685            // should never happen).
2686            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2687            if (procs == null) return null;
2688            final int N = procs.size();
2689            for (int i = 0; i < N; i++) {
2690                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2691            }
2692        }
2693        ProcessRecord proc = mProcessNames.get(processName, uid);
2694        if (false && proc != null && !keepIfLarge
2695                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2696                && proc.lastCachedPss >= 4000) {
2697            // Turn this condition on to cause killing to happen regularly, for testing.
2698            if (proc.baseProcessTracker != null) {
2699                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2700            }
2701            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2702        } else if (proc != null && !keepIfLarge
2703                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2704                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2705            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2706            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2707                if (proc.baseProcessTracker != null) {
2708                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2709                }
2710                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2711            }
2712        }
2713        return proc;
2714    }
2715
2716    void ensurePackageDexOpt(String packageName) {
2717        IPackageManager pm = AppGlobals.getPackageManager();
2718        try {
2719            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2720                mDidDexOpt = true;
2721            }
2722        } catch (RemoteException e) {
2723        }
2724    }
2725
2726    boolean isNextTransitionForward() {
2727        int transit = mWindowManager.getPendingAppTransition();
2728        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2729                || transit == AppTransition.TRANSIT_TASK_OPEN
2730                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2731    }
2732
2733    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2734            String processName, String abiOverride, int uid, Runnable crashHandler) {
2735        synchronized(this) {
2736            ApplicationInfo info = new ApplicationInfo();
2737            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2738            // For isolated processes, the former contains the parent's uid and the latter the
2739            // actual uid of the isolated process.
2740            // In the special case introduced by this method (which is, starting an isolated
2741            // process directly from the SystemServer without an actual parent app process) the
2742            // closest thing to a parent's uid is SYSTEM_UID.
2743            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2744            // the |isolated| logic in the ProcessRecord constructor.
2745            info.uid = Process.SYSTEM_UID;
2746            info.processName = processName;
2747            info.className = entryPoint;
2748            info.packageName = "android";
2749            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2750                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2751                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2752                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2753                    crashHandler);
2754            return proc != null ? proc.pid : 0;
2755        }
2756    }
2757
2758    final ProcessRecord startProcessLocked(String processName,
2759            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2760            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2761            boolean isolated, boolean keepIfLarge) {
2762        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2763                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2764                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2765                null /* crashHandler */);
2766    }
2767
2768    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2769            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2770            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2771            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2772        long startTime = SystemClock.elapsedRealtime();
2773        ProcessRecord app;
2774        if (!isolated) {
2775            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2776            checkTime(startTime, "startProcess: after getProcessRecord");
2777        } else {
2778            // If this is an isolated process, it can't re-use an existing process.
2779            app = null;
2780        }
2781        // We don't have to do anything more if:
2782        // (1) There is an existing application record; and
2783        // (2) The caller doesn't think it is dead, OR there is no thread
2784        //     object attached to it so we know it couldn't have crashed; and
2785        // (3) There is a pid assigned to it, so it is either starting or
2786        //     already running.
2787        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2788                + " app=" + app + " knownToBeDead=" + knownToBeDead
2789                + " thread=" + (app != null ? app.thread : null)
2790                + " pid=" + (app != null ? app.pid : -1));
2791        if (app != null && app.pid > 0) {
2792            if (!knownToBeDead || app.thread == null) {
2793                // We already have the app running, or are waiting for it to
2794                // come up (we have a pid but not yet its thread), so keep it.
2795                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2796                // If this is a new package in the process, add the package to the list
2797                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2798                checkTime(startTime, "startProcess: done, added package to proc");
2799                return app;
2800            }
2801
2802            // An application record is attached to a previous process,
2803            // clean it up now.
2804            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2805            checkTime(startTime, "startProcess: bad proc running, killing");
2806            Process.killProcessGroup(app.info.uid, app.pid);
2807            handleAppDiedLocked(app, true, true);
2808            checkTime(startTime, "startProcess: done killing old proc");
2809        }
2810
2811        String hostingNameStr = hostingName != null
2812                ? hostingName.flattenToShortString() : null;
2813
2814        if (!isolated) {
2815            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2816                // If we are in the background, then check to see if this process
2817                // is bad.  If so, we will just silently fail.
2818                if (mBadProcesses.get(info.processName, info.uid) != null) {
2819                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2820                            + "/" + info.processName);
2821                    return null;
2822                }
2823            } else {
2824                // When the user is explicitly starting a process, then clear its
2825                // crash count so that we won't make it bad until they see at
2826                // least one crash dialog again, and make the process good again
2827                // if it had been bad.
2828                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2829                        + "/" + info.processName);
2830                mProcessCrashTimes.remove(info.processName, info.uid);
2831                if (mBadProcesses.get(info.processName, info.uid) != null) {
2832                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2833                            UserHandle.getUserId(info.uid), info.uid,
2834                            info.processName);
2835                    mBadProcesses.remove(info.processName, info.uid);
2836                    if (app != null) {
2837                        app.bad = false;
2838                    }
2839                }
2840            }
2841        }
2842
2843        if (app == null) {
2844            checkTime(startTime, "startProcess: creating new process record");
2845            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2846            app.crashHandler = crashHandler;
2847            if (app == null) {
2848                Slog.w(TAG, "Failed making new process record for "
2849                        + processName + "/" + info.uid + " isolated=" + isolated);
2850                return null;
2851            }
2852            mProcessNames.put(processName, app.uid, app);
2853            if (isolated) {
2854                mIsolatedProcesses.put(app.uid, app);
2855            }
2856            checkTime(startTime, "startProcess: done creating new process record");
2857        } else {
2858            // If this is a new package in the process, add the package to the list
2859            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2860            checkTime(startTime, "startProcess: added package to existing proc");
2861        }
2862
2863        // If the system is not ready yet, then hold off on starting this
2864        // process until it is.
2865        if (!mProcessesReady
2866                && !isAllowedWhileBooting(info)
2867                && !allowWhileBooting) {
2868            if (!mProcessesOnHold.contains(app)) {
2869                mProcessesOnHold.add(app);
2870            }
2871            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2872            checkTime(startTime, "startProcess: returning with proc on hold");
2873            return app;
2874        }
2875
2876        checkTime(startTime, "startProcess: stepping in to startProcess");
2877        startProcessLocked(
2878                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2879        checkTime(startTime, "startProcess: done starting proc!");
2880        return (app.pid != 0) ? app : null;
2881    }
2882
2883    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2884        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2885    }
2886
2887    private final void startProcessLocked(ProcessRecord app,
2888            String hostingType, String hostingNameStr) {
2889        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2890                null /* entryPoint */, null /* entryPointArgs */);
2891    }
2892
2893    private final void startProcessLocked(ProcessRecord app, String hostingType,
2894            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2895        long startTime = SystemClock.elapsedRealtime();
2896        if (app.pid > 0 && app.pid != MY_PID) {
2897            checkTime(startTime, "startProcess: removing from pids map");
2898            synchronized (mPidsSelfLocked) {
2899                mPidsSelfLocked.remove(app.pid);
2900                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2901            }
2902            checkTime(startTime, "startProcess: done removing from pids map");
2903            app.setPid(0);
2904        }
2905
2906        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2907                "startProcessLocked removing on hold: " + app);
2908        mProcessesOnHold.remove(app);
2909
2910        checkTime(startTime, "startProcess: starting to update cpu stats");
2911        updateCpuStats();
2912        checkTime(startTime, "startProcess: done updating cpu stats");
2913
2914        try {
2915            int uid = app.uid;
2916
2917            int[] gids = null;
2918            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2919            if (!app.isolated) {
2920                int[] permGids = null;
2921                try {
2922                    checkTime(startTime, "startProcess: getting gids from package manager");
2923                    final PackageManager pm = mContext.getPackageManager();
2924                    permGids = pm.getPackageGids(app.info.packageName);
2925
2926                    if (Environment.isExternalStorageEmulated()) {
2927                        checkTime(startTime, "startProcess: checking external storage perm");
2928                        if (pm.checkPermission(
2929                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2930                                app.info.packageName) == PERMISSION_GRANTED) {
2931                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2932                        } else {
2933                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2934                        }
2935                    }
2936                } catch (PackageManager.NameNotFoundException e) {
2937                    Slog.w(TAG, "Unable to retrieve gids", e);
2938                }
2939
2940                /*
2941                 * Add shared application and profile GIDs so applications can share some
2942                 * resources like shared libraries and access user-wide resources
2943                 */
2944                if (permGids == null) {
2945                    gids = new int[2];
2946                } else {
2947                    gids = new int[permGids.length + 2];
2948                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2949                }
2950                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2951                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2952            }
2953            checkTime(startTime, "startProcess: building args");
2954            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2955                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2956                        && mTopComponent != null
2957                        && app.processName.equals(mTopComponent.getPackageName())) {
2958                    uid = 0;
2959                }
2960                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2961                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2962                    uid = 0;
2963                }
2964            }
2965            int debugFlags = 0;
2966            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2967                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2968                // Also turn on CheckJNI for debuggable apps. It's quite
2969                // awkward to turn on otherwise.
2970                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2971            }
2972            // Run the app in safe mode if its manifest requests so or the
2973            // system is booted in safe mode.
2974            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2975                mSafeMode == true) {
2976                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2977            }
2978            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2979                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2980            }
2981            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2982                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2983            }
2984            if ("1".equals(SystemProperties.get("debug.assert"))) {
2985                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2986            }
2987
2988            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
2989            if (requiredAbi == null) {
2990                requiredAbi = Build.SUPPORTED_ABIS[0];
2991            }
2992
2993            String instructionSet = null;
2994            if (app.info.primaryCpuAbi != null) {
2995                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
2996            }
2997
2998            // Start the process.  It will either succeed and return a result containing
2999            // the PID of the new process, or else throw a RuntimeException.
3000            boolean isActivityProcess = (entryPoint == null);
3001            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3002            checkTime(startTime, "startProcess: asking zygote to start proc");
3003            Process.ProcessStartResult startResult = Process.start(entryPoint,
3004                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3005                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3006                    app.info.dataDir, entryPointArgs);
3007            checkTime(startTime, "startProcess: returned from zygote!");
3008
3009            if (app.isolated) {
3010                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3011            }
3012            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3013            checkTime(startTime, "startProcess: done updating battery stats");
3014
3015            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3016                    UserHandle.getUserId(uid), startResult.pid, uid,
3017                    app.processName, hostingType,
3018                    hostingNameStr != null ? hostingNameStr : "");
3019
3020            if (app.persistent) {
3021                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3022            }
3023
3024            checkTime(startTime, "startProcess: building log message");
3025            StringBuilder buf = mStringBuilder;
3026            buf.setLength(0);
3027            buf.append("Start proc ");
3028            buf.append(app.processName);
3029            if (!isActivityProcess) {
3030                buf.append(" [");
3031                buf.append(entryPoint);
3032                buf.append("]");
3033            }
3034            buf.append(" for ");
3035            buf.append(hostingType);
3036            if (hostingNameStr != null) {
3037                buf.append(" ");
3038                buf.append(hostingNameStr);
3039            }
3040            buf.append(": pid=");
3041            buf.append(startResult.pid);
3042            buf.append(" uid=");
3043            buf.append(uid);
3044            buf.append(" gids={");
3045            if (gids != null) {
3046                for (int gi=0; gi<gids.length; gi++) {
3047                    if (gi != 0) buf.append(", ");
3048                    buf.append(gids[gi]);
3049
3050                }
3051            }
3052            buf.append("}");
3053            if (requiredAbi != null) {
3054                buf.append(" abi=");
3055                buf.append(requiredAbi);
3056            }
3057            Slog.i(TAG, buf.toString());
3058            app.setPid(startResult.pid);
3059            app.usingWrapper = startResult.usingWrapper;
3060            app.removed = false;
3061            app.killed = false;
3062            app.killedByAm = false;
3063            checkTime(startTime, "startProcess: starting to update pids map");
3064            synchronized (mPidsSelfLocked) {
3065                this.mPidsSelfLocked.put(startResult.pid, app);
3066                if (isActivityProcess) {
3067                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3068                    msg.obj = app;
3069                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3070                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3071                }
3072            }
3073            checkTime(startTime, "startProcess: done updating pids map");
3074        } catch (RuntimeException e) {
3075            // XXX do better error recovery.
3076            app.setPid(0);
3077            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3078            if (app.isolated) {
3079                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3080            }
3081            Slog.e(TAG, "Failure starting process " + app.processName, e);
3082        }
3083    }
3084
3085    void updateUsageStats(ActivityRecord component, boolean resumed) {
3086        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3087        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3088        if (resumed) {
3089            if (mUsageStatsService != null) {
3090                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3091                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3092            }
3093            synchronized (stats) {
3094                stats.noteActivityResumedLocked(component.app.uid);
3095            }
3096        } else {
3097            if (mUsageStatsService != null) {
3098                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3099                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3100            }
3101            synchronized (stats) {
3102                stats.noteActivityPausedLocked(component.app.uid);
3103            }
3104        }
3105    }
3106
3107    Intent getHomeIntent() {
3108        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3109        intent.setComponent(mTopComponent);
3110        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3111            intent.addCategory(Intent.CATEGORY_HOME);
3112        }
3113        return intent;
3114    }
3115
3116    boolean startHomeActivityLocked(int userId) {
3117        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3118                && mTopAction == null) {
3119            // We are running in factory test mode, but unable to find
3120            // the factory test app, so just sit around displaying the
3121            // error message and don't try to start anything.
3122            return false;
3123        }
3124        Intent intent = getHomeIntent();
3125        ActivityInfo aInfo =
3126            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3127        if (aInfo != null) {
3128            intent.setComponent(new ComponentName(
3129                    aInfo.applicationInfo.packageName, aInfo.name));
3130            // Don't do this if the home app is currently being
3131            // instrumented.
3132            aInfo = new ActivityInfo(aInfo);
3133            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3134            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3135                    aInfo.applicationInfo.uid, true);
3136            if (app == null || app.instrumentationClass == null) {
3137                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3138                mStackSupervisor.startHomeActivity(intent, aInfo);
3139            }
3140        }
3141
3142        return true;
3143    }
3144
3145    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3146        ActivityInfo ai = null;
3147        ComponentName comp = intent.getComponent();
3148        try {
3149            if (comp != null) {
3150                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3151            } else {
3152                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3153                        intent,
3154                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3155                            flags, userId);
3156
3157                if (info != null) {
3158                    ai = info.activityInfo;
3159                }
3160            }
3161        } catch (RemoteException e) {
3162            // ignore
3163        }
3164
3165        return ai;
3166    }
3167
3168    /**
3169     * Starts the "new version setup screen" if appropriate.
3170     */
3171    void startSetupActivityLocked() {
3172        // Only do this once per boot.
3173        if (mCheckedForSetup) {
3174            return;
3175        }
3176
3177        // We will show this screen if the current one is a different
3178        // version than the last one shown, and we are not running in
3179        // low-level factory test mode.
3180        final ContentResolver resolver = mContext.getContentResolver();
3181        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3182                Settings.Global.getInt(resolver,
3183                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3184            mCheckedForSetup = true;
3185
3186            // See if we should be showing the platform update setup UI.
3187            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3188            List<ResolveInfo> ris = mContext.getPackageManager()
3189                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3190
3191            // We don't allow third party apps to replace this.
3192            ResolveInfo ri = null;
3193            for (int i=0; ris != null && i<ris.size(); i++) {
3194                if ((ris.get(i).activityInfo.applicationInfo.flags
3195                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3196                    ri = ris.get(i);
3197                    break;
3198                }
3199            }
3200
3201            if (ri != null) {
3202                String vers = ri.activityInfo.metaData != null
3203                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3204                        : null;
3205                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3206                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3207                            Intent.METADATA_SETUP_VERSION);
3208                }
3209                String lastVers = Settings.Secure.getString(
3210                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3211                if (vers != null && !vers.equals(lastVers)) {
3212                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3213                    intent.setComponent(new ComponentName(
3214                            ri.activityInfo.packageName, ri.activityInfo.name));
3215                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3216                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3217                            null);
3218                }
3219            }
3220        }
3221    }
3222
3223    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3224        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3225    }
3226
3227    void enforceNotIsolatedCaller(String caller) {
3228        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3229            throw new SecurityException("Isolated process not allowed to call " + caller);
3230        }
3231    }
3232
3233    void enforceShellRestriction(String restriction, int userHandle) {
3234        if (Binder.getCallingUid() == Process.SHELL_UID) {
3235            if (userHandle < 0
3236                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3237                throw new SecurityException("Shell does not have permission to access user "
3238                        + userHandle);
3239            }
3240        }
3241    }
3242
3243    @Override
3244    public int getFrontActivityScreenCompatMode() {
3245        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3246        synchronized (this) {
3247            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3248        }
3249    }
3250
3251    @Override
3252    public void setFrontActivityScreenCompatMode(int mode) {
3253        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3254                "setFrontActivityScreenCompatMode");
3255        synchronized (this) {
3256            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3257        }
3258    }
3259
3260    @Override
3261    public int getPackageScreenCompatMode(String packageName) {
3262        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3263        synchronized (this) {
3264            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3265        }
3266    }
3267
3268    @Override
3269    public void setPackageScreenCompatMode(String packageName, int mode) {
3270        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3271                "setPackageScreenCompatMode");
3272        synchronized (this) {
3273            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3274        }
3275    }
3276
3277    @Override
3278    public boolean getPackageAskScreenCompat(String packageName) {
3279        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3280        synchronized (this) {
3281            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3282        }
3283    }
3284
3285    @Override
3286    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3287        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3288                "setPackageAskScreenCompat");
3289        synchronized (this) {
3290            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3291        }
3292    }
3293
3294    private void dispatchProcessesChanged() {
3295        int N;
3296        synchronized (this) {
3297            N = mPendingProcessChanges.size();
3298            if (mActiveProcessChanges.length < N) {
3299                mActiveProcessChanges = new ProcessChangeItem[N];
3300            }
3301            mPendingProcessChanges.toArray(mActiveProcessChanges);
3302            mAvailProcessChanges.addAll(mPendingProcessChanges);
3303            mPendingProcessChanges.clear();
3304            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3305        }
3306
3307        int i = mProcessObservers.beginBroadcast();
3308        while (i > 0) {
3309            i--;
3310            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3311            if (observer != null) {
3312                try {
3313                    for (int j=0; j<N; j++) {
3314                        ProcessChangeItem item = mActiveProcessChanges[j];
3315                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3316                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3317                                    + item.pid + " uid=" + item.uid + ": "
3318                                    + item.foregroundActivities);
3319                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3320                                    item.foregroundActivities);
3321                        }
3322                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3323                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3324                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3325                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3326                        }
3327                    }
3328                } catch (RemoteException e) {
3329                }
3330            }
3331        }
3332        mProcessObservers.finishBroadcast();
3333    }
3334
3335    private void dispatchProcessDied(int pid, int uid) {
3336        int i = mProcessObservers.beginBroadcast();
3337        while (i > 0) {
3338            i--;
3339            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3340            if (observer != null) {
3341                try {
3342                    observer.onProcessDied(pid, uid);
3343                } catch (RemoteException e) {
3344                }
3345            }
3346        }
3347        mProcessObservers.finishBroadcast();
3348    }
3349
3350    @Override
3351    public final int startActivity(IApplicationThread caller, String callingPackage,
3352            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3353            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3354        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3355            resultWho, requestCode, startFlags, profilerInfo, options,
3356            UserHandle.getCallingUserId());
3357    }
3358
3359    @Override
3360    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3361            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3362            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3363        enforceNotIsolatedCaller("startActivity");
3364        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3365                false, ALLOW_FULL_ONLY, "startActivity", null);
3366        // TODO: Switch to user app stacks here.
3367        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3368                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3369                profilerInfo, null, null, options, userId, null, null);
3370    }
3371
3372    @Override
3373    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3374            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3375            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3376
3377        // This is very dangerous -- it allows you to perform a start activity (including
3378        // permission grants) as any app that may launch one of your own activities.  So
3379        // we will only allow this to be done from activities that are part of the core framework,
3380        // and then only when they are running as the system.
3381        final ActivityRecord sourceRecord;
3382        final int targetUid;
3383        final String targetPackage;
3384        synchronized (this) {
3385            if (resultTo == null) {
3386                throw new SecurityException("Must be called from an activity");
3387            }
3388            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3389            if (sourceRecord == null) {
3390                throw new SecurityException("Called with bad activity token: " + resultTo);
3391            }
3392            if (!sourceRecord.info.packageName.equals("android")) {
3393                throw new SecurityException(
3394                        "Must be called from an activity that is declared in the android package");
3395            }
3396            if (sourceRecord.app == null) {
3397                throw new SecurityException("Called without a process attached to activity");
3398            }
3399            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3400                // This is still okay, as long as this activity is running under the
3401                // uid of the original calling activity.
3402                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3403                    throw new SecurityException(
3404                            "Calling activity in uid " + sourceRecord.app.uid
3405                                    + " must be system uid or original calling uid "
3406                                    + sourceRecord.launchedFromUid);
3407                }
3408            }
3409            targetUid = sourceRecord.launchedFromUid;
3410            targetPackage = sourceRecord.launchedFromPackage;
3411        }
3412
3413        if (userId == UserHandle.USER_NULL) {
3414            userId = UserHandle.getUserId(sourceRecord.app.uid);
3415        }
3416
3417        // TODO: Switch to user app stacks here.
3418        try {
3419            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3420                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3421                    null, null, options, userId, null, null);
3422            return ret;
3423        } catch (SecurityException e) {
3424            // XXX need to figure out how to propagate to original app.
3425            // A SecurityException here is generally actually a fault of the original
3426            // calling activity (such as a fairly granting permissions), so propagate it
3427            // back to them.
3428            /*
3429            StringBuilder msg = new StringBuilder();
3430            msg.append("While launching");
3431            msg.append(intent.toString());
3432            msg.append(": ");
3433            msg.append(e.getMessage());
3434            */
3435            throw e;
3436        }
3437    }
3438
3439    @Override
3440    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3441            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3442            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3443        enforceNotIsolatedCaller("startActivityAndWait");
3444        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3445                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3446        WaitResult res = new WaitResult();
3447        // TODO: Switch to user app stacks here.
3448        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3449                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3450                options, userId, null, null);
3451        return res;
3452    }
3453
3454    @Override
3455    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3456            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3457            int startFlags, Configuration config, Bundle options, int userId) {
3458        enforceNotIsolatedCaller("startActivityWithConfig");
3459        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3460                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3461        // TODO: Switch to user app stacks here.
3462        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3463                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3464                null, null, config, options, userId, null, null);
3465        return ret;
3466    }
3467
3468    @Override
3469    public int startActivityIntentSender(IApplicationThread caller,
3470            IntentSender intent, Intent fillInIntent, String resolvedType,
3471            IBinder resultTo, String resultWho, int requestCode,
3472            int flagsMask, int flagsValues, Bundle options) {
3473        enforceNotIsolatedCaller("startActivityIntentSender");
3474        // Refuse possible leaked file descriptors
3475        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3476            throw new IllegalArgumentException("File descriptors passed in Intent");
3477        }
3478
3479        IIntentSender sender = intent.getTarget();
3480        if (!(sender instanceof PendingIntentRecord)) {
3481            throw new IllegalArgumentException("Bad PendingIntent object");
3482        }
3483
3484        PendingIntentRecord pir = (PendingIntentRecord)sender;
3485
3486        synchronized (this) {
3487            // If this is coming from the currently resumed activity, it is
3488            // effectively saying that app switches are allowed at this point.
3489            final ActivityStack stack = getFocusedStack();
3490            if (stack.mResumedActivity != null &&
3491                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3492                mAppSwitchesAllowedTime = 0;
3493            }
3494        }
3495        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3496                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3497        return ret;
3498    }
3499
3500    @Override
3501    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3502            Intent intent, String resolvedType, IVoiceInteractionSession session,
3503            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3504            Bundle options, int userId) {
3505        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3506                != PackageManager.PERMISSION_GRANTED) {
3507            String msg = "Permission Denial: startVoiceActivity() from pid="
3508                    + Binder.getCallingPid()
3509                    + ", uid=" + Binder.getCallingUid()
3510                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3511            Slog.w(TAG, msg);
3512            throw new SecurityException(msg);
3513        }
3514        if (session == null || interactor == null) {
3515            throw new NullPointerException("null session or interactor");
3516        }
3517        userId = handleIncomingUser(callingPid, callingUid, userId,
3518                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3519        // TODO: Switch to user app stacks here.
3520        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3521                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3522                null, options, userId, null, null);
3523    }
3524
3525    @Override
3526    public boolean startNextMatchingActivity(IBinder callingActivity,
3527            Intent intent, Bundle options) {
3528        // Refuse possible leaked file descriptors
3529        if (intent != null && intent.hasFileDescriptors() == true) {
3530            throw new IllegalArgumentException("File descriptors passed in Intent");
3531        }
3532
3533        synchronized (this) {
3534            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3535            if (r == null) {
3536                ActivityOptions.abort(options);
3537                return false;
3538            }
3539            if (r.app == null || r.app.thread == null) {
3540                // The caller is not running...  d'oh!
3541                ActivityOptions.abort(options);
3542                return false;
3543            }
3544            intent = new Intent(intent);
3545            // The caller is not allowed to change the data.
3546            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3547            // And we are resetting to find the next component...
3548            intent.setComponent(null);
3549
3550            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3551
3552            ActivityInfo aInfo = null;
3553            try {
3554                List<ResolveInfo> resolves =
3555                    AppGlobals.getPackageManager().queryIntentActivities(
3556                            intent, r.resolvedType,
3557                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3558                            UserHandle.getCallingUserId());
3559
3560                // Look for the original activity in the list...
3561                final int N = resolves != null ? resolves.size() : 0;
3562                for (int i=0; i<N; i++) {
3563                    ResolveInfo rInfo = resolves.get(i);
3564                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3565                            && rInfo.activityInfo.name.equals(r.info.name)) {
3566                        // We found the current one...  the next matching is
3567                        // after it.
3568                        i++;
3569                        if (i<N) {
3570                            aInfo = resolves.get(i).activityInfo;
3571                        }
3572                        if (debug) {
3573                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3574                                    + "/" + r.info.name);
3575                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3576                                    + "/" + aInfo.name);
3577                        }
3578                        break;
3579                    }
3580                }
3581            } catch (RemoteException e) {
3582            }
3583
3584            if (aInfo == null) {
3585                // Nobody who is next!
3586                ActivityOptions.abort(options);
3587                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3588                return false;
3589            }
3590
3591            intent.setComponent(new ComponentName(
3592                    aInfo.applicationInfo.packageName, aInfo.name));
3593            intent.setFlags(intent.getFlags()&~(
3594                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3595                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3596                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3597                    Intent.FLAG_ACTIVITY_NEW_TASK));
3598
3599            // Okay now we need to start the new activity, replacing the
3600            // currently running activity.  This is a little tricky because
3601            // we want to start the new one as if the current one is finished,
3602            // but not finish the current one first so that there is no flicker.
3603            // And thus...
3604            final boolean wasFinishing = r.finishing;
3605            r.finishing = true;
3606
3607            // Propagate reply information over to the new activity.
3608            final ActivityRecord resultTo = r.resultTo;
3609            final String resultWho = r.resultWho;
3610            final int requestCode = r.requestCode;
3611            r.resultTo = null;
3612            if (resultTo != null) {
3613                resultTo.removeResultsLocked(r, resultWho, requestCode);
3614            }
3615
3616            final long origId = Binder.clearCallingIdentity();
3617            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3618                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3619                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3620                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3621            Binder.restoreCallingIdentity(origId);
3622
3623            r.finishing = wasFinishing;
3624            if (res != ActivityManager.START_SUCCESS) {
3625                return false;
3626            }
3627            return true;
3628        }
3629    }
3630
3631    @Override
3632    public final int startActivityFromRecents(int taskId, Bundle options) {
3633        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3634            String msg = "Permission Denial: startActivityFromRecents called without " +
3635                    START_TASKS_FROM_RECENTS;
3636            Slog.w(TAG, msg);
3637            throw new SecurityException(msg);
3638        }
3639        return startActivityFromRecentsInner(taskId, options);
3640    }
3641
3642    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3643        final TaskRecord task;
3644        final int callingUid;
3645        final String callingPackage;
3646        final Intent intent;
3647        final int userId;
3648        synchronized (this) {
3649            task = recentTaskForIdLocked(taskId);
3650            if (task == null) {
3651                throw new IllegalArgumentException("Task " + taskId + " not found.");
3652            }
3653            callingUid = task.mCallingUid;
3654            callingPackage = task.mCallingPackage;
3655            intent = task.intent;
3656            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3657            userId = task.userId;
3658        }
3659        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3660                options, userId, null, task);
3661    }
3662
3663    final int startActivityInPackage(int uid, String callingPackage,
3664            Intent intent, String resolvedType, IBinder resultTo,
3665            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3666            IActivityContainer container, TaskRecord inTask) {
3667
3668        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3669                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3670
3671        // TODO: Switch to user app stacks here.
3672        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3673                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3674                null, null, null, options, userId, container, inTask);
3675        return ret;
3676    }
3677
3678    @Override
3679    public final int startActivities(IApplicationThread caller, String callingPackage,
3680            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3681            int userId) {
3682        enforceNotIsolatedCaller("startActivities");
3683        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3684                false, ALLOW_FULL_ONLY, "startActivity", null);
3685        // TODO: Switch to user app stacks here.
3686        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3687                resolvedTypes, resultTo, options, userId);
3688        return ret;
3689    }
3690
3691    final int startActivitiesInPackage(int uid, String callingPackage,
3692            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3693            Bundle options, int userId) {
3694
3695        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3696                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3697        // TODO: Switch to user app stacks here.
3698        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3699                resultTo, options, userId);
3700        return ret;
3701    }
3702
3703    //explicitly remove thd old information in mRecentTasks when removing existing user.
3704    private void removeRecentTasksForUserLocked(int userId) {
3705        if(userId <= 0) {
3706            Slog.i(TAG, "Can't remove recent task on user " + userId);
3707            return;
3708        }
3709
3710        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3711            TaskRecord tr = mRecentTasks.get(i);
3712            if (tr.userId == userId) {
3713                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3714                        + " when finishing user" + userId);
3715                mRecentTasks.remove(i);
3716                tr.removedFromRecents(mTaskPersister);
3717            }
3718        }
3719
3720        // Remove tasks from persistent storage.
3721        mTaskPersister.wakeup(null, true);
3722    }
3723
3724    // Sort by taskId
3725    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3726        @Override
3727        public int compare(TaskRecord lhs, TaskRecord rhs) {
3728            return rhs.taskId - lhs.taskId;
3729        }
3730    };
3731
3732    // Extract the affiliates of the chain containing mRecentTasks[start].
3733    private int processNextAffiliateChain(int start) {
3734        final TaskRecord startTask = mRecentTasks.get(start);
3735        final int affiliateId = startTask.mAffiliatedTaskId;
3736
3737        // Quick identification of isolated tasks. I.e. those not launched behind.
3738        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3739                startTask.mNextAffiliate == null) {
3740            // There is still a slim chance that there are other tasks that point to this task
3741            // and that the chain is so messed up that this task no longer points to them but
3742            // the gain of this optimization outweighs the risk.
3743            startTask.inRecents = true;
3744            return start + 1;
3745        }
3746
3747        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3748        mTmpRecents.clear();
3749        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3750            final TaskRecord task = mRecentTasks.get(i);
3751            if (task.mAffiliatedTaskId == affiliateId) {
3752                mRecentTasks.remove(i);
3753                mTmpRecents.add(task);
3754            }
3755        }
3756
3757        // Sort them all by taskId. That is the order they were create in and that order will
3758        // always be correct.
3759        Collections.sort(mTmpRecents, mTaskRecordComparator);
3760
3761        // Go through and fix up the linked list.
3762        // The first one is the end of the chain and has no next.
3763        final TaskRecord first = mTmpRecents.get(0);
3764        first.inRecents = true;
3765        if (first.mNextAffiliate != null) {
3766            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3767            first.setNextAffiliate(null);
3768            mTaskPersister.wakeup(first, false);
3769        }
3770        // Everything in the middle is doubly linked from next to prev.
3771        final int tmpSize = mTmpRecents.size();
3772        for (int i = 0; i < tmpSize - 1; ++i) {
3773            final TaskRecord next = mTmpRecents.get(i);
3774            final TaskRecord prev = mTmpRecents.get(i + 1);
3775            if (next.mPrevAffiliate != prev) {
3776                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3777                        " setting prev=" + prev);
3778                next.setPrevAffiliate(prev);
3779                mTaskPersister.wakeup(next, false);
3780            }
3781            if (prev.mNextAffiliate != next) {
3782                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3783                        " setting next=" + next);
3784                prev.setNextAffiliate(next);
3785                mTaskPersister.wakeup(prev, false);
3786            }
3787            prev.inRecents = true;
3788        }
3789        // The last one is the beginning of the list and has no prev.
3790        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3791        if (last.mPrevAffiliate != null) {
3792            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3793            last.setPrevAffiliate(null);
3794            mTaskPersister.wakeup(last, false);
3795        }
3796
3797        // Insert the group back into mRecentTasks at start.
3798        mRecentTasks.addAll(start, mTmpRecents);
3799
3800        // Let the caller know where we left off.
3801        return start + tmpSize;
3802    }
3803
3804    /**
3805     * Update the recent tasks lists: make sure tasks should still be here (their
3806     * applications / activities still exist), update their availability, fixup ordering
3807     * of affiliations.
3808     */
3809    void cleanupRecentTasksLocked(int userId) {
3810        if (mRecentTasks == null) {
3811            // Happens when called from the packagemanager broadcast before boot.
3812            return;
3813        }
3814
3815        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3816        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3817        final IPackageManager pm = AppGlobals.getPackageManager();
3818        final ActivityInfo dummyAct = new ActivityInfo();
3819        final ApplicationInfo dummyApp = new ApplicationInfo();
3820
3821        int N = mRecentTasks.size();
3822
3823        int[] users = userId == UserHandle.USER_ALL
3824                ? getUsersLocked() : new int[] { userId };
3825        for (int user : users) {
3826            for (int i = 0; i < N; i++) {
3827                TaskRecord task = mRecentTasks.get(i);
3828                if (task.userId != user) {
3829                    // Only look at tasks for the user ID of interest.
3830                    continue;
3831                }
3832                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3833                    // This situation is broken, and we should just get rid of it now.
3834                    mRecentTasks.remove(i);
3835                    task.removedFromRecents(mTaskPersister);
3836                    i--;
3837                    N--;
3838                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3839                    continue;
3840                }
3841                // Check whether this activity is currently available.
3842                if (task.realActivity != null) {
3843                    ActivityInfo ai = availActCache.get(task.realActivity);
3844                    if (ai == null) {
3845                        try {
3846                            ai = pm.getActivityInfo(task.realActivity,
3847                                    PackageManager.GET_UNINSTALLED_PACKAGES
3848                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3849                        } catch (RemoteException e) {
3850                            // Will never happen.
3851                            continue;
3852                        }
3853                        if (ai == null) {
3854                            ai = dummyAct;
3855                        }
3856                        availActCache.put(task.realActivity, ai);
3857                    }
3858                    if (ai == dummyAct) {
3859                        // This could be either because the activity no longer exists, or the
3860                        // app is temporarily gone.  For the former we want to remove the recents
3861                        // entry; for the latter we want to mark it as unavailable.
3862                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3863                        if (app == null) {
3864                            try {
3865                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3866                                        PackageManager.GET_UNINSTALLED_PACKAGES
3867                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3868                            } catch (RemoteException e) {
3869                                // Will never happen.
3870                                continue;
3871                            }
3872                            if (app == null) {
3873                                app = dummyApp;
3874                            }
3875                            availAppCache.put(task.realActivity.getPackageName(), app);
3876                        }
3877                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3878                            // Doesn't exist any more!  Good-bye.
3879                            mRecentTasks.remove(i);
3880                            task.removedFromRecents(mTaskPersister);
3881                            i--;
3882                            N--;
3883                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3884                            continue;
3885                        } else {
3886                            // Otherwise just not available for now.
3887                            if (task.isAvailable) {
3888                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3889                                        + task);
3890                            }
3891                            task.isAvailable = false;
3892                        }
3893                    } else {
3894                        if (!ai.enabled || !ai.applicationInfo.enabled
3895                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3896                            if (task.isAvailable) {
3897                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3898                                        + task + " (enabled=" + ai.enabled + "/"
3899                                        + ai.applicationInfo.enabled +  " flags="
3900                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3901                            }
3902                            task.isAvailable = false;
3903                        } else {
3904                            if (!task.isAvailable) {
3905                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3906                                        + task);
3907                            }
3908                            task.isAvailable = true;
3909                        }
3910                    }
3911                }
3912            }
3913        }
3914
3915        // Verify the affiliate chain for each task.
3916        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
3917        }
3918
3919        mTmpRecents.clear();
3920        // mRecentTasks is now in sorted, affiliated order.
3921    }
3922
3923    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3924        int N = mRecentTasks.size();
3925        TaskRecord top = task;
3926        int topIndex = taskIndex;
3927        while (top.mNextAffiliate != null && topIndex > 0) {
3928            top = top.mNextAffiliate;
3929            topIndex--;
3930        }
3931        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3932                + topIndex + " from intial " + taskIndex);
3933        // Find the end of the chain, doing a sanity check along the way.
3934        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3935        int endIndex = topIndex;
3936        TaskRecord prev = top;
3937        while (endIndex < N) {
3938            TaskRecord cur = mRecentTasks.get(endIndex);
3939            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3940                    + endIndex + " " + cur);
3941            if (cur == top) {
3942                // Verify start of the chain.
3943                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3944                    Slog.wtf(TAG, "Bad chain @" + endIndex
3945                            + ": first task has next affiliate: " + prev);
3946                    sane = false;
3947                    break;
3948                }
3949            } else {
3950                // Verify middle of the chain's next points back to the one before.
3951                if (cur.mNextAffiliate != prev
3952                        || cur.mNextAffiliateTaskId != prev.taskId) {
3953                    Slog.wtf(TAG, "Bad chain @" + endIndex
3954                            + ": middle task " + cur + " @" + endIndex
3955                            + " has bad next affiliate "
3956                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3957                            + ", expected " + prev);
3958                    sane = false;
3959                    break;
3960                }
3961            }
3962            if (cur.mPrevAffiliateTaskId == -1) {
3963                // Chain ends here.
3964                if (cur.mPrevAffiliate != null) {
3965                    Slog.wtf(TAG, "Bad chain @" + endIndex
3966                            + ": last task " + cur + " has previous affiliate "
3967                            + cur.mPrevAffiliate);
3968                    sane = false;
3969                }
3970                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
3971                break;
3972            } else {
3973                // Verify middle of the chain's prev points to a valid item.
3974                if (cur.mPrevAffiliate == null) {
3975                    Slog.wtf(TAG, "Bad chain @" + endIndex
3976                            + ": task " + cur + " has previous affiliate "
3977                            + cur.mPrevAffiliate + " but should be id "
3978                            + cur.mPrevAffiliate);
3979                    sane = false;
3980                    break;
3981                }
3982            }
3983            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
3984                Slog.wtf(TAG, "Bad chain @" + endIndex
3985                        + ": task " + cur + " has affiliated id "
3986                        + cur.mAffiliatedTaskId + " but should be "
3987                        + task.mAffiliatedTaskId);
3988                sane = false;
3989                break;
3990            }
3991            prev = cur;
3992            endIndex++;
3993            if (endIndex >= N) {
3994                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
3995                        + ": last task " + prev);
3996                sane = false;
3997                break;
3998            }
3999        }
4000        if (sane) {
4001            if (endIndex < taskIndex) {
4002                Slog.wtf(TAG, "Bad chain @" + endIndex
4003                        + ": did not extend to task " + task + " @" + taskIndex);
4004                sane = false;
4005            }
4006        }
4007        if (sane) {
4008            // All looks good, we can just move all of the affiliated tasks
4009            // to the top.
4010            for (int i=topIndex; i<=endIndex; i++) {
4011                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4012                        + " from " + i + " to " + (i-topIndex));
4013                TaskRecord cur = mRecentTasks.remove(i);
4014                mRecentTasks.add(i-topIndex, cur);
4015            }
4016            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4017                    + " to " + endIndex);
4018            return true;
4019        }
4020
4021        // Whoops, couldn't do it.
4022        return false;
4023    }
4024
4025    final void addRecentTaskLocked(TaskRecord task) {
4026        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4027                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4028
4029        int N = mRecentTasks.size();
4030        // Quick case: check if the top-most recent task is the same.
4031        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4032            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4033            return;
4034        }
4035        // Another quick case: check if this is part of a set of affiliated
4036        // tasks that are at the top.
4037        if (isAffiliated && N > 0 && task.inRecents
4038                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4039            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4040                    + " at top when adding " + task);
4041            return;
4042        }
4043        // Another quick case: never add voice sessions.
4044        if (task.voiceSession != null) {
4045            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4046            return;
4047        }
4048
4049        boolean needAffiliationFix = false;
4050
4051        // Slightly less quick case: the task is already in recents, so all we need
4052        // to do is move it.
4053        if (task.inRecents) {
4054            int taskIndex = mRecentTasks.indexOf(task);
4055            if (taskIndex >= 0) {
4056                if (!isAffiliated) {
4057                    // Simple case: this is not an affiliated task, so we just move it to the front.
4058                    mRecentTasks.remove(taskIndex);
4059                    mRecentTasks.add(0, task);
4060                    notifyTaskPersisterLocked(task, false);
4061                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4062                            + " from " + taskIndex);
4063                    return;
4064                } else {
4065                    // More complicated: need to keep all affiliated tasks together.
4066                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4067                        // All went well.
4068                        return;
4069                    }
4070
4071                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4072                    // everything and then go through our general path of adding a new task.
4073                    needAffiliationFix = true;
4074                }
4075            } else {
4076                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4077                needAffiliationFix = true;
4078            }
4079        }
4080
4081        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4082        trimRecentsForTask(task, true);
4083
4084        N = mRecentTasks.size();
4085        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4086            final TaskRecord tr = mRecentTasks.remove(N - 1);
4087            tr.removedFromRecents(mTaskPersister);
4088            N--;
4089        }
4090        task.inRecents = true;
4091        if (!isAffiliated || needAffiliationFix) {
4092            // If this is a simple non-affiliated task, or we had some failure trying to
4093            // handle it as part of an affilated task, then just place it at the top.
4094            mRecentTasks.add(0, task);
4095        } else if (isAffiliated) {
4096            // If this is a new affiliated task, then move all of the affiliated tasks
4097            // to the front and insert this new one.
4098            TaskRecord other = task.mNextAffiliate;
4099            if (other == null) {
4100                other = task.mPrevAffiliate;
4101            }
4102            if (other != null) {
4103                int otherIndex = mRecentTasks.indexOf(other);
4104                if (otherIndex >= 0) {
4105                    // Insert new task at appropriate location.
4106                    int taskIndex;
4107                    if (other == task.mNextAffiliate) {
4108                        // We found the index of our next affiliation, which is who is
4109                        // before us in the list, so add after that point.
4110                        taskIndex = otherIndex+1;
4111                    } else {
4112                        // We found the index of our previous affiliation, which is who is
4113                        // after us in the list, so add at their position.
4114                        taskIndex = otherIndex;
4115                    }
4116                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4117                            + taskIndex + ": " + task);
4118                    mRecentTasks.add(taskIndex, task);
4119
4120                    // Now move everything to the front.
4121                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4122                        // All went well.
4123                        return;
4124                    }
4125
4126                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4127                    // everything and then go through our general path of adding a new task.
4128                    needAffiliationFix = true;
4129                } else {
4130                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4131                            + other);
4132                    needAffiliationFix = true;
4133                }
4134            } else {
4135                if (DEBUG_RECENTS) Slog.d(TAG,
4136                        "addRecent: adding affiliated task without next/prev:" + task);
4137                needAffiliationFix = true;
4138            }
4139        }
4140        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4141
4142        if (needAffiliationFix) {
4143            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4144            cleanupRecentTasksLocked(task.userId);
4145        }
4146    }
4147
4148    /**
4149     * If needed, remove oldest existing entries in recents that are for the same kind
4150     * of task as the given one.
4151     */
4152    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4153        int N = mRecentTasks.size();
4154        final Intent intent = task.intent;
4155        final boolean document = intent != null && intent.isDocument();
4156
4157        int maxRecents = task.maxRecents - 1;
4158        for (int i=0; i<N; i++) {
4159            final TaskRecord tr = mRecentTasks.get(i);
4160            if (task != tr) {
4161                if (task.userId != tr.userId) {
4162                    continue;
4163                }
4164                if (i > MAX_RECENT_BITMAPS) {
4165                    tr.freeLastThumbnail();
4166                }
4167                final Intent trIntent = tr.intent;
4168                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4169                    (intent == null || !intent.filterEquals(trIntent))) {
4170                    continue;
4171                }
4172                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4173                if (document && trIsDocument) {
4174                    // These are the same document activity (not necessarily the same doc).
4175                    if (maxRecents > 0) {
4176                        --maxRecents;
4177                        continue;
4178                    }
4179                    // Hit the maximum number of documents for this task. Fall through
4180                    // and remove this document from recents.
4181                } else if (document || trIsDocument) {
4182                    // Only one of these is a document. Not the droid we're looking for.
4183                    continue;
4184                }
4185            }
4186
4187            if (!doTrim) {
4188                // If the caller is not actually asking for a trim, just tell them we reached
4189                // a point where the trim would happen.
4190                return i;
4191            }
4192
4193            // Either task and tr are the same or, their affinities match or their intents match
4194            // and neither of them is a document, or they are documents using the same activity
4195            // and their maxRecents has been reached.
4196            tr.disposeThumbnail();
4197            mRecentTasks.remove(i);
4198            if (task != tr) {
4199                tr.removedFromRecents(mTaskPersister);
4200            }
4201            i--;
4202            N--;
4203            if (task.intent == null) {
4204                // If the new recent task we are adding is not fully
4205                // specified, then replace it with the existing recent task.
4206                task = tr;
4207            }
4208            notifyTaskPersisterLocked(tr, false);
4209        }
4210
4211        return -1;
4212    }
4213
4214    @Override
4215    public void reportActivityFullyDrawn(IBinder token) {
4216        synchronized (this) {
4217            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4218            if (r == null) {
4219                return;
4220            }
4221            r.reportFullyDrawnLocked();
4222        }
4223    }
4224
4225    @Override
4226    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4227        synchronized (this) {
4228            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4229            if (r == null) {
4230                return;
4231            }
4232            final long origId = Binder.clearCallingIdentity();
4233            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4234            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4235                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4236            if (config != null) {
4237                r.frozenBeforeDestroy = true;
4238                if (!updateConfigurationLocked(config, r, false, false)) {
4239                    mStackSupervisor.resumeTopActivitiesLocked();
4240                }
4241            }
4242            Binder.restoreCallingIdentity(origId);
4243        }
4244    }
4245
4246    @Override
4247    public int getRequestedOrientation(IBinder token) {
4248        synchronized (this) {
4249            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4250            if (r == null) {
4251                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4252            }
4253            return mWindowManager.getAppOrientation(r.appToken);
4254        }
4255    }
4256
4257    /**
4258     * This is the internal entry point for handling Activity.finish().
4259     *
4260     * @param token The Binder token referencing the Activity we want to finish.
4261     * @param resultCode Result code, if any, from this Activity.
4262     * @param resultData Result data (Intent), if any, from this Activity.
4263     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4264     *            the root Activity in the task.
4265     *
4266     * @return Returns true if the activity successfully finished, or false if it is still running.
4267     */
4268    @Override
4269    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4270            boolean finishTask) {
4271        // Refuse possible leaked file descriptors
4272        if (resultData != null && resultData.hasFileDescriptors() == true) {
4273            throw new IllegalArgumentException("File descriptors passed in Intent");
4274        }
4275
4276        synchronized(this) {
4277            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4278            if (r == null) {
4279                return true;
4280            }
4281            // Keep track of the root activity of the task before we finish it
4282            TaskRecord tr = r.task;
4283            ActivityRecord rootR = tr.getRootActivity();
4284            // Do not allow task to finish in Lock Task mode.
4285            if (tr == mStackSupervisor.mLockTaskModeTask) {
4286                if (rootR == r) {
4287                    mStackSupervisor.showLockTaskToast();
4288                    return false;
4289                }
4290            }
4291            if (mController != null) {
4292                // Find the first activity that is not finishing.
4293                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4294                if (next != null) {
4295                    // ask watcher if this is allowed
4296                    boolean resumeOK = true;
4297                    try {
4298                        resumeOK = mController.activityResuming(next.packageName);
4299                    } catch (RemoteException e) {
4300                        mController = null;
4301                        Watchdog.getInstance().setActivityController(null);
4302                    }
4303
4304                    if (!resumeOK) {
4305                        return false;
4306                    }
4307                }
4308            }
4309            final long origId = Binder.clearCallingIdentity();
4310            try {
4311                boolean res;
4312                if (finishTask && r == rootR) {
4313                    // If requested, remove the task that is associated to this activity only if it
4314                    // was the root activity in the task. The result code and data is ignored
4315                    // because we don't support returning them across task boundaries.
4316                    res = removeTaskByIdLocked(tr.taskId, false);
4317                } else {
4318                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4319                            resultData, "app-request", true);
4320                }
4321                return res;
4322            } finally {
4323                Binder.restoreCallingIdentity(origId);
4324            }
4325        }
4326    }
4327
4328    @Override
4329    public final void finishHeavyWeightApp() {
4330        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4331                != PackageManager.PERMISSION_GRANTED) {
4332            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4333                    + Binder.getCallingPid()
4334                    + ", uid=" + Binder.getCallingUid()
4335                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4336            Slog.w(TAG, msg);
4337            throw new SecurityException(msg);
4338        }
4339
4340        synchronized(this) {
4341            if (mHeavyWeightProcess == null) {
4342                return;
4343            }
4344
4345            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4346                    mHeavyWeightProcess.activities);
4347            for (int i=0; i<activities.size(); i++) {
4348                ActivityRecord r = activities.get(i);
4349                if (!r.finishing) {
4350                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4351                            null, "finish-heavy", true);
4352                }
4353            }
4354
4355            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4356                    mHeavyWeightProcess.userId, 0));
4357            mHeavyWeightProcess = null;
4358        }
4359    }
4360
4361    @Override
4362    public void crashApplication(int uid, int initialPid, String packageName,
4363            String message) {
4364        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4365                != PackageManager.PERMISSION_GRANTED) {
4366            String msg = "Permission Denial: crashApplication() from pid="
4367                    + Binder.getCallingPid()
4368                    + ", uid=" + Binder.getCallingUid()
4369                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4370            Slog.w(TAG, msg);
4371            throw new SecurityException(msg);
4372        }
4373
4374        synchronized(this) {
4375            ProcessRecord proc = null;
4376
4377            // Figure out which process to kill.  We don't trust that initialPid
4378            // still has any relation to current pids, so must scan through the
4379            // list.
4380            synchronized (mPidsSelfLocked) {
4381                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4382                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4383                    if (p.uid != uid) {
4384                        continue;
4385                    }
4386                    if (p.pid == initialPid) {
4387                        proc = p;
4388                        break;
4389                    }
4390                    if (p.pkgList.containsKey(packageName)) {
4391                        proc = p;
4392                    }
4393                }
4394            }
4395
4396            if (proc == null) {
4397                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4398                        + " initialPid=" + initialPid
4399                        + " packageName=" + packageName);
4400                return;
4401            }
4402
4403            if (proc.thread != null) {
4404                if (proc.pid == Process.myPid()) {
4405                    Log.w(TAG, "crashApplication: trying to crash self!");
4406                    return;
4407                }
4408                long ident = Binder.clearCallingIdentity();
4409                try {
4410                    proc.thread.scheduleCrash(message);
4411                } catch (RemoteException e) {
4412                }
4413                Binder.restoreCallingIdentity(ident);
4414            }
4415        }
4416    }
4417
4418    @Override
4419    public final void finishSubActivity(IBinder token, String resultWho,
4420            int requestCode) {
4421        synchronized(this) {
4422            final long origId = Binder.clearCallingIdentity();
4423            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4424            if (r != null) {
4425                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4426            }
4427            Binder.restoreCallingIdentity(origId);
4428        }
4429    }
4430
4431    @Override
4432    public boolean finishActivityAffinity(IBinder token) {
4433        synchronized(this) {
4434            final long origId = Binder.clearCallingIdentity();
4435            try {
4436                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4437
4438                ActivityRecord rootR = r.task.getRootActivity();
4439                // Do not allow task to finish in Lock Task mode.
4440                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4441                    if (rootR == r) {
4442                        mStackSupervisor.showLockTaskToast();
4443                        return false;
4444                    }
4445                }
4446                boolean res = false;
4447                if (r != null) {
4448                    res = r.task.stack.finishActivityAffinityLocked(r);
4449                }
4450                return res;
4451            } finally {
4452                Binder.restoreCallingIdentity(origId);
4453            }
4454        }
4455    }
4456
4457    @Override
4458    public void finishVoiceTask(IVoiceInteractionSession session) {
4459        synchronized(this) {
4460            final long origId = Binder.clearCallingIdentity();
4461            try {
4462                mStackSupervisor.finishVoiceTask(session);
4463            } finally {
4464                Binder.restoreCallingIdentity(origId);
4465            }
4466        }
4467
4468    }
4469
4470    @Override
4471    public boolean releaseActivityInstance(IBinder token) {
4472        synchronized(this) {
4473            final long origId = Binder.clearCallingIdentity();
4474            try {
4475                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4476                if (r.task == null || r.task.stack == null) {
4477                    return false;
4478                }
4479                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4480            } finally {
4481                Binder.restoreCallingIdentity(origId);
4482            }
4483        }
4484    }
4485
4486    @Override
4487    public void releaseSomeActivities(IApplicationThread appInt) {
4488        synchronized(this) {
4489            final long origId = Binder.clearCallingIdentity();
4490            try {
4491                ProcessRecord app = getRecordForAppLocked(appInt);
4492                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4493            } finally {
4494                Binder.restoreCallingIdentity(origId);
4495            }
4496        }
4497    }
4498
4499    @Override
4500    public boolean willActivityBeVisible(IBinder token) {
4501        synchronized(this) {
4502            ActivityStack stack = ActivityRecord.getStackLocked(token);
4503            if (stack != null) {
4504                return stack.willActivityBeVisibleLocked(token);
4505            }
4506            return false;
4507        }
4508    }
4509
4510    @Override
4511    public void overridePendingTransition(IBinder token, String packageName,
4512            int enterAnim, int exitAnim) {
4513        synchronized(this) {
4514            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4515            if (self == null) {
4516                return;
4517            }
4518
4519            final long origId = Binder.clearCallingIdentity();
4520
4521            if (self.state == ActivityState.RESUMED
4522                    || self.state == ActivityState.PAUSING) {
4523                mWindowManager.overridePendingAppTransition(packageName,
4524                        enterAnim, exitAnim, null);
4525            }
4526
4527            Binder.restoreCallingIdentity(origId);
4528        }
4529    }
4530
4531    /**
4532     * Main function for removing an existing process from the activity manager
4533     * as a result of that process going away.  Clears out all connections
4534     * to the process.
4535     */
4536    private final void handleAppDiedLocked(ProcessRecord app,
4537            boolean restarting, boolean allowRestart) {
4538        int pid = app.pid;
4539        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4540        if (!kept && !restarting) {
4541            removeLruProcessLocked(app);
4542            if (pid > 0) {
4543                ProcessList.remove(pid);
4544            }
4545        }
4546
4547        if (mProfileProc == app) {
4548            clearProfilerLocked();
4549        }
4550
4551        // Remove this application's activities from active lists.
4552        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4553
4554        app.activities.clear();
4555
4556        if (app.instrumentationClass != null) {
4557            Slog.w(TAG, "Crash of app " + app.processName
4558                  + " running instrumentation " + app.instrumentationClass);
4559            Bundle info = new Bundle();
4560            info.putString("shortMsg", "Process crashed.");
4561            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4562        }
4563
4564        if (!restarting) {
4565            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4566                // If there was nothing to resume, and we are not already
4567                // restarting this process, but there is a visible activity that
4568                // is hosted by the process...  then make sure all visible
4569                // activities are running, taking care of restarting this
4570                // process.
4571                if (hasVisibleActivities) {
4572                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4573                }
4574            }
4575        }
4576    }
4577
4578    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4579        IBinder threadBinder = thread.asBinder();
4580        // Find the application record.
4581        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4582            ProcessRecord rec = mLruProcesses.get(i);
4583            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4584                return i;
4585            }
4586        }
4587        return -1;
4588    }
4589
4590    final ProcessRecord getRecordForAppLocked(
4591            IApplicationThread thread) {
4592        if (thread == null) {
4593            return null;
4594        }
4595
4596        int appIndex = getLRURecordIndexForAppLocked(thread);
4597        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4598    }
4599
4600    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4601        // If there are no longer any background processes running,
4602        // and the app that died was not running instrumentation,
4603        // then tell everyone we are now low on memory.
4604        boolean haveBg = false;
4605        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4606            ProcessRecord rec = mLruProcesses.get(i);
4607            if (rec.thread != null
4608                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4609                haveBg = true;
4610                break;
4611            }
4612        }
4613
4614        if (!haveBg) {
4615            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4616            if (doReport) {
4617                long now = SystemClock.uptimeMillis();
4618                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4619                    doReport = false;
4620                } else {
4621                    mLastMemUsageReportTime = now;
4622                }
4623            }
4624            final ArrayList<ProcessMemInfo> memInfos
4625                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4626            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4627            long now = SystemClock.uptimeMillis();
4628            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4629                ProcessRecord rec = mLruProcesses.get(i);
4630                if (rec == dyingProc || rec.thread == null) {
4631                    continue;
4632                }
4633                if (doReport) {
4634                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4635                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4636                }
4637                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4638                    // The low memory report is overriding any current
4639                    // state for a GC request.  Make sure to do
4640                    // heavy/important/visible/foreground processes first.
4641                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4642                        rec.lastRequestedGc = 0;
4643                    } else {
4644                        rec.lastRequestedGc = rec.lastLowMemory;
4645                    }
4646                    rec.reportLowMemory = true;
4647                    rec.lastLowMemory = now;
4648                    mProcessesToGc.remove(rec);
4649                    addProcessToGcListLocked(rec);
4650                }
4651            }
4652            if (doReport) {
4653                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4654                mHandler.sendMessage(msg);
4655            }
4656            scheduleAppGcsLocked();
4657        }
4658    }
4659
4660    final void appDiedLocked(ProcessRecord app) {
4661       appDiedLocked(app, app.pid, app.thread);
4662    }
4663
4664    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4665        // First check if this ProcessRecord is actually active for the pid.
4666        synchronized (mPidsSelfLocked) {
4667            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4668            if (curProc != app) {
4669                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4670                return;
4671            }
4672        }
4673
4674        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4675        synchronized (stats) {
4676            stats.noteProcessDiedLocked(app.info.uid, pid);
4677        }
4678
4679        Process.killProcessQuiet(pid);
4680        Process.killProcessGroup(app.info.uid, pid);
4681        app.killed = true;
4682
4683        // Clean up already done if the process has been re-started.
4684        if (app.pid == pid && app.thread != null &&
4685                app.thread.asBinder() == thread.asBinder()) {
4686            boolean doLowMem = app.instrumentationClass == null;
4687            boolean doOomAdj = doLowMem;
4688            if (!app.killedByAm) {
4689                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4690                        + ") has died");
4691                mAllowLowerMemLevel = true;
4692            } else {
4693                // Note that we always want to do oom adj to update our state with the
4694                // new number of procs.
4695                mAllowLowerMemLevel = false;
4696                doLowMem = false;
4697            }
4698            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4699            if (DEBUG_CLEANUP) Slog.v(
4700                TAG, "Dying app: " + app + ", pid: " + pid
4701                + ", thread: " + thread.asBinder());
4702            handleAppDiedLocked(app, false, true);
4703
4704            if (doOomAdj) {
4705                updateOomAdjLocked();
4706            }
4707            if (doLowMem) {
4708                doLowMemReportIfNeededLocked(app);
4709            }
4710        } else if (app.pid != pid) {
4711            // A new process has already been started.
4712            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4713                    + ") has died and restarted (pid " + app.pid + ").");
4714            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4715        } else if (DEBUG_PROCESSES) {
4716            Slog.d(TAG, "Received spurious death notification for thread "
4717                    + thread.asBinder());
4718        }
4719    }
4720
4721    /**
4722     * If a stack trace dump file is configured, dump process stack traces.
4723     * @param clearTraces causes the dump file to be erased prior to the new
4724     *    traces being written, if true; when false, the new traces will be
4725     *    appended to any existing file content.
4726     * @param firstPids of dalvik VM processes to dump stack traces for first
4727     * @param lastPids of dalvik VM processes to dump stack traces for last
4728     * @param nativeProcs optional list of native process names to dump stack crawls
4729     * @return file containing stack traces, or null if no dump file is configured
4730     */
4731    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4732            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4733        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4734        if (tracesPath == null || tracesPath.length() == 0) {
4735            return null;
4736        }
4737
4738        File tracesFile = new File(tracesPath);
4739        try {
4740            File tracesDir = tracesFile.getParentFile();
4741            if (!tracesDir.exists()) {
4742                tracesDir.mkdirs();
4743                if (!SELinux.restorecon(tracesDir)) {
4744                    return null;
4745                }
4746            }
4747            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4748
4749            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4750            tracesFile.createNewFile();
4751            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4752        } catch (IOException e) {
4753            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4754            return null;
4755        }
4756
4757        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4758        return tracesFile;
4759    }
4760
4761    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4762            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4763        // Use a FileObserver to detect when traces finish writing.
4764        // The order of traces is considered important to maintain for legibility.
4765        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4766            @Override
4767            public synchronized void onEvent(int event, String path) { notify(); }
4768        };
4769
4770        try {
4771            observer.startWatching();
4772
4773            // First collect all of the stacks of the most important pids.
4774            if (firstPids != null) {
4775                try {
4776                    int num = firstPids.size();
4777                    for (int i = 0; i < num; i++) {
4778                        synchronized (observer) {
4779                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4780                            observer.wait(200);  // Wait for write-close, give up after 200msec
4781                        }
4782                    }
4783                } catch (InterruptedException e) {
4784                    Slog.wtf(TAG, e);
4785                }
4786            }
4787
4788            // Next collect the stacks of the native pids
4789            if (nativeProcs != null) {
4790                int[] pids = Process.getPidsForCommands(nativeProcs);
4791                if (pids != null) {
4792                    for (int pid : pids) {
4793                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4794                    }
4795                }
4796            }
4797
4798            // Lastly, measure CPU usage.
4799            if (processCpuTracker != null) {
4800                processCpuTracker.init();
4801                System.gc();
4802                processCpuTracker.update();
4803                try {
4804                    synchronized (processCpuTracker) {
4805                        processCpuTracker.wait(500); // measure over 1/2 second.
4806                    }
4807                } catch (InterruptedException e) {
4808                }
4809                processCpuTracker.update();
4810
4811                // We'll take the stack crawls of just the top apps using CPU.
4812                final int N = processCpuTracker.countWorkingStats();
4813                int numProcs = 0;
4814                for (int i=0; i<N && numProcs<5; i++) {
4815                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4816                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4817                        numProcs++;
4818                        try {
4819                            synchronized (observer) {
4820                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4821                                observer.wait(200);  // Wait for write-close, give up after 200msec
4822                            }
4823                        } catch (InterruptedException e) {
4824                            Slog.wtf(TAG, e);
4825                        }
4826
4827                    }
4828                }
4829            }
4830        } finally {
4831            observer.stopWatching();
4832        }
4833    }
4834
4835    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4836        if (true || IS_USER_BUILD) {
4837            return;
4838        }
4839        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4840        if (tracesPath == null || tracesPath.length() == 0) {
4841            return;
4842        }
4843
4844        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4845        StrictMode.allowThreadDiskWrites();
4846        try {
4847            final File tracesFile = new File(tracesPath);
4848            final File tracesDir = tracesFile.getParentFile();
4849            final File tracesTmp = new File(tracesDir, "__tmp__");
4850            try {
4851                if (!tracesDir.exists()) {
4852                    tracesDir.mkdirs();
4853                    if (!SELinux.restorecon(tracesDir.getPath())) {
4854                        return;
4855                    }
4856                }
4857                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4858
4859                if (tracesFile.exists()) {
4860                    tracesTmp.delete();
4861                    tracesFile.renameTo(tracesTmp);
4862                }
4863                StringBuilder sb = new StringBuilder();
4864                Time tobj = new Time();
4865                tobj.set(System.currentTimeMillis());
4866                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4867                sb.append(": ");
4868                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4869                sb.append(" since ");
4870                sb.append(msg);
4871                FileOutputStream fos = new FileOutputStream(tracesFile);
4872                fos.write(sb.toString().getBytes());
4873                if (app == null) {
4874                    fos.write("\n*** No application process!".getBytes());
4875                }
4876                fos.close();
4877                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4878            } catch (IOException e) {
4879                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4880                return;
4881            }
4882
4883            if (app != null) {
4884                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4885                firstPids.add(app.pid);
4886                dumpStackTraces(tracesPath, firstPids, null, null, null);
4887            }
4888
4889            File lastTracesFile = null;
4890            File curTracesFile = null;
4891            for (int i=9; i>=0; i--) {
4892                String name = String.format(Locale.US, "slow%02d.txt", i);
4893                curTracesFile = new File(tracesDir, name);
4894                if (curTracesFile.exists()) {
4895                    if (lastTracesFile != null) {
4896                        curTracesFile.renameTo(lastTracesFile);
4897                    } else {
4898                        curTracesFile.delete();
4899                    }
4900                }
4901                lastTracesFile = curTracesFile;
4902            }
4903            tracesFile.renameTo(curTracesFile);
4904            if (tracesTmp.exists()) {
4905                tracesTmp.renameTo(tracesFile);
4906            }
4907        } finally {
4908            StrictMode.setThreadPolicy(oldPolicy);
4909        }
4910    }
4911
4912    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4913            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4914        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4915        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4916
4917        if (mController != null) {
4918            try {
4919                // 0 == continue, -1 = kill process immediately
4920                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4921                if (res < 0 && app.pid != MY_PID) {
4922                    app.kill("anr", true);
4923                }
4924            } catch (RemoteException e) {
4925                mController = null;
4926                Watchdog.getInstance().setActivityController(null);
4927            }
4928        }
4929
4930        long anrTime = SystemClock.uptimeMillis();
4931        if (MONITOR_CPU_USAGE) {
4932            updateCpuStatsNow();
4933        }
4934
4935        synchronized (this) {
4936            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4937            if (mShuttingDown) {
4938                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4939                return;
4940            } else if (app.notResponding) {
4941                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4942                return;
4943            } else if (app.crashing) {
4944                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4945                return;
4946            }
4947
4948            // In case we come through here for the same app before completing
4949            // this one, mark as anring now so we will bail out.
4950            app.notResponding = true;
4951
4952            // Log the ANR to the event log.
4953            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4954                    app.processName, app.info.flags, annotation);
4955
4956            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4957            firstPids.add(app.pid);
4958
4959            int parentPid = app.pid;
4960            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4961            if (parentPid != app.pid) firstPids.add(parentPid);
4962
4963            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4964
4965            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4966                ProcessRecord r = mLruProcesses.get(i);
4967                if (r != null && r.thread != null) {
4968                    int pid = r.pid;
4969                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4970                        if (r.persistent) {
4971                            firstPids.add(pid);
4972                        } else {
4973                            lastPids.put(pid, Boolean.TRUE);
4974                        }
4975                    }
4976                }
4977            }
4978        }
4979
4980        // Log the ANR to the main log.
4981        StringBuilder info = new StringBuilder();
4982        info.setLength(0);
4983        info.append("ANR in ").append(app.processName);
4984        if (activity != null && activity.shortComponentName != null) {
4985            info.append(" (").append(activity.shortComponentName).append(")");
4986        }
4987        info.append("\n");
4988        info.append("PID: ").append(app.pid).append("\n");
4989        if (annotation != null) {
4990            info.append("Reason: ").append(annotation).append("\n");
4991        }
4992        if (parent != null && parent != activity) {
4993            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4994        }
4995
4996        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4997
4998        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4999                NATIVE_STACKS_OF_INTEREST);
5000
5001        String cpuInfo = null;
5002        if (MONITOR_CPU_USAGE) {
5003            updateCpuStatsNow();
5004            synchronized (mProcessCpuTracker) {
5005                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5006            }
5007            info.append(processCpuTracker.printCurrentLoad());
5008            info.append(cpuInfo);
5009        }
5010
5011        info.append(processCpuTracker.printCurrentState(anrTime));
5012
5013        Slog.e(TAG, info.toString());
5014        if (tracesFile == null) {
5015            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5016            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5017        }
5018
5019        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5020                cpuInfo, tracesFile, null);
5021
5022        if (mController != null) {
5023            try {
5024                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5025                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5026                if (res != 0) {
5027                    if (res < 0 && app.pid != MY_PID) {
5028                        app.kill("anr", true);
5029                    } else {
5030                        synchronized (this) {
5031                            mServices.scheduleServiceTimeoutLocked(app);
5032                        }
5033                    }
5034                    return;
5035                }
5036            } catch (RemoteException e) {
5037                mController = null;
5038                Watchdog.getInstance().setActivityController(null);
5039            }
5040        }
5041
5042        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5043        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5044                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5045
5046        synchronized (this) {
5047            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5048                app.kill("bg anr", true);
5049                return;
5050            }
5051
5052            // Set the app's notResponding state, and look up the errorReportReceiver
5053            makeAppNotRespondingLocked(app,
5054                    activity != null ? activity.shortComponentName : null,
5055                    annotation != null ? "ANR " + annotation : "ANR",
5056                    info.toString());
5057
5058            // Bring up the infamous App Not Responding dialog
5059            Message msg = Message.obtain();
5060            HashMap<String, Object> map = new HashMap<String, Object>();
5061            msg.what = SHOW_NOT_RESPONDING_MSG;
5062            msg.obj = map;
5063            msg.arg1 = aboveSystem ? 1 : 0;
5064            map.put("app", app);
5065            if (activity != null) {
5066                map.put("activity", activity);
5067            }
5068
5069            mHandler.sendMessage(msg);
5070        }
5071    }
5072
5073    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5074        if (!mLaunchWarningShown) {
5075            mLaunchWarningShown = true;
5076            mHandler.post(new Runnable() {
5077                @Override
5078                public void run() {
5079                    synchronized (ActivityManagerService.this) {
5080                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5081                        d.show();
5082                        mHandler.postDelayed(new Runnable() {
5083                            @Override
5084                            public void run() {
5085                                synchronized (ActivityManagerService.this) {
5086                                    d.dismiss();
5087                                    mLaunchWarningShown = false;
5088                                }
5089                            }
5090                        }, 4000);
5091                    }
5092                }
5093            });
5094        }
5095    }
5096
5097    @Override
5098    public boolean clearApplicationUserData(final String packageName,
5099            final IPackageDataObserver observer, int userId) {
5100        enforceNotIsolatedCaller("clearApplicationUserData");
5101        int uid = Binder.getCallingUid();
5102        int pid = Binder.getCallingPid();
5103        userId = handleIncomingUser(pid, uid,
5104                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5105        long callingId = Binder.clearCallingIdentity();
5106        try {
5107            IPackageManager pm = AppGlobals.getPackageManager();
5108            int pkgUid = -1;
5109            synchronized(this) {
5110                try {
5111                    pkgUid = pm.getPackageUid(packageName, userId);
5112                } catch (RemoteException e) {
5113                }
5114                if (pkgUid == -1) {
5115                    Slog.w(TAG, "Invalid packageName: " + packageName);
5116                    if (observer != null) {
5117                        try {
5118                            observer.onRemoveCompleted(packageName, false);
5119                        } catch (RemoteException e) {
5120                            Slog.i(TAG, "Observer no longer exists.");
5121                        }
5122                    }
5123                    return false;
5124                }
5125                if (uid == pkgUid || checkComponentPermission(
5126                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5127                        pid, uid, -1, true)
5128                        == PackageManager.PERMISSION_GRANTED) {
5129                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5130                } else {
5131                    throw new SecurityException("PID " + pid + " does not have permission "
5132                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5133                                    + " of package " + packageName);
5134                }
5135
5136                // Remove all tasks match the cleared application package and user
5137                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5138                    final TaskRecord tr = mRecentTasks.get(i);
5139                    final String taskPackageName =
5140                            tr.getBaseIntent().getComponent().getPackageName();
5141                    if (tr.userId != userId) continue;
5142                    if (!taskPackageName.equals(packageName)) continue;
5143                    removeTaskByIdLocked(tr.taskId, false);
5144                }
5145            }
5146
5147            try {
5148                // Clear application user data
5149                pm.clearApplicationUserData(packageName, observer, userId);
5150
5151                synchronized(this) {
5152                    // Remove all permissions granted from/to this package
5153                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5154                }
5155
5156                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5157                        Uri.fromParts("package", packageName, null));
5158                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5159                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5160                        null, null, 0, null, null, null, false, false, userId);
5161            } catch (RemoteException e) {
5162            }
5163        } finally {
5164            Binder.restoreCallingIdentity(callingId);
5165        }
5166        return true;
5167    }
5168
5169    @Override
5170    public void killBackgroundProcesses(final String packageName, int userId) {
5171        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5172                != PackageManager.PERMISSION_GRANTED &&
5173                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5174                        != PackageManager.PERMISSION_GRANTED) {
5175            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5176                    + Binder.getCallingPid()
5177                    + ", uid=" + Binder.getCallingUid()
5178                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5179            Slog.w(TAG, msg);
5180            throw new SecurityException(msg);
5181        }
5182
5183        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5184                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5185        long callingId = Binder.clearCallingIdentity();
5186        try {
5187            IPackageManager pm = AppGlobals.getPackageManager();
5188            synchronized(this) {
5189                int appId = -1;
5190                try {
5191                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5192                } catch (RemoteException e) {
5193                }
5194                if (appId == -1) {
5195                    Slog.w(TAG, "Invalid packageName: " + packageName);
5196                    return;
5197                }
5198                killPackageProcessesLocked(packageName, appId, userId,
5199                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5200            }
5201        } finally {
5202            Binder.restoreCallingIdentity(callingId);
5203        }
5204    }
5205
5206    @Override
5207    public void killAllBackgroundProcesses() {
5208        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5209                != PackageManager.PERMISSION_GRANTED) {
5210            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5211                    + Binder.getCallingPid()
5212                    + ", uid=" + Binder.getCallingUid()
5213                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5214            Slog.w(TAG, msg);
5215            throw new SecurityException(msg);
5216        }
5217
5218        long callingId = Binder.clearCallingIdentity();
5219        try {
5220            synchronized(this) {
5221                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5222                final int NP = mProcessNames.getMap().size();
5223                for (int ip=0; ip<NP; ip++) {
5224                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5225                    final int NA = apps.size();
5226                    for (int ia=0; ia<NA; ia++) {
5227                        ProcessRecord app = apps.valueAt(ia);
5228                        if (app.persistent) {
5229                            // we don't kill persistent processes
5230                            continue;
5231                        }
5232                        if (app.removed) {
5233                            procs.add(app);
5234                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5235                            app.removed = true;
5236                            procs.add(app);
5237                        }
5238                    }
5239                }
5240
5241                int N = procs.size();
5242                for (int i=0; i<N; i++) {
5243                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5244                }
5245                mAllowLowerMemLevel = true;
5246                updateOomAdjLocked();
5247                doLowMemReportIfNeededLocked(null);
5248            }
5249        } finally {
5250            Binder.restoreCallingIdentity(callingId);
5251        }
5252    }
5253
5254    @Override
5255    public void forceStopPackage(final String packageName, int userId) {
5256        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5257                != PackageManager.PERMISSION_GRANTED) {
5258            String msg = "Permission Denial: forceStopPackage() from pid="
5259                    + Binder.getCallingPid()
5260                    + ", uid=" + Binder.getCallingUid()
5261                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5262            Slog.w(TAG, msg);
5263            throw new SecurityException(msg);
5264        }
5265        final int callingPid = Binder.getCallingPid();
5266        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5267                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5268        long callingId = Binder.clearCallingIdentity();
5269        try {
5270            IPackageManager pm = AppGlobals.getPackageManager();
5271            synchronized(this) {
5272                int[] users = userId == UserHandle.USER_ALL
5273                        ? getUsersLocked() : new int[] { userId };
5274                for (int user : users) {
5275                    int pkgUid = -1;
5276                    try {
5277                        pkgUid = pm.getPackageUid(packageName, user);
5278                    } catch (RemoteException e) {
5279                    }
5280                    if (pkgUid == -1) {
5281                        Slog.w(TAG, "Invalid packageName: " + packageName);
5282                        continue;
5283                    }
5284                    try {
5285                        pm.setPackageStoppedState(packageName, true, user);
5286                    } catch (RemoteException e) {
5287                    } catch (IllegalArgumentException e) {
5288                        Slog.w(TAG, "Failed trying to unstop package "
5289                                + packageName + ": " + e);
5290                    }
5291                    if (isUserRunningLocked(user, false)) {
5292                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5293                    }
5294                }
5295            }
5296        } finally {
5297            Binder.restoreCallingIdentity(callingId);
5298        }
5299    }
5300
5301    @Override
5302    public void addPackageDependency(String packageName) {
5303        synchronized (this) {
5304            int callingPid = Binder.getCallingPid();
5305            if (callingPid == Process.myPid()) {
5306                //  Yeah, um, no.
5307                Slog.w(TAG, "Can't addPackageDependency on system process");
5308                return;
5309            }
5310            ProcessRecord proc;
5311            synchronized (mPidsSelfLocked) {
5312                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5313            }
5314            if (proc != null) {
5315                if (proc.pkgDeps == null) {
5316                    proc.pkgDeps = new ArraySet<String>(1);
5317                }
5318                proc.pkgDeps.add(packageName);
5319            }
5320        }
5321    }
5322
5323    /*
5324     * The pkg name and app id have to be specified.
5325     */
5326    @Override
5327    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5328        if (pkg == null) {
5329            return;
5330        }
5331        // Make sure the uid is valid.
5332        if (appid < 0) {
5333            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5334            return;
5335        }
5336        int callerUid = Binder.getCallingUid();
5337        // Only the system server can kill an application
5338        if (callerUid == Process.SYSTEM_UID) {
5339            // Post an aysnc message to kill the application
5340            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5341            msg.arg1 = appid;
5342            msg.arg2 = 0;
5343            Bundle bundle = new Bundle();
5344            bundle.putString("pkg", pkg);
5345            bundle.putString("reason", reason);
5346            msg.obj = bundle;
5347            mHandler.sendMessage(msg);
5348        } else {
5349            throw new SecurityException(callerUid + " cannot kill pkg: " +
5350                    pkg);
5351        }
5352    }
5353
5354    @Override
5355    public void closeSystemDialogs(String reason) {
5356        enforceNotIsolatedCaller("closeSystemDialogs");
5357
5358        final int pid = Binder.getCallingPid();
5359        final int uid = Binder.getCallingUid();
5360        final long origId = Binder.clearCallingIdentity();
5361        try {
5362            synchronized (this) {
5363                // Only allow this from foreground processes, so that background
5364                // applications can't abuse it to prevent system UI from being shown.
5365                if (uid >= Process.FIRST_APPLICATION_UID) {
5366                    ProcessRecord proc;
5367                    synchronized (mPidsSelfLocked) {
5368                        proc = mPidsSelfLocked.get(pid);
5369                    }
5370                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5371                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5372                                + " from background process " + proc);
5373                        return;
5374                    }
5375                }
5376                closeSystemDialogsLocked(reason);
5377            }
5378        } finally {
5379            Binder.restoreCallingIdentity(origId);
5380        }
5381    }
5382
5383    void closeSystemDialogsLocked(String reason) {
5384        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5385        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5386                | Intent.FLAG_RECEIVER_FOREGROUND);
5387        if (reason != null) {
5388            intent.putExtra("reason", reason);
5389        }
5390        mWindowManager.closeSystemDialogs(reason);
5391
5392        mStackSupervisor.closeSystemDialogsLocked();
5393
5394        broadcastIntentLocked(null, null, intent, null,
5395                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5396                Process.SYSTEM_UID, UserHandle.USER_ALL);
5397    }
5398
5399    @Override
5400    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5401        enforceNotIsolatedCaller("getProcessMemoryInfo");
5402        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5403        for (int i=pids.length-1; i>=0; i--) {
5404            ProcessRecord proc;
5405            int oomAdj;
5406            synchronized (this) {
5407                synchronized (mPidsSelfLocked) {
5408                    proc = mPidsSelfLocked.get(pids[i]);
5409                    oomAdj = proc != null ? proc.setAdj : 0;
5410                }
5411            }
5412            infos[i] = new Debug.MemoryInfo();
5413            Debug.getMemoryInfo(pids[i], infos[i]);
5414            if (proc != null) {
5415                synchronized (this) {
5416                    if (proc.thread != null && proc.setAdj == oomAdj) {
5417                        // Record this for posterity if the process has been stable.
5418                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5419                                infos[i].getTotalUss(), false, proc.pkgList);
5420                    }
5421                }
5422            }
5423        }
5424        return infos;
5425    }
5426
5427    @Override
5428    public long[] getProcessPss(int[] pids) {
5429        enforceNotIsolatedCaller("getProcessPss");
5430        long[] pss = new long[pids.length];
5431        for (int i=pids.length-1; i>=0; i--) {
5432            ProcessRecord proc;
5433            int oomAdj;
5434            synchronized (this) {
5435                synchronized (mPidsSelfLocked) {
5436                    proc = mPidsSelfLocked.get(pids[i]);
5437                    oomAdj = proc != null ? proc.setAdj : 0;
5438                }
5439            }
5440            long[] tmpUss = new long[1];
5441            pss[i] = Debug.getPss(pids[i], tmpUss);
5442            if (proc != null) {
5443                synchronized (this) {
5444                    if (proc.thread != null && proc.setAdj == oomAdj) {
5445                        // Record this for posterity if the process has been stable.
5446                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5447                    }
5448                }
5449            }
5450        }
5451        return pss;
5452    }
5453
5454    @Override
5455    public void killApplicationProcess(String processName, int uid) {
5456        if (processName == null) {
5457            return;
5458        }
5459
5460        int callerUid = Binder.getCallingUid();
5461        // Only the system server can kill an application
5462        if (callerUid == Process.SYSTEM_UID) {
5463            synchronized (this) {
5464                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5465                if (app != null && app.thread != null) {
5466                    try {
5467                        app.thread.scheduleSuicide();
5468                    } catch (RemoteException e) {
5469                        // If the other end already died, then our work here is done.
5470                    }
5471                } else {
5472                    Slog.w(TAG, "Process/uid not found attempting kill of "
5473                            + processName + " / " + uid);
5474                }
5475            }
5476        } else {
5477            throw new SecurityException(callerUid + " cannot kill app process: " +
5478                    processName);
5479        }
5480    }
5481
5482    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5483        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5484                false, true, false, false, UserHandle.getUserId(uid), reason);
5485        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5486                Uri.fromParts("package", packageName, null));
5487        if (!mProcessesReady) {
5488            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5489                    | Intent.FLAG_RECEIVER_FOREGROUND);
5490        }
5491        intent.putExtra(Intent.EXTRA_UID, uid);
5492        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5493        broadcastIntentLocked(null, null, intent,
5494                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5495                false, false,
5496                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5497    }
5498
5499    private void forceStopUserLocked(int userId, String reason) {
5500        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5501        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5502        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5503                | Intent.FLAG_RECEIVER_FOREGROUND);
5504        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5505        broadcastIntentLocked(null, null, intent,
5506                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5507                false, false,
5508                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5509    }
5510
5511    private final boolean killPackageProcessesLocked(String packageName, int appId,
5512            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5513            boolean doit, boolean evenPersistent, String reason) {
5514        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5515
5516        // Remove all processes this package may have touched: all with the
5517        // same UID (except for the system or root user), and all whose name
5518        // matches the package name.
5519        final int NP = mProcessNames.getMap().size();
5520        for (int ip=0; ip<NP; ip++) {
5521            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5522            final int NA = apps.size();
5523            for (int ia=0; ia<NA; ia++) {
5524                ProcessRecord app = apps.valueAt(ia);
5525                if (app.persistent && !evenPersistent) {
5526                    // we don't kill persistent processes
5527                    continue;
5528                }
5529                if (app.removed) {
5530                    if (doit) {
5531                        procs.add(app);
5532                    }
5533                    continue;
5534                }
5535
5536                // Skip process if it doesn't meet our oom adj requirement.
5537                if (app.setAdj < minOomAdj) {
5538                    continue;
5539                }
5540
5541                // If no package is specified, we call all processes under the
5542                // give user id.
5543                if (packageName == null) {
5544                    if (app.userId != userId) {
5545                        continue;
5546                    }
5547                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5548                        continue;
5549                    }
5550                // Package has been specified, we want to hit all processes
5551                // that match it.  We need to qualify this by the processes
5552                // that are running under the specified app and user ID.
5553                } else {
5554                    final boolean isDep = app.pkgDeps != null
5555                            && app.pkgDeps.contains(packageName);
5556                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5557                        continue;
5558                    }
5559                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5560                        continue;
5561                    }
5562                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5563                        continue;
5564                    }
5565                }
5566
5567                // Process has passed all conditions, kill it!
5568                if (!doit) {
5569                    return true;
5570                }
5571                app.removed = true;
5572                procs.add(app);
5573            }
5574        }
5575
5576        int N = procs.size();
5577        for (int i=0; i<N; i++) {
5578            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5579        }
5580        updateOomAdjLocked();
5581        return N > 0;
5582    }
5583
5584    private final boolean forceStopPackageLocked(String name, int appId,
5585            boolean callerWillRestart, boolean purgeCache, boolean doit,
5586            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5587        int i;
5588        int N;
5589
5590        if (userId == UserHandle.USER_ALL && name == null) {
5591            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5592        }
5593
5594        if (appId < 0 && name != null) {
5595            try {
5596                appId = UserHandle.getAppId(
5597                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5598            } catch (RemoteException e) {
5599            }
5600        }
5601
5602        if (doit) {
5603            if (name != null) {
5604                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5605                        + " user=" + userId + ": " + reason);
5606            } else {
5607                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5608            }
5609
5610            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5611            for (int ip=pmap.size()-1; ip>=0; ip--) {
5612                SparseArray<Long> ba = pmap.valueAt(ip);
5613                for (i=ba.size()-1; i>=0; i--) {
5614                    boolean remove = false;
5615                    final int entUid = ba.keyAt(i);
5616                    if (name != null) {
5617                        if (userId == UserHandle.USER_ALL) {
5618                            if (UserHandle.getAppId(entUid) == appId) {
5619                                remove = true;
5620                            }
5621                        } else {
5622                            if (entUid == UserHandle.getUid(userId, appId)) {
5623                                remove = true;
5624                            }
5625                        }
5626                    } else if (UserHandle.getUserId(entUid) == userId) {
5627                        remove = true;
5628                    }
5629                    if (remove) {
5630                        ba.removeAt(i);
5631                    }
5632                }
5633                if (ba.size() == 0) {
5634                    pmap.removeAt(ip);
5635                }
5636            }
5637        }
5638
5639        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5640                -100, callerWillRestart, true, doit, evenPersistent,
5641                name == null ? ("stop user " + userId) : ("stop " + name));
5642
5643        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5644            if (!doit) {
5645                return true;
5646            }
5647            didSomething = true;
5648        }
5649
5650        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5651            if (!doit) {
5652                return true;
5653            }
5654            didSomething = true;
5655        }
5656
5657        if (name == null) {
5658            // Remove all sticky broadcasts from this user.
5659            mStickyBroadcasts.remove(userId);
5660        }
5661
5662        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5663        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5664                userId, providers)) {
5665            if (!doit) {
5666                return true;
5667            }
5668            didSomething = true;
5669        }
5670        N = providers.size();
5671        for (i=0; i<N; i++) {
5672            removeDyingProviderLocked(null, providers.get(i), true);
5673        }
5674
5675        // Remove transient permissions granted from/to this package/user
5676        removeUriPermissionsForPackageLocked(name, userId, false);
5677
5678        if (name == null || uninstalling) {
5679            // Remove pending intents.  For now we only do this when force
5680            // stopping users, because we have some problems when doing this
5681            // for packages -- app widgets are not currently cleaned up for
5682            // such packages, so they can be left with bad pending intents.
5683            if (mIntentSenderRecords.size() > 0) {
5684                Iterator<WeakReference<PendingIntentRecord>> it
5685                        = mIntentSenderRecords.values().iterator();
5686                while (it.hasNext()) {
5687                    WeakReference<PendingIntentRecord> wpir = it.next();
5688                    if (wpir == null) {
5689                        it.remove();
5690                        continue;
5691                    }
5692                    PendingIntentRecord pir = wpir.get();
5693                    if (pir == null) {
5694                        it.remove();
5695                        continue;
5696                    }
5697                    if (name == null) {
5698                        // Stopping user, remove all objects for the user.
5699                        if (pir.key.userId != userId) {
5700                            // Not the same user, skip it.
5701                            continue;
5702                        }
5703                    } else {
5704                        if (UserHandle.getAppId(pir.uid) != appId) {
5705                            // Different app id, skip it.
5706                            continue;
5707                        }
5708                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5709                            // Different user, skip it.
5710                            continue;
5711                        }
5712                        if (!pir.key.packageName.equals(name)) {
5713                            // Different package, skip it.
5714                            continue;
5715                        }
5716                    }
5717                    if (!doit) {
5718                        return true;
5719                    }
5720                    didSomething = true;
5721                    it.remove();
5722                    pir.canceled = true;
5723                    if (pir.key.activity != null) {
5724                        pir.key.activity.pendingResults.remove(pir.ref);
5725                    }
5726                }
5727            }
5728        }
5729
5730        if (doit) {
5731            if (purgeCache && name != null) {
5732                AttributeCache ac = AttributeCache.instance();
5733                if (ac != null) {
5734                    ac.removePackage(name);
5735                }
5736            }
5737            if (mBooted) {
5738                mStackSupervisor.resumeTopActivitiesLocked();
5739                mStackSupervisor.scheduleIdleLocked();
5740            }
5741        }
5742
5743        return didSomething;
5744    }
5745
5746    private final boolean removeProcessLocked(ProcessRecord app,
5747            boolean callerWillRestart, boolean allowRestart, String reason) {
5748        final String name = app.processName;
5749        final int uid = app.uid;
5750        if (DEBUG_PROCESSES) Slog.d(
5751            TAG, "Force removing proc " + app.toShortString() + " (" + name
5752            + "/" + uid + ")");
5753
5754        mProcessNames.remove(name, uid);
5755        mIsolatedProcesses.remove(app.uid);
5756        if (mHeavyWeightProcess == app) {
5757            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5758                    mHeavyWeightProcess.userId, 0));
5759            mHeavyWeightProcess = null;
5760        }
5761        boolean needRestart = false;
5762        if (app.pid > 0 && app.pid != MY_PID) {
5763            int pid = app.pid;
5764            synchronized (mPidsSelfLocked) {
5765                mPidsSelfLocked.remove(pid);
5766                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5767            }
5768            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5769            if (app.isolated) {
5770                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5771            }
5772            app.kill(reason, true);
5773            handleAppDiedLocked(app, true, allowRestart);
5774            removeLruProcessLocked(app);
5775
5776            if (app.persistent && !app.isolated) {
5777                if (!callerWillRestart) {
5778                    addAppLocked(app.info, false, null /* ABI override */);
5779                } else {
5780                    needRestart = true;
5781                }
5782            }
5783        } else {
5784            mRemovedProcesses.add(app);
5785        }
5786
5787        return needRestart;
5788    }
5789
5790    private final void processStartTimedOutLocked(ProcessRecord app) {
5791        final int pid = app.pid;
5792        boolean gone = false;
5793        synchronized (mPidsSelfLocked) {
5794            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5795            if (knownApp != null && knownApp.thread == null) {
5796                mPidsSelfLocked.remove(pid);
5797                gone = true;
5798            }
5799        }
5800
5801        if (gone) {
5802            Slog.w(TAG, "Process " + app + " failed to attach");
5803            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5804                    pid, app.uid, app.processName);
5805            mProcessNames.remove(app.processName, app.uid);
5806            mIsolatedProcesses.remove(app.uid);
5807            if (mHeavyWeightProcess == app) {
5808                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5809                        mHeavyWeightProcess.userId, 0));
5810                mHeavyWeightProcess = null;
5811            }
5812            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5813            if (app.isolated) {
5814                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5815            }
5816            // Take care of any launching providers waiting for this process.
5817            checkAppInLaunchingProvidersLocked(app, true);
5818            // Take care of any services that are waiting for the process.
5819            mServices.processStartTimedOutLocked(app);
5820            app.kill("start timeout", true);
5821            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5822                Slog.w(TAG, "Unattached app died before backup, skipping");
5823                try {
5824                    IBackupManager bm = IBackupManager.Stub.asInterface(
5825                            ServiceManager.getService(Context.BACKUP_SERVICE));
5826                    bm.agentDisconnected(app.info.packageName);
5827                } catch (RemoteException e) {
5828                    // Can't happen; the backup manager is local
5829                }
5830            }
5831            if (isPendingBroadcastProcessLocked(pid)) {
5832                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5833                skipPendingBroadcastLocked(pid);
5834            }
5835        } else {
5836            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5837        }
5838    }
5839
5840    private final boolean attachApplicationLocked(IApplicationThread thread,
5841            int pid) {
5842
5843        // Find the application record that is being attached...  either via
5844        // the pid if we are running in multiple processes, or just pull the
5845        // next app record if we are emulating process with anonymous threads.
5846        ProcessRecord app;
5847        if (pid != MY_PID && pid >= 0) {
5848            synchronized (mPidsSelfLocked) {
5849                app = mPidsSelfLocked.get(pid);
5850            }
5851        } else {
5852            app = null;
5853        }
5854
5855        if (app == null) {
5856            Slog.w(TAG, "No pending application record for pid " + pid
5857                    + " (IApplicationThread " + thread + "); dropping process");
5858            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5859            if (pid > 0 && pid != MY_PID) {
5860                Process.killProcessQuiet(pid);
5861                //TODO: Process.killProcessGroup(app.info.uid, pid);
5862            } else {
5863                try {
5864                    thread.scheduleExit();
5865                } catch (Exception e) {
5866                    // Ignore exceptions.
5867                }
5868            }
5869            return false;
5870        }
5871
5872        // If this application record is still attached to a previous
5873        // process, clean it up now.
5874        if (app.thread != null) {
5875            handleAppDiedLocked(app, true, true);
5876        }
5877
5878        // Tell the process all about itself.
5879
5880        if (localLOGV) Slog.v(
5881                TAG, "Binding process pid " + pid + " to record " + app);
5882
5883        final String processName = app.processName;
5884        try {
5885            AppDeathRecipient adr = new AppDeathRecipient(
5886                    app, pid, thread);
5887            thread.asBinder().linkToDeath(adr, 0);
5888            app.deathRecipient = adr;
5889        } catch (RemoteException e) {
5890            app.resetPackageList(mProcessStats);
5891            startProcessLocked(app, "link fail", processName);
5892            return false;
5893        }
5894
5895        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5896
5897        app.makeActive(thread, mProcessStats);
5898        app.curAdj = app.setAdj = -100;
5899        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5900        app.forcingToForeground = null;
5901        updateProcessForegroundLocked(app, false, false);
5902        app.hasShownUi = false;
5903        app.debugging = false;
5904        app.cached = false;
5905
5906        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5907
5908        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5909        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5910
5911        if (!normalMode) {
5912            Slog.i(TAG, "Launching preboot mode app: " + app);
5913        }
5914
5915        if (localLOGV) Slog.v(
5916            TAG, "New app record " + app
5917            + " thread=" + thread.asBinder() + " pid=" + pid);
5918        try {
5919            int testMode = IApplicationThread.DEBUG_OFF;
5920            if (mDebugApp != null && mDebugApp.equals(processName)) {
5921                testMode = mWaitForDebugger
5922                    ? IApplicationThread.DEBUG_WAIT
5923                    : IApplicationThread.DEBUG_ON;
5924                app.debugging = true;
5925                if (mDebugTransient) {
5926                    mDebugApp = mOrigDebugApp;
5927                    mWaitForDebugger = mOrigWaitForDebugger;
5928                }
5929            }
5930            String profileFile = app.instrumentationProfileFile;
5931            ParcelFileDescriptor profileFd = null;
5932            int samplingInterval = 0;
5933            boolean profileAutoStop = false;
5934            if (mProfileApp != null && mProfileApp.equals(processName)) {
5935                mProfileProc = app;
5936                profileFile = mProfileFile;
5937                profileFd = mProfileFd;
5938                samplingInterval = mSamplingInterval;
5939                profileAutoStop = mAutoStopProfiler;
5940            }
5941            boolean enableOpenGlTrace = false;
5942            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5943                enableOpenGlTrace = true;
5944                mOpenGlTraceApp = null;
5945            }
5946
5947            // If the app is being launched for restore or full backup, set it up specially
5948            boolean isRestrictedBackupMode = false;
5949            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5950                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5951                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5952                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5953            }
5954
5955            ensurePackageDexOpt(app.instrumentationInfo != null
5956                    ? app.instrumentationInfo.packageName
5957                    : app.info.packageName);
5958            if (app.instrumentationClass != null) {
5959                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5960            }
5961            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5962                    + processName + " with config " + mConfiguration);
5963            ApplicationInfo appInfo = app.instrumentationInfo != null
5964                    ? app.instrumentationInfo : app.info;
5965            app.compat = compatibilityInfoForPackageLocked(appInfo);
5966            if (profileFd != null) {
5967                profileFd = profileFd.dup();
5968            }
5969            ProfilerInfo profilerInfo = profileFile == null ? null
5970                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
5971            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
5972                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
5973                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5974                    isRestrictedBackupMode || !normalMode, app.persistent,
5975                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5976                    mCoreSettingsObserver.getCoreSettingsLocked());
5977            updateLruProcessLocked(app, false, null);
5978            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5979        } catch (Exception e) {
5980            // todo: Yikes!  What should we do?  For now we will try to
5981            // start another process, but that could easily get us in
5982            // an infinite loop of restarting processes...
5983            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
5984
5985            app.resetPackageList(mProcessStats);
5986            app.unlinkDeathRecipient();
5987            startProcessLocked(app, "bind fail", processName);
5988            return false;
5989        }
5990
5991        // Remove this record from the list of starting applications.
5992        mPersistentStartingProcesses.remove(app);
5993        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5994                "Attach application locked removing on hold: " + app);
5995        mProcessesOnHold.remove(app);
5996
5997        boolean badApp = false;
5998        boolean didSomething = false;
5999
6000        // See if the top visible activity is waiting to run in this process...
6001        if (normalMode) {
6002            try {
6003                if (mStackSupervisor.attachApplicationLocked(app)) {
6004                    didSomething = true;
6005                }
6006            } catch (Exception e) {
6007                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6008                badApp = true;
6009            }
6010        }
6011
6012        // Find any services that should be running in this process...
6013        if (!badApp) {
6014            try {
6015                didSomething |= mServices.attachApplicationLocked(app, processName);
6016            } catch (Exception e) {
6017                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6018                badApp = true;
6019            }
6020        }
6021
6022        // Check if a next-broadcast receiver is in this process...
6023        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6024            try {
6025                didSomething |= sendPendingBroadcastsLocked(app);
6026            } catch (Exception e) {
6027                // If the app died trying to launch the receiver we declare it 'bad'
6028                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6029                badApp = true;
6030            }
6031        }
6032
6033        // Check whether the next backup agent is in this process...
6034        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6035            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6036            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6037            try {
6038                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6039                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6040                        mBackupTarget.backupMode);
6041            } catch (Exception e) {
6042                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6043                badApp = true;
6044            }
6045        }
6046
6047        if (badApp) {
6048            app.kill("error during init", true);
6049            handleAppDiedLocked(app, false, true);
6050            return false;
6051        }
6052
6053        if (!didSomething) {
6054            updateOomAdjLocked();
6055        }
6056
6057        return true;
6058    }
6059
6060    @Override
6061    public final void attachApplication(IApplicationThread thread) {
6062        synchronized (this) {
6063            int callingPid = Binder.getCallingPid();
6064            final long origId = Binder.clearCallingIdentity();
6065            attachApplicationLocked(thread, callingPid);
6066            Binder.restoreCallingIdentity(origId);
6067        }
6068    }
6069
6070    @Override
6071    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6072        final long origId = Binder.clearCallingIdentity();
6073        synchronized (this) {
6074            ActivityStack stack = ActivityRecord.getStackLocked(token);
6075            if (stack != null) {
6076                ActivityRecord r =
6077                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6078                if (stopProfiling) {
6079                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6080                        try {
6081                            mProfileFd.close();
6082                        } catch (IOException e) {
6083                        }
6084                        clearProfilerLocked();
6085                    }
6086                }
6087            }
6088        }
6089        Binder.restoreCallingIdentity(origId);
6090    }
6091
6092    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6093        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6094                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6095    }
6096
6097    void enableScreenAfterBoot() {
6098        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6099                SystemClock.uptimeMillis());
6100        mWindowManager.enableScreenAfterBoot();
6101
6102        synchronized (this) {
6103            updateEventDispatchingLocked();
6104        }
6105    }
6106
6107    @Override
6108    public void showBootMessage(final CharSequence msg, final boolean always) {
6109        enforceNotIsolatedCaller("showBootMessage");
6110        mWindowManager.showBootMessage(msg, always);
6111    }
6112
6113    @Override
6114    public void keyguardWaitingForActivityDrawn() {
6115        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6116        final long token = Binder.clearCallingIdentity();
6117        try {
6118            synchronized (this) {
6119                if (DEBUG_LOCKSCREEN) logLockScreen("");
6120                mWindowManager.keyguardWaitingForActivityDrawn();
6121                if (mLockScreenShown) {
6122                    mLockScreenShown = false;
6123                    comeOutOfSleepIfNeededLocked();
6124                }
6125            }
6126        } finally {
6127            Binder.restoreCallingIdentity(token);
6128        }
6129    }
6130
6131    final void finishBooting() {
6132        synchronized (this) {
6133            if (!mBootAnimationComplete) {
6134                mCallFinishBooting = true;
6135                return;
6136            }
6137            mCallFinishBooting = false;
6138        }
6139
6140        // Register receivers to handle package update events
6141        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6142
6143        // Let system services know.
6144        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6145
6146        synchronized (this) {
6147            // Ensure that any processes we had put on hold are now started
6148            // up.
6149            final int NP = mProcessesOnHold.size();
6150            if (NP > 0) {
6151                ArrayList<ProcessRecord> procs =
6152                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6153                for (int ip=0; ip<NP; ip++) {
6154                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6155                            + procs.get(ip));
6156                    startProcessLocked(procs.get(ip), "on-hold", null);
6157                }
6158            }
6159
6160            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6161                // Start looking for apps that are abusing wake locks.
6162                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6163                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6164                // Tell anyone interested that we are done booting!
6165                SystemProperties.set("sys.boot_completed", "1");
6166
6167                // And trigger dev.bootcomplete if we are not showing encryption progress
6168                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6169                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6170                    SystemProperties.set("dev.bootcomplete", "1");
6171                }
6172                for (int i=0; i<mStartedUsers.size(); i++) {
6173                    UserStartedState uss = mStartedUsers.valueAt(i);
6174                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6175                        uss.mState = UserStartedState.STATE_RUNNING;
6176                        final int userId = mStartedUsers.keyAt(i);
6177                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6178                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6179                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6180                        broadcastIntentLocked(null, null, intent, null,
6181                                new IIntentReceiver.Stub() {
6182                                    @Override
6183                                    public void performReceive(Intent intent, int resultCode,
6184                                            String data, Bundle extras, boolean ordered,
6185                                            boolean sticky, int sendingUser) {
6186                                        synchronized (ActivityManagerService.this) {
6187                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6188                                                    true, false);
6189                                        }
6190                                    }
6191                                },
6192                                0, null, null,
6193                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6194                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6195                                userId);
6196                    }
6197                }
6198                scheduleStartProfilesLocked();
6199            }
6200        }
6201    }
6202
6203    @Override
6204    public void bootAnimationComplete() {
6205        final boolean callFinishBooting;
6206        synchronized (this) {
6207            callFinishBooting = mCallFinishBooting;
6208            mBootAnimationComplete = true;
6209        }
6210        if (callFinishBooting) {
6211            finishBooting();
6212        }
6213    }
6214
6215    final void ensureBootCompleted() {
6216        boolean booting;
6217        boolean enableScreen;
6218        synchronized (this) {
6219            booting = mBooting;
6220            mBooting = false;
6221            enableScreen = !mBooted;
6222            mBooted = true;
6223        }
6224
6225        if (booting) {
6226            finishBooting();
6227        }
6228
6229        if (enableScreen) {
6230            enableScreenAfterBoot();
6231        }
6232    }
6233
6234    @Override
6235    public final void activityResumed(IBinder token) {
6236        final long origId = Binder.clearCallingIdentity();
6237        synchronized(this) {
6238            ActivityStack stack = ActivityRecord.getStackLocked(token);
6239            if (stack != null) {
6240                ActivityRecord.activityResumedLocked(token);
6241            }
6242        }
6243        Binder.restoreCallingIdentity(origId);
6244    }
6245
6246    @Override
6247    public final void activityPaused(IBinder token) {
6248        final long origId = Binder.clearCallingIdentity();
6249        synchronized(this) {
6250            ActivityStack stack = ActivityRecord.getStackLocked(token);
6251            if (stack != null) {
6252                stack.activityPausedLocked(token, false);
6253            }
6254        }
6255        Binder.restoreCallingIdentity(origId);
6256    }
6257
6258    @Override
6259    public final void activityStopped(IBinder token, Bundle icicle,
6260            PersistableBundle persistentState, CharSequence description) {
6261        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6262
6263        // Refuse possible leaked file descriptors
6264        if (icicle != null && icicle.hasFileDescriptors()) {
6265            throw new IllegalArgumentException("File descriptors passed in Bundle");
6266        }
6267
6268        final long origId = Binder.clearCallingIdentity();
6269
6270        synchronized (this) {
6271            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6272            if (r != null) {
6273                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6274            }
6275        }
6276
6277        trimApplications();
6278
6279        Binder.restoreCallingIdentity(origId);
6280    }
6281
6282    @Override
6283    public final void activityDestroyed(IBinder token) {
6284        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6285        synchronized (this) {
6286            ActivityStack stack = ActivityRecord.getStackLocked(token);
6287            if (stack != null) {
6288                stack.activityDestroyedLocked(token);
6289            }
6290        }
6291    }
6292
6293    @Override
6294    public final void backgroundResourcesReleased(IBinder token) {
6295        final long origId = Binder.clearCallingIdentity();
6296        try {
6297            synchronized (this) {
6298                ActivityStack stack = ActivityRecord.getStackLocked(token);
6299                if (stack != null) {
6300                    stack.backgroundResourcesReleased(token);
6301                }
6302            }
6303        } finally {
6304            Binder.restoreCallingIdentity(origId);
6305        }
6306    }
6307
6308    @Override
6309    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6310        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6311    }
6312
6313    @Override
6314    public final void notifyEnterAnimationComplete(IBinder token) {
6315        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6316    }
6317
6318    @Override
6319    public String getCallingPackage(IBinder token) {
6320        synchronized (this) {
6321            ActivityRecord r = getCallingRecordLocked(token);
6322            return r != null ? r.info.packageName : null;
6323        }
6324    }
6325
6326    @Override
6327    public ComponentName getCallingActivity(IBinder token) {
6328        synchronized (this) {
6329            ActivityRecord r = getCallingRecordLocked(token);
6330            return r != null ? r.intent.getComponent() : null;
6331        }
6332    }
6333
6334    private ActivityRecord getCallingRecordLocked(IBinder token) {
6335        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6336        if (r == null) {
6337            return null;
6338        }
6339        return r.resultTo;
6340    }
6341
6342    @Override
6343    public ComponentName getActivityClassForToken(IBinder token) {
6344        synchronized(this) {
6345            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6346            if (r == null) {
6347                return null;
6348            }
6349            return r.intent.getComponent();
6350        }
6351    }
6352
6353    @Override
6354    public String getPackageForToken(IBinder token) {
6355        synchronized(this) {
6356            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6357            if (r == null) {
6358                return null;
6359            }
6360            return r.packageName;
6361        }
6362    }
6363
6364    @Override
6365    public IIntentSender getIntentSender(int type,
6366            String packageName, IBinder token, String resultWho,
6367            int requestCode, Intent[] intents, String[] resolvedTypes,
6368            int flags, Bundle options, int userId) {
6369        enforceNotIsolatedCaller("getIntentSender");
6370        // Refuse possible leaked file descriptors
6371        if (intents != null) {
6372            if (intents.length < 1) {
6373                throw new IllegalArgumentException("Intents array length must be >= 1");
6374            }
6375            for (int i=0; i<intents.length; i++) {
6376                Intent intent = intents[i];
6377                if (intent != null) {
6378                    if (intent.hasFileDescriptors()) {
6379                        throw new IllegalArgumentException("File descriptors passed in Intent");
6380                    }
6381                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6382                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6383                        throw new IllegalArgumentException(
6384                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6385                    }
6386                    intents[i] = new Intent(intent);
6387                }
6388            }
6389            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6390                throw new IllegalArgumentException(
6391                        "Intent array length does not match resolvedTypes length");
6392            }
6393        }
6394        if (options != null) {
6395            if (options.hasFileDescriptors()) {
6396                throw new IllegalArgumentException("File descriptors passed in options");
6397            }
6398        }
6399
6400        synchronized(this) {
6401            int callingUid = Binder.getCallingUid();
6402            int origUserId = userId;
6403            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6404                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6405                    ALLOW_NON_FULL, "getIntentSender", null);
6406            if (origUserId == UserHandle.USER_CURRENT) {
6407                // We don't want to evaluate this until the pending intent is
6408                // actually executed.  However, we do want to always do the
6409                // security checking for it above.
6410                userId = UserHandle.USER_CURRENT;
6411            }
6412            try {
6413                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6414                    int uid = AppGlobals.getPackageManager()
6415                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6416                    if (!UserHandle.isSameApp(callingUid, uid)) {
6417                        String msg = "Permission Denial: getIntentSender() from pid="
6418                            + Binder.getCallingPid()
6419                            + ", uid=" + Binder.getCallingUid()
6420                            + ", (need uid=" + uid + ")"
6421                            + " is not allowed to send as package " + packageName;
6422                        Slog.w(TAG, msg);
6423                        throw new SecurityException(msg);
6424                    }
6425                }
6426
6427                return getIntentSenderLocked(type, packageName, callingUid, userId,
6428                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6429
6430            } catch (RemoteException e) {
6431                throw new SecurityException(e);
6432            }
6433        }
6434    }
6435
6436    IIntentSender getIntentSenderLocked(int type, String packageName,
6437            int callingUid, int userId, IBinder token, String resultWho,
6438            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6439            Bundle options) {
6440        if (DEBUG_MU)
6441            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6442        ActivityRecord activity = null;
6443        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6444            activity = ActivityRecord.isInStackLocked(token);
6445            if (activity == null) {
6446                return null;
6447            }
6448            if (activity.finishing) {
6449                return null;
6450            }
6451        }
6452
6453        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6454        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6455        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6456        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6457                |PendingIntent.FLAG_UPDATE_CURRENT);
6458
6459        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6460                type, packageName, activity, resultWho,
6461                requestCode, intents, resolvedTypes, flags, options, userId);
6462        WeakReference<PendingIntentRecord> ref;
6463        ref = mIntentSenderRecords.get(key);
6464        PendingIntentRecord rec = ref != null ? ref.get() : null;
6465        if (rec != null) {
6466            if (!cancelCurrent) {
6467                if (updateCurrent) {
6468                    if (rec.key.requestIntent != null) {
6469                        rec.key.requestIntent.replaceExtras(intents != null ?
6470                                intents[intents.length - 1] : null);
6471                    }
6472                    if (intents != null) {
6473                        intents[intents.length-1] = rec.key.requestIntent;
6474                        rec.key.allIntents = intents;
6475                        rec.key.allResolvedTypes = resolvedTypes;
6476                    } else {
6477                        rec.key.allIntents = null;
6478                        rec.key.allResolvedTypes = null;
6479                    }
6480                }
6481                return rec;
6482            }
6483            rec.canceled = true;
6484            mIntentSenderRecords.remove(key);
6485        }
6486        if (noCreate) {
6487            return rec;
6488        }
6489        rec = new PendingIntentRecord(this, key, callingUid);
6490        mIntentSenderRecords.put(key, rec.ref);
6491        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6492            if (activity.pendingResults == null) {
6493                activity.pendingResults
6494                        = new HashSet<WeakReference<PendingIntentRecord>>();
6495            }
6496            activity.pendingResults.add(rec.ref);
6497        }
6498        return rec;
6499    }
6500
6501    @Override
6502    public void cancelIntentSender(IIntentSender sender) {
6503        if (!(sender instanceof PendingIntentRecord)) {
6504            return;
6505        }
6506        synchronized(this) {
6507            PendingIntentRecord rec = (PendingIntentRecord)sender;
6508            try {
6509                int uid = AppGlobals.getPackageManager()
6510                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6511                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6512                    String msg = "Permission Denial: cancelIntentSender() from pid="
6513                        + Binder.getCallingPid()
6514                        + ", uid=" + Binder.getCallingUid()
6515                        + " is not allowed to cancel packges "
6516                        + rec.key.packageName;
6517                    Slog.w(TAG, msg);
6518                    throw new SecurityException(msg);
6519                }
6520            } catch (RemoteException e) {
6521                throw new SecurityException(e);
6522            }
6523            cancelIntentSenderLocked(rec, true);
6524        }
6525    }
6526
6527    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6528        rec.canceled = true;
6529        mIntentSenderRecords.remove(rec.key);
6530        if (cleanActivity && rec.key.activity != null) {
6531            rec.key.activity.pendingResults.remove(rec.ref);
6532        }
6533    }
6534
6535    @Override
6536    public String getPackageForIntentSender(IIntentSender pendingResult) {
6537        if (!(pendingResult instanceof PendingIntentRecord)) {
6538            return null;
6539        }
6540        try {
6541            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6542            return res.key.packageName;
6543        } catch (ClassCastException e) {
6544        }
6545        return null;
6546    }
6547
6548    @Override
6549    public int getUidForIntentSender(IIntentSender sender) {
6550        if (sender instanceof PendingIntentRecord) {
6551            try {
6552                PendingIntentRecord res = (PendingIntentRecord)sender;
6553                return res.uid;
6554            } catch (ClassCastException e) {
6555            }
6556        }
6557        return -1;
6558    }
6559
6560    @Override
6561    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6562        if (!(pendingResult instanceof PendingIntentRecord)) {
6563            return false;
6564        }
6565        try {
6566            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6567            if (res.key.allIntents == null) {
6568                return false;
6569            }
6570            for (int i=0; i<res.key.allIntents.length; i++) {
6571                Intent intent = res.key.allIntents[i];
6572                if (intent.getPackage() != null && intent.getComponent() != null) {
6573                    return false;
6574                }
6575            }
6576            return true;
6577        } catch (ClassCastException e) {
6578        }
6579        return false;
6580    }
6581
6582    @Override
6583    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6584        if (!(pendingResult instanceof PendingIntentRecord)) {
6585            return false;
6586        }
6587        try {
6588            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6589            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6590                return true;
6591            }
6592            return false;
6593        } catch (ClassCastException e) {
6594        }
6595        return false;
6596    }
6597
6598    @Override
6599    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6600        if (!(pendingResult instanceof PendingIntentRecord)) {
6601            return null;
6602        }
6603        try {
6604            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6605            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6606        } catch (ClassCastException e) {
6607        }
6608        return null;
6609    }
6610
6611    @Override
6612    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6613        if (!(pendingResult instanceof PendingIntentRecord)) {
6614            return null;
6615        }
6616        try {
6617            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6618            Intent intent = res.key.requestIntent;
6619            if (intent != null) {
6620                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6621                        || res.lastTagPrefix.equals(prefix))) {
6622                    return res.lastTag;
6623                }
6624                res.lastTagPrefix = prefix;
6625                StringBuilder sb = new StringBuilder(128);
6626                if (prefix != null) {
6627                    sb.append(prefix);
6628                }
6629                if (intent.getAction() != null) {
6630                    sb.append(intent.getAction());
6631                } else if (intent.getComponent() != null) {
6632                    intent.getComponent().appendShortString(sb);
6633                } else {
6634                    sb.append("?");
6635                }
6636                return res.lastTag = sb.toString();
6637            }
6638        } catch (ClassCastException e) {
6639        }
6640        return null;
6641    }
6642
6643    @Override
6644    public void setProcessLimit(int max) {
6645        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6646                "setProcessLimit()");
6647        synchronized (this) {
6648            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6649            mProcessLimitOverride = max;
6650        }
6651        trimApplications();
6652    }
6653
6654    @Override
6655    public int getProcessLimit() {
6656        synchronized (this) {
6657            return mProcessLimitOverride;
6658        }
6659    }
6660
6661    void foregroundTokenDied(ForegroundToken token) {
6662        synchronized (ActivityManagerService.this) {
6663            synchronized (mPidsSelfLocked) {
6664                ForegroundToken cur
6665                    = mForegroundProcesses.get(token.pid);
6666                if (cur != token) {
6667                    return;
6668                }
6669                mForegroundProcesses.remove(token.pid);
6670                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6671                if (pr == null) {
6672                    return;
6673                }
6674                pr.forcingToForeground = null;
6675                updateProcessForegroundLocked(pr, false, false);
6676            }
6677            updateOomAdjLocked();
6678        }
6679    }
6680
6681    @Override
6682    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6683        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6684                "setProcessForeground()");
6685        synchronized(this) {
6686            boolean changed = false;
6687
6688            synchronized (mPidsSelfLocked) {
6689                ProcessRecord pr = mPidsSelfLocked.get(pid);
6690                if (pr == null && isForeground) {
6691                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6692                    return;
6693                }
6694                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6695                if (oldToken != null) {
6696                    oldToken.token.unlinkToDeath(oldToken, 0);
6697                    mForegroundProcesses.remove(pid);
6698                    if (pr != null) {
6699                        pr.forcingToForeground = null;
6700                    }
6701                    changed = true;
6702                }
6703                if (isForeground && token != null) {
6704                    ForegroundToken newToken = new ForegroundToken() {
6705                        @Override
6706                        public void binderDied() {
6707                            foregroundTokenDied(this);
6708                        }
6709                    };
6710                    newToken.pid = pid;
6711                    newToken.token = token;
6712                    try {
6713                        token.linkToDeath(newToken, 0);
6714                        mForegroundProcesses.put(pid, newToken);
6715                        pr.forcingToForeground = token;
6716                        changed = true;
6717                    } catch (RemoteException e) {
6718                        // If the process died while doing this, we will later
6719                        // do the cleanup with the process death link.
6720                    }
6721                }
6722            }
6723
6724            if (changed) {
6725                updateOomAdjLocked();
6726            }
6727        }
6728    }
6729
6730    // =========================================================
6731    // PERMISSIONS
6732    // =========================================================
6733
6734    static class PermissionController extends IPermissionController.Stub {
6735        ActivityManagerService mActivityManagerService;
6736        PermissionController(ActivityManagerService activityManagerService) {
6737            mActivityManagerService = activityManagerService;
6738        }
6739
6740        @Override
6741        public boolean checkPermission(String permission, int pid, int uid) {
6742            return mActivityManagerService.checkPermission(permission, pid,
6743                    uid) == PackageManager.PERMISSION_GRANTED;
6744        }
6745    }
6746
6747    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6748        @Override
6749        public int checkComponentPermission(String permission, int pid, int uid,
6750                int owningUid, boolean exported) {
6751            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6752                    owningUid, exported);
6753        }
6754
6755        @Override
6756        public Object getAMSLock() {
6757            return ActivityManagerService.this;
6758        }
6759    }
6760
6761    /**
6762     * This can be called with or without the global lock held.
6763     */
6764    int checkComponentPermission(String permission, int pid, int uid,
6765            int owningUid, boolean exported) {
6766        // We might be performing an operation on behalf of an indirect binder
6767        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6768        // client identity accordingly before proceeding.
6769        Identity tlsIdentity = sCallerIdentity.get();
6770        if (tlsIdentity != null) {
6771            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6772                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6773            uid = tlsIdentity.uid;
6774            pid = tlsIdentity.pid;
6775        }
6776
6777        if (pid == MY_PID) {
6778            return PackageManager.PERMISSION_GRANTED;
6779        }
6780
6781        return ActivityManager.checkComponentPermission(permission, uid,
6782                owningUid, exported);
6783    }
6784
6785    /**
6786     * As the only public entry point for permissions checking, this method
6787     * can enforce the semantic that requesting a check on a null global
6788     * permission is automatically denied.  (Internally a null permission
6789     * string is used when calling {@link #checkComponentPermission} in cases
6790     * when only uid-based security is needed.)
6791     *
6792     * This can be called with or without the global lock held.
6793     */
6794    @Override
6795    public int checkPermission(String permission, int pid, int uid) {
6796        if (permission == null) {
6797            return PackageManager.PERMISSION_DENIED;
6798        }
6799        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6800    }
6801
6802    /**
6803     * Binder IPC calls go through the public entry point.
6804     * This can be called with or without the global lock held.
6805     */
6806    int checkCallingPermission(String permission) {
6807        return checkPermission(permission,
6808                Binder.getCallingPid(),
6809                UserHandle.getAppId(Binder.getCallingUid()));
6810    }
6811
6812    /**
6813     * This can be called with or without the global lock held.
6814     */
6815    void enforceCallingPermission(String permission, String func) {
6816        if (checkCallingPermission(permission)
6817                == PackageManager.PERMISSION_GRANTED) {
6818            return;
6819        }
6820
6821        String msg = "Permission Denial: " + func + " from pid="
6822                + Binder.getCallingPid()
6823                + ", uid=" + Binder.getCallingUid()
6824                + " requires " + permission;
6825        Slog.w(TAG, msg);
6826        throw new SecurityException(msg);
6827    }
6828
6829    /**
6830     * Determine if UID is holding permissions required to access {@link Uri} in
6831     * the given {@link ProviderInfo}. Final permission checking is always done
6832     * in {@link ContentProvider}.
6833     */
6834    private final boolean checkHoldingPermissionsLocked(
6835            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6836        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6837                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6838        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6839            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6840                    != PERMISSION_GRANTED) {
6841                return false;
6842            }
6843        }
6844        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6845    }
6846
6847    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6848            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6849        if (pi.applicationInfo.uid == uid) {
6850            return true;
6851        } else if (!pi.exported) {
6852            return false;
6853        }
6854
6855        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6856        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6857        try {
6858            // check if target holds top-level <provider> permissions
6859            if (!readMet && pi.readPermission != null && considerUidPermissions
6860                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6861                readMet = true;
6862            }
6863            if (!writeMet && pi.writePermission != null && considerUidPermissions
6864                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6865                writeMet = true;
6866            }
6867
6868            // track if unprotected read/write is allowed; any denied
6869            // <path-permission> below removes this ability
6870            boolean allowDefaultRead = pi.readPermission == null;
6871            boolean allowDefaultWrite = pi.writePermission == null;
6872
6873            // check if target holds any <path-permission> that match uri
6874            final PathPermission[] pps = pi.pathPermissions;
6875            if (pps != null) {
6876                final String path = grantUri.uri.getPath();
6877                int i = pps.length;
6878                while (i > 0 && (!readMet || !writeMet)) {
6879                    i--;
6880                    PathPermission pp = pps[i];
6881                    if (pp.match(path)) {
6882                        if (!readMet) {
6883                            final String pprperm = pp.getReadPermission();
6884                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6885                                    + pprperm + " for " + pp.getPath()
6886                                    + ": match=" + pp.match(path)
6887                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6888                            if (pprperm != null) {
6889                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6890                                        == PERMISSION_GRANTED) {
6891                                    readMet = true;
6892                                } else {
6893                                    allowDefaultRead = false;
6894                                }
6895                            }
6896                        }
6897                        if (!writeMet) {
6898                            final String ppwperm = pp.getWritePermission();
6899                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6900                                    + ppwperm + " for " + pp.getPath()
6901                                    + ": match=" + pp.match(path)
6902                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6903                            if (ppwperm != null) {
6904                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6905                                        == PERMISSION_GRANTED) {
6906                                    writeMet = true;
6907                                } else {
6908                                    allowDefaultWrite = false;
6909                                }
6910                            }
6911                        }
6912                    }
6913                }
6914            }
6915
6916            // grant unprotected <provider> read/write, if not blocked by
6917            // <path-permission> above
6918            if (allowDefaultRead) readMet = true;
6919            if (allowDefaultWrite) writeMet = true;
6920
6921        } catch (RemoteException e) {
6922            return false;
6923        }
6924
6925        return readMet && writeMet;
6926    }
6927
6928    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6929        ProviderInfo pi = null;
6930        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6931        if (cpr != null) {
6932            pi = cpr.info;
6933        } else {
6934            try {
6935                pi = AppGlobals.getPackageManager().resolveContentProvider(
6936                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6937            } catch (RemoteException ex) {
6938            }
6939        }
6940        return pi;
6941    }
6942
6943    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6944        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6945        if (targetUris != null) {
6946            return targetUris.get(grantUri);
6947        }
6948        return null;
6949    }
6950
6951    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6952            String targetPkg, int targetUid, GrantUri grantUri) {
6953        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6954        if (targetUris == null) {
6955            targetUris = Maps.newArrayMap();
6956            mGrantedUriPermissions.put(targetUid, targetUris);
6957        }
6958
6959        UriPermission perm = targetUris.get(grantUri);
6960        if (perm == null) {
6961            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6962            targetUris.put(grantUri, perm);
6963        }
6964
6965        return perm;
6966    }
6967
6968    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6969            final int modeFlags) {
6970        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6971        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6972                : UriPermission.STRENGTH_OWNED;
6973
6974        // Root gets to do everything.
6975        if (uid == 0) {
6976            return true;
6977        }
6978
6979        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6980        if (perms == null) return false;
6981
6982        // First look for exact match
6983        final UriPermission exactPerm = perms.get(grantUri);
6984        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6985            return true;
6986        }
6987
6988        // No exact match, look for prefixes
6989        final int N = perms.size();
6990        for (int i = 0; i < N; i++) {
6991            final UriPermission perm = perms.valueAt(i);
6992            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6993                    && perm.getStrength(modeFlags) >= minStrength) {
6994                return true;
6995            }
6996        }
6997
6998        return false;
6999    }
7000
7001    /**
7002     * @param uri This uri must NOT contain an embedded userId.
7003     * @param userId The userId in which the uri is to be resolved.
7004     */
7005    @Override
7006    public int checkUriPermission(Uri uri, int pid, int uid,
7007            final int modeFlags, int userId) {
7008        enforceNotIsolatedCaller("checkUriPermission");
7009
7010        // Another redirected-binder-call permissions check as in
7011        // {@link checkComponentPermission}.
7012        Identity tlsIdentity = sCallerIdentity.get();
7013        if (tlsIdentity != null) {
7014            uid = tlsIdentity.uid;
7015            pid = tlsIdentity.pid;
7016        }
7017
7018        // Our own process gets to do everything.
7019        if (pid == MY_PID) {
7020            return PackageManager.PERMISSION_GRANTED;
7021        }
7022        synchronized (this) {
7023            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7024                    ? PackageManager.PERMISSION_GRANTED
7025                    : PackageManager.PERMISSION_DENIED;
7026        }
7027    }
7028
7029    /**
7030     * Check if the targetPkg can be granted permission to access uri by
7031     * the callingUid using the given modeFlags.  Throws a security exception
7032     * if callingUid is not allowed to do this.  Returns the uid of the target
7033     * if the URI permission grant should be performed; returns -1 if it is not
7034     * needed (for example targetPkg already has permission to access the URI).
7035     * If you already know the uid of the target, you can supply it in
7036     * lastTargetUid else set that to -1.
7037     */
7038    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7039            final int modeFlags, int lastTargetUid) {
7040        if (!Intent.isAccessUriMode(modeFlags)) {
7041            return -1;
7042        }
7043
7044        if (targetPkg != null) {
7045            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7046                    "Checking grant " + targetPkg + " permission to " + grantUri);
7047        }
7048
7049        final IPackageManager pm = AppGlobals.getPackageManager();
7050
7051        // If this is not a content: uri, we can't do anything with it.
7052        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7053            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7054                    "Can't grant URI permission for non-content URI: " + grantUri);
7055            return -1;
7056        }
7057
7058        final String authority = grantUri.uri.getAuthority();
7059        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7060        if (pi == null) {
7061            Slog.w(TAG, "No content provider found for permission check: " +
7062                    grantUri.uri.toSafeString());
7063            return -1;
7064        }
7065
7066        int targetUid = lastTargetUid;
7067        if (targetUid < 0 && targetPkg != null) {
7068            try {
7069                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7070                if (targetUid < 0) {
7071                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7072                            "Can't grant URI permission no uid for: " + targetPkg);
7073                    return -1;
7074                }
7075            } catch (RemoteException ex) {
7076                return -1;
7077            }
7078        }
7079
7080        if (targetUid >= 0) {
7081            // First...  does the target actually need this permission?
7082            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7083                // No need to grant the target this permission.
7084                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7085                        "Target " + targetPkg + " already has full permission to " + grantUri);
7086                return -1;
7087            }
7088        } else {
7089            // First...  there is no target package, so can anyone access it?
7090            boolean allowed = pi.exported;
7091            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7092                if (pi.readPermission != null) {
7093                    allowed = false;
7094                }
7095            }
7096            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7097                if (pi.writePermission != null) {
7098                    allowed = false;
7099                }
7100            }
7101            if (allowed) {
7102                return -1;
7103            }
7104        }
7105
7106        /* There is a special cross user grant if:
7107         * - The target is on another user.
7108         * - Apps on the current user can access the uri without any uid permissions.
7109         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7110         * grant uri permissions.
7111         */
7112        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7113                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7114                modeFlags, false /*without considering the uid permissions*/);
7115
7116        // Second...  is the provider allowing granting of URI permissions?
7117        if (!specialCrossUserGrant) {
7118            if (!pi.grantUriPermissions) {
7119                throw new SecurityException("Provider " + pi.packageName
7120                        + "/" + pi.name
7121                        + " does not allow granting of Uri permissions (uri "
7122                        + grantUri + ")");
7123            }
7124            if (pi.uriPermissionPatterns != null) {
7125                final int N = pi.uriPermissionPatterns.length;
7126                boolean allowed = false;
7127                for (int i=0; i<N; i++) {
7128                    if (pi.uriPermissionPatterns[i] != null
7129                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7130                        allowed = true;
7131                        break;
7132                    }
7133                }
7134                if (!allowed) {
7135                    throw new SecurityException("Provider " + pi.packageName
7136                            + "/" + pi.name
7137                            + " does not allow granting of permission to path of Uri "
7138                            + grantUri);
7139                }
7140            }
7141        }
7142
7143        // Third...  does the caller itself have permission to access
7144        // this uri?
7145        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7146            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7147                // Require they hold a strong enough Uri permission
7148                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7149                    throw new SecurityException("Uid " + callingUid
7150                            + " does not have permission to uri " + grantUri);
7151                }
7152            }
7153        }
7154        return targetUid;
7155    }
7156
7157    /**
7158     * @param uri This uri must NOT contain an embedded userId.
7159     * @param userId The userId in which the uri is to be resolved.
7160     */
7161    @Override
7162    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7163            final int modeFlags, int userId) {
7164        enforceNotIsolatedCaller("checkGrantUriPermission");
7165        synchronized(this) {
7166            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7167                    new GrantUri(userId, uri, false), modeFlags, -1);
7168        }
7169    }
7170
7171    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7172            final int modeFlags, UriPermissionOwner owner) {
7173        if (!Intent.isAccessUriMode(modeFlags)) {
7174            return;
7175        }
7176
7177        // So here we are: the caller has the assumed permission
7178        // to the uri, and the target doesn't.  Let's now give this to
7179        // the target.
7180
7181        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7182                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7183
7184        final String authority = grantUri.uri.getAuthority();
7185        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7186        if (pi == null) {
7187            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7188            return;
7189        }
7190
7191        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7192            grantUri.prefix = true;
7193        }
7194        final UriPermission perm = findOrCreateUriPermissionLocked(
7195                pi.packageName, targetPkg, targetUid, grantUri);
7196        perm.grantModes(modeFlags, owner);
7197    }
7198
7199    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7200            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7201        if (targetPkg == null) {
7202            throw new NullPointerException("targetPkg");
7203        }
7204        int targetUid;
7205        final IPackageManager pm = AppGlobals.getPackageManager();
7206        try {
7207            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7208        } catch (RemoteException ex) {
7209            return;
7210        }
7211
7212        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7213                targetUid);
7214        if (targetUid < 0) {
7215            return;
7216        }
7217
7218        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7219                owner);
7220    }
7221
7222    static class NeededUriGrants extends ArrayList<GrantUri> {
7223        final String targetPkg;
7224        final int targetUid;
7225        final int flags;
7226
7227        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7228            this.targetPkg = targetPkg;
7229            this.targetUid = targetUid;
7230            this.flags = flags;
7231        }
7232    }
7233
7234    /**
7235     * Like checkGrantUriPermissionLocked, but takes an Intent.
7236     */
7237    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7238            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7239        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7240                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7241                + " clip=" + (intent != null ? intent.getClipData() : null)
7242                + " from " + intent + "; flags=0x"
7243                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7244
7245        if (targetPkg == null) {
7246            throw new NullPointerException("targetPkg");
7247        }
7248
7249        if (intent == null) {
7250            return null;
7251        }
7252        Uri data = intent.getData();
7253        ClipData clip = intent.getClipData();
7254        if (data == null && clip == null) {
7255            return null;
7256        }
7257        // Default userId for uris in the intent (if they don't specify it themselves)
7258        int contentUserHint = intent.getContentUserHint();
7259        if (contentUserHint == UserHandle.USER_CURRENT) {
7260            contentUserHint = UserHandle.getUserId(callingUid);
7261        }
7262        final IPackageManager pm = AppGlobals.getPackageManager();
7263        int targetUid;
7264        if (needed != null) {
7265            targetUid = needed.targetUid;
7266        } else {
7267            try {
7268                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7269            } catch (RemoteException ex) {
7270                return null;
7271            }
7272            if (targetUid < 0) {
7273                if (DEBUG_URI_PERMISSION) {
7274                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7275                            + " on user " + targetUserId);
7276                }
7277                return null;
7278            }
7279        }
7280        if (data != null) {
7281            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7282            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7283                    targetUid);
7284            if (targetUid > 0) {
7285                if (needed == null) {
7286                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7287                }
7288                needed.add(grantUri);
7289            }
7290        }
7291        if (clip != null) {
7292            for (int i=0; i<clip.getItemCount(); i++) {
7293                Uri uri = clip.getItemAt(i).getUri();
7294                if (uri != null) {
7295                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7296                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7297                            targetUid);
7298                    if (targetUid > 0) {
7299                        if (needed == null) {
7300                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7301                        }
7302                        needed.add(grantUri);
7303                    }
7304                } else {
7305                    Intent clipIntent = clip.getItemAt(i).getIntent();
7306                    if (clipIntent != null) {
7307                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7308                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7309                        if (newNeeded != null) {
7310                            needed = newNeeded;
7311                        }
7312                    }
7313                }
7314            }
7315        }
7316
7317        return needed;
7318    }
7319
7320    /**
7321     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7322     */
7323    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7324            UriPermissionOwner owner) {
7325        if (needed != null) {
7326            for (int i=0; i<needed.size(); i++) {
7327                GrantUri grantUri = needed.get(i);
7328                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7329                        grantUri, needed.flags, owner);
7330            }
7331        }
7332    }
7333
7334    void grantUriPermissionFromIntentLocked(int callingUid,
7335            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7336        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7337                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7338        if (needed == null) {
7339            return;
7340        }
7341
7342        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7343    }
7344
7345    /**
7346     * @param uri This uri must NOT contain an embedded userId.
7347     * @param userId The userId in which the uri is to be resolved.
7348     */
7349    @Override
7350    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7351            final int modeFlags, int userId) {
7352        enforceNotIsolatedCaller("grantUriPermission");
7353        GrantUri grantUri = new GrantUri(userId, uri, false);
7354        synchronized(this) {
7355            final ProcessRecord r = getRecordForAppLocked(caller);
7356            if (r == null) {
7357                throw new SecurityException("Unable to find app for caller "
7358                        + caller
7359                        + " when granting permission to uri " + grantUri);
7360            }
7361            if (targetPkg == null) {
7362                throw new IllegalArgumentException("null target");
7363            }
7364            if (grantUri == null) {
7365                throw new IllegalArgumentException("null uri");
7366            }
7367
7368            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7369                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7370                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7371                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7372
7373            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7374                    UserHandle.getUserId(r.uid));
7375        }
7376    }
7377
7378    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7379        if (perm.modeFlags == 0) {
7380            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7381                    perm.targetUid);
7382            if (perms != null) {
7383                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7384                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7385
7386                perms.remove(perm.uri);
7387                if (perms.isEmpty()) {
7388                    mGrantedUriPermissions.remove(perm.targetUid);
7389                }
7390            }
7391        }
7392    }
7393
7394    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7395        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7396
7397        final IPackageManager pm = AppGlobals.getPackageManager();
7398        final String authority = grantUri.uri.getAuthority();
7399        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7400        if (pi == null) {
7401            Slog.w(TAG, "No content provider found for permission revoke: "
7402                    + grantUri.toSafeString());
7403            return;
7404        }
7405
7406        // Does the caller have this permission on the URI?
7407        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7408            // If they don't have direct access to the URI, then revoke any
7409            // ownerless URI permissions that have been granted to them.
7410            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7411            if (perms != null) {
7412                boolean persistChanged = false;
7413                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7414                    final UriPermission perm = it.next();
7415                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7416                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7417                        if (DEBUG_URI_PERMISSION)
7418                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7419                                    " permission to " + perm.uri);
7420                        persistChanged |= perm.revokeModes(
7421                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7422                        if (perm.modeFlags == 0) {
7423                            it.remove();
7424                        }
7425                    }
7426                }
7427                if (perms.isEmpty()) {
7428                    mGrantedUriPermissions.remove(callingUid);
7429                }
7430                if (persistChanged) {
7431                    schedulePersistUriGrants();
7432                }
7433            }
7434            return;
7435        }
7436
7437        boolean persistChanged = false;
7438
7439        // Go through all of the permissions and remove any that match.
7440        int N = mGrantedUriPermissions.size();
7441        for (int i = 0; i < N; i++) {
7442            final int targetUid = mGrantedUriPermissions.keyAt(i);
7443            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7444
7445            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7446                final UriPermission perm = it.next();
7447                if (perm.uri.sourceUserId == grantUri.sourceUserId
7448                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7449                    if (DEBUG_URI_PERMISSION)
7450                        Slog.v(TAG,
7451                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7452                    persistChanged |= perm.revokeModes(
7453                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7454                    if (perm.modeFlags == 0) {
7455                        it.remove();
7456                    }
7457                }
7458            }
7459
7460            if (perms.isEmpty()) {
7461                mGrantedUriPermissions.remove(targetUid);
7462                N--;
7463                i--;
7464            }
7465        }
7466
7467        if (persistChanged) {
7468            schedulePersistUriGrants();
7469        }
7470    }
7471
7472    /**
7473     * @param uri This uri must NOT contain an embedded userId.
7474     * @param userId The userId in which the uri is to be resolved.
7475     */
7476    @Override
7477    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7478            int userId) {
7479        enforceNotIsolatedCaller("revokeUriPermission");
7480        synchronized(this) {
7481            final ProcessRecord r = getRecordForAppLocked(caller);
7482            if (r == null) {
7483                throw new SecurityException("Unable to find app for caller "
7484                        + caller
7485                        + " when revoking permission to uri " + uri);
7486            }
7487            if (uri == null) {
7488                Slog.w(TAG, "revokeUriPermission: null uri");
7489                return;
7490            }
7491
7492            if (!Intent.isAccessUriMode(modeFlags)) {
7493                return;
7494            }
7495
7496            final IPackageManager pm = AppGlobals.getPackageManager();
7497            final String authority = uri.getAuthority();
7498            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7499            if (pi == null) {
7500                Slog.w(TAG, "No content provider found for permission revoke: "
7501                        + uri.toSafeString());
7502                return;
7503            }
7504
7505            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7506        }
7507    }
7508
7509    /**
7510     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7511     * given package.
7512     *
7513     * @param packageName Package name to match, or {@code null} to apply to all
7514     *            packages.
7515     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7516     *            to all users.
7517     * @param persistable If persistable grants should be removed.
7518     */
7519    private void removeUriPermissionsForPackageLocked(
7520            String packageName, int userHandle, boolean persistable) {
7521        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7522            throw new IllegalArgumentException("Must narrow by either package or user");
7523        }
7524
7525        boolean persistChanged = false;
7526
7527        int N = mGrantedUriPermissions.size();
7528        for (int i = 0; i < N; i++) {
7529            final int targetUid = mGrantedUriPermissions.keyAt(i);
7530            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7531
7532            // Only inspect grants matching user
7533            if (userHandle == UserHandle.USER_ALL
7534                    || userHandle == UserHandle.getUserId(targetUid)) {
7535                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7536                    final UriPermission perm = it.next();
7537
7538                    // Only inspect grants matching package
7539                    if (packageName == null || perm.sourcePkg.equals(packageName)
7540                            || perm.targetPkg.equals(packageName)) {
7541                        persistChanged |= perm.revokeModes(persistable
7542                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7543
7544                        // Only remove when no modes remain; any persisted grants
7545                        // will keep this alive.
7546                        if (perm.modeFlags == 0) {
7547                            it.remove();
7548                        }
7549                    }
7550                }
7551
7552                if (perms.isEmpty()) {
7553                    mGrantedUriPermissions.remove(targetUid);
7554                    N--;
7555                    i--;
7556                }
7557            }
7558        }
7559
7560        if (persistChanged) {
7561            schedulePersistUriGrants();
7562        }
7563    }
7564
7565    @Override
7566    public IBinder newUriPermissionOwner(String name) {
7567        enforceNotIsolatedCaller("newUriPermissionOwner");
7568        synchronized(this) {
7569            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7570            return owner.getExternalTokenLocked();
7571        }
7572    }
7573
7574    /**
7575     * @param uri This uri must NOT contain an embedded userId.
7576     * @param sourceUserId The userId in which the uri is to be resolved.
7577     * @param targetUserId The userId of the app that receives the grant.
7578     */
7579    @Override
7580    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7581            final int modeFlags, int sourceUserId, int targetUserId) {
7582        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7583                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7584        synchronized(this) {
7585            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7586            if (owner == null) {
7587                throw new IllegalArgumentException("Unknown owner: " + token);
7588            }
7589            if (fromUid != Binder.getCallingUid()) {
7590                if (Binder.getCallingUid() != Process.myUid()) {
7591                    // Only system code can grant URI permissions on behalf
7592                    // of other users.
7593                    throw new SecurityException("nice try");
7594                }
7595            }
7596            if (targetPkg == null) {
7597                throw new IllegalArgumentException("null target");
7598            }
7599            if (uri == null) {
7600                throw new IllegalArgumentException("null uri");
7601            }
7602
7603            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7604                    modeFlags, owner, targetUserId);
7605        }
7606    }
7607
7608    /**
7609     * @param uri This uri must NOT contain an embedded userId.
7610     * @param userId The userId in which the uri is to be resolved.
7611     */
7612    @Override
7613    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7614        synchronized(this) {
7615            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7616            if (owner == null) {
7617                throw new IllegalArgumentException("Unknown owner: " + token);
7618            }
7619
7620            if (uri == null) {
7621                owner.removeUriPermissionsLocked(mode);
7622            } else {
7623                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7624            }
7625        }
7626    }
7627
7628    private void schedulePersistUriGrants() {
7629        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7630            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7631                    10 * DateUtils.SECOND_IN_MILLIS);
7632        }
7633    }
7634
7635    private void writeGrantedUriPermissions() {
7636        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7637
7638        // Snapshot permissions so we can persist without lock
7639        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7640        synchronized (this) {
7641            final int size = mGrantedUriPermissions.size();
7642            for (int i = 0; i < size; i++) {
7643                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7644                for (UriPermission perm : perms.values()) {
7645                    if (perm.persistedModeFlags != 0) {
7646                        persist.add(perm.snapshot());
7647                    }
7648                }
7649            }
7650        }
7651
7652        FileOutputStream fos = null;
7653        try {
7654            fos = mGrantFile.startWrite();
7655
7656            XmlSerializer out = new FastXmlSerializer();
7657            out.setOutput(fos, "utf-8");
7658            out.startDocument(null, true);
7659            out.startTag(null, TAG_URI_GRANTS);
7660            for (UriPermission.Snapshot perm : persist) {
7661                out.startTag(null, TAG_URI_GRANT);
7662                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7663                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7664                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7665                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7666                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7667                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7668                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7669                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7670                out.endTag(null, TAG_URI_GRANT);
7671            }
7672            out.endTag(null, TAG_URI_GRANTS);
7673            out.endDocument();
7674
7675            mGrantFile.finishWrite(fos);
7676        } catch (IOException e) {
7677            if (fos != null) {
7678                mGrantFile.failWrite(fos);
7679            }
7680        }
7681    }
7682
7683    private void readGrantedUriPermissionsLocked() {
7684        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7685
7686        final long now = System.currentTimeMillis();
7687
7688        FileInputStream fis = null;
7689        try {
7690            fis = mGrantFile.openRead();
7691            final XmlPullParser in = Xml.newPullParser();
7692            in.setInput(fis, null);
7693
7694            int type;
7695            while ((type = in.next()) != END_DOCUMENT) {
7696                final String tag = in.getName();
7697                if (type == START_TAG) {
7698                    if (TAG_URI_GRANT.equals(tag)) {
7699                        final int sourceUserId;
7700                        final int targetUserId;
7701                        final int userHandle = readIntAttribute(in,
7702                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7703                        if (userHandle != UserHandle.USER_NULL) {
7704                            // For backwards compatibility.
7705                            sourceUserId = userHandle;
7706                            targetUserId = userHandle;
7707                        } else {
7708                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7709                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7710                        }
7711                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7712                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7713                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7714                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7715                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7716                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7717
7718                        // Sanity check that provider still belongs to source package
7719                        final ProviderInfo pi = getProviderInfoLocked(
7720                                uri.getAuthority(), sourceUserId);
7721                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7722                            int targetUid = -1;
7723                            try {
7724                                targetUid = AppGlobals.getPackageManager()
7725                                        .getPackageUid(targetPkg, targetUserId);
7726                            } catch (RemoteException e) {
7727                            }
7728                            if (targetUid != -1) {
7729                                final UriPermission perm = findOrCreateUriPermissionLocked(
7730                                        sourcePkg, targetPkg, targetUid,
7731                                        new GrantUri(sourceUserId, uri, prefix));
7732                                perm.initPersistedModes(modeFlags, createdTime);
7733                            }
7734                        } else {
7735                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7736                                    + " but instead found " + pi);
7737                        }
7738                    }
7739                }
7740            }
7741        } catch (FileNotFoundException e) {
7742            // Missing grants is okay
7743        } catch (IOException e) {
7744            Slog.wtf(TAG, "Failed reading Uri grants", e);
7745        } catch (XmlPullParserException e) {
7746            Slog.wtf(TAG, "Failed reading Uri grants", e);
7747        } finally {
7748            IoUtils.closeQuietly(fis);
7749        }
7750    }
7751
7752    /**
7753     * @param uri This uri must NOT contain an embedded userId.
7754     * @param userId The userId in which the uri is to be resolved.
7755     */
7756    @Override
7757    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7758        enforceNotIsolatedCaller("takePersistableUriPermission");
7759
7760        Preconditions.checkFlagsArgument(modeFlags,
7761                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7762
7763        synchronized (this) {
7764            final int callingUid = Binder.getCallingUid();
7765            boolean persistChanged = false;
7766            GrantUri grantUri = new GrantUri(userId, uri, false);
7767
7768            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7769                    new GrantUri(userId, uri, false));
7770            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7771                    new GrantUri(userId, uri, true));
7772
7773            final boolean exactValid = (exactPerm != null)
7774                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7775            final boolean prefixValid = (prefixPerm != null)
7776                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7777
7778            if (!(exactValid || prefixValid)) {
7779                throw new SecurityException("No persistable permission grants found for UID "
7780                        + callingUid + " and Uri " + grantUri.toSafeString());
7781            }
7782
7783            if (exactValid) {
7784                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7785            }
7786            if (prefixValid) {
7787                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7788            }
7789
7790            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7791
7792            if (persistChanged) {
7793                schedulePersistUriGrants();
7794            }
7795        }
7796    }
7797
7798    /**
7799     * @param uri This uri must NOT contain an embedded userId.
7800     * @param userId The userId in which the uri is to be resolved.
7801     */
7802    @Override
7803    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7804        enforceNotIsolatedCaller("releasePersistableUriPermission");
7805
7806        Preconditions.checkFlagsArgument(modeFlags,
7807                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7808
7809        synchronized (this) {
7810            final int callingUid = Binder.getCallingUid();
7811            boolean persistChanged = false;
7812
7813            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7814                    new GrantUri(userId, uri, false));
7815            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7816                    new GrantUri(userId, uri, true));
7817            if (exactPerm == null && prefixPerm == null) {
7818                throw new SecurityException("No permission grants found for UID " + callingUid
7819                        + " and Uri " + uri.toSafeString());
7820            }
7821
7822            if (exactPerm != null) {
7823                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7824                removeUriPermissionIfNeededLocked(exactPerm);
7825            }
7826            if (prefixPerm != null) {
7827                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7828                removeUriPermissionIfNeededLocked(prefixPerm);
7829            }
7830
7831            if (persistChanged) {
7832                schedulePersistUriGrants();
7833            }
7834        }
7835    }
7836
7837    /**
7838     * Prune any older {@link UriPermission} for the given UID until outstanding
7839     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7840     *
7841     * @return if any mutations occured that require persisting.
7842     */
7843    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7844        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7845        if (perms == null) return false;
7846        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7847
7848        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7849        for (UriPermission perm : perms.values()) {
7850            if (perm.persistedModeFlags != 0) {
7851                persisted.add(perm);
7852            }
7853        }
7854
7855        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7856        if (trimCount <= 0) return false;
7857
7858        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7859        for (int i = 0; i < trimCount; i++) {
7860            final UriPermission perm = persisted.get(i);
7861
7862            if (DEBUG_URI_PERMISSION) {
7863                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7864            }
7865
7866            perm.releasePersistableModes(~0);
7867            removeUriPermissionIfNeededLocked(perm);
7868        }
7869
7870        return true;
7871    }
7872
7873    @Override
7874    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7875            String packageName, boolean incoming) {
7876        enforceNotIsolatedCaller("getPersistedUriPermissions");
7877        Preconditions.checkNotNull(packageName, "packageName");
7878
7879        final int callingUid = Binder.getCallingUid();
7880        final IPackageManager pm = AppGlobals.getPackageManager();
7881        try {
7882            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7883            if (packageUid != callingUid) {
7884                throw new SecurityException(
7885                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7886            }
7887        } catch (RemoteException e) {
7888            throw new SecurityException("Failed to verify package name ownership");
7889        }
7890
7891        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7892        synchronized (this) {
7893            if (incoming) {
7894                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7895                        callingUid);
7896                if (perms == null) {
7897                    Slog.w(TAG, "No permission grants found for " + packageName);
7898                } else {
7899                    for (UriPermission perm : perms.values()) {
7900                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7901                            result.add(perm.buildPersistedPublicApiObject());
7902                        }
7903                    }
7904                }
7905            } else {
7906                final int size = mGrantedUriPermissions.size();
7907                for (int i = 0; i < size; i++) {
7908                    final ArrayMap<GrantUri, UriPermission> perms =
7909                            mGrantedUriPermissions.valueAt(i);
7910                    for (UriPermission perm : perms.values()) {
7911                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7912                            result.add(perm.buildPersistedPublicApiObject());
7913                        }
7914                    }
7915                }
7916            }
7917        }
7918        return new ParceledListSlice<android.content.UriPermission>(result);
7919    }
7920
7921    @Override
7922    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7923        synchronized (this) {
7924            ProcessRecord app =
7925                who != null ? getRecordForAppLocked(who) : null;
7926            if (app == null) return;
7927
7928            Message msg = Message.obtain();
7929            msg.what = WAIT_FOR_DEBUGGER_MSG;
7930            msg.obj = app;
7931            msg.arg1 = waiting ? 1 : 0;
7932            mHandler.sendMessage(msg);
7933        }
7934    }
7935
7936    @Override
7937    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7938        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7939        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7940        outInfo.availMem = Process.getFreeMemory();
7941        outInfo.totalMem = Process.getTotalMemory();
7942        outInfo.threshold = homeAppMem;
7943        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7944        outInfo.hiddenAppThreshold = cachedAppMem;
7945        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7946                ProcessList.SERVICE_ADJ);
7947        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7948                ProcessList.VISIBLE_APP_ADJ);
7949        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7950                ProcessList.FOREGROUND_APP_ADJ);
7951    }
7952
7953    // =========================================================
7954    // TASK MANAGEMENT
7955    // =========================================================
7956
7957    @Override
7958    public List<IAppTask> getAppTasks(String callingPackage) {
7959        int callingUid = Binder.getCallingUid();
7960        long ident = Binder.clearCallingIdentity();
7961
7962        synchronized(this) {
7963            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7964            try {
7965                if (localLOGV) Slog.v(TAG, "getAppTasks");
7966
7967                final int N = mRecentTasks.size();
7968                for (int i = 0; i < N; i++) {
7969                    TaskRecord tr = mRecentTasks.get(i);
7970                    // Skip tasks that do not match the caller.  We don't need to verify
7971                    // callingPackage, because we are also limiting to callingUid and know
7972                    // that will limit to the correct security sandbox.
7973                    if (tr.effectiveUid != callingUid) {
7974                        continue;
7975                    }
7976                    Intent intent = tr.getBaseIntent();
7977                    if (intent == null ||
7978                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7979                        continue;
7980                    }
7981                    ActivityManager.RecentTaskInfo taskInfo =
7982                            createRecentTaskInfoFromTaskRecord(tr);
7983                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7984                    list.add(taskImpl);
7985                }
7986            } finally {
7987                Binder.restoreCallingIdentity(ident);
7988            }
7989            return list;
7990        }
7991    }
7992
7993    @Override
7994    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7995        final int callingUid = Binder.getCallingUid();
7996        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7997
7998        synchronized(this) {
7999            if (localLOGV) Slog.v(
8000                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8001
8002            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8003                    callingUid);
8004
8005            // TODO: Improve with MRU list from all ActivityStacks.
8006            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8007        }
8008
8009        return list;
8010    }
8011
8012    TaskRecord getMostRecentTask() {
8013        return mRecentTasks.get(0);
8014    }
8015
8016    /**
8017     * Creates a new RecentTaskInfo from a TaskRecord.
8018     */
8019    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8020        // Update the task description to reflect any changes in the task stack
8021        tr.updateTaskDescription();
8022
8023        // Compose the recent task info
8024        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8025        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8026        rti.persistentId = tr.taskId;
8027        rti.baseIntent = new Intent(tr.getBaseIntent());
8028        rti.origActivity = tr.origActivity;
8029        rti.description = tr.lastDescription;
8030        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8031        rti.userId = tr.userId;
8032        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8033        rti.firstActiveTime = tr.firstActiveTime;
8034        rti.lastActiveTime = tr.lastActiveTime;
8035        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8036        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8037        return rti;
8038    }
8039
8040    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8041        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8042                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8043        if (!allowed) {
8044            if (checkPermission(android.Manifest.permission.GET_TASKS,
8045                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8046                // Temporary compatibility: some existing apps on the system image may
8047                // still be requesting the old permission and not switched to the new
8048                // one; if so, we'll still allow them full access.  This means we need
8049                // to see if they are holding the old permission and are a system app.
8050                try {
8051                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8052                        allowed = true;
8053                        Slog.w(TAG, caller + ": caller " + callingUid
8054                                + " is using old GET_TASKS but privileged; allowing");
8055                    }
8056                } catch (RemoteException e) {
8057                }
8058            }
8059        }
8060        if (!allowed) {
8061            Slog.w(TAG, caller + ": caller " + callingUid
8062                    + " does not hold GET_TASKS; limiting output");
8063        }
8064        return allowed;
8065    }
8066
8067    @Override
8068    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8069        final int callingUid = Binder.getCallingUid();
8070        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8071                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8072
8073        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8074        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8075        synchronized (this) {
8076            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8077                    callingUid);
8078            final boolean detailed = checkCallingPermission(
8079                    android.Manifest.permission.GET_DETAILED_TASKS)
8080                    == PackageManager.PERMISSION_GRANTED;
8081
8082            final int N = mRecentTasks.size();
8083            ArrayList<ActivityManager.RecentTaskInfo> res
8084                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8085                            maxNum < N ? maxNum : N);
8086
8087            final Set<Integer> includedUsers;
8088            if (includeProfiles) {
8089                includedUsers = getProfileIdsLocked(userId);
8090            } else {
8091                includedUsers = new HashSet<Integer>();
8092            }
8093            includedUsers.add(Integer.valueOf(userId));
8094
8095            for (int i=0; i<N && maxNum > 0; i++) {
8096                TaskRecord tr = mRecentTasks.get(i);
8097                // Only add calling user or related users recent tasks
8098                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8099                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8100                    continue;
8101                }
8102
8103                // Return the entry if desired by the caller.  We always return
8104                // the first entry, because callers always expect this to be the
8105                // foreground app.  We may filter others if the caller has
8106                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8107                // we should exclude the entry.
8108
8109                if (i == 0
8110                        || withExcluded
8111                        || (tr.intent == null)
8112                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8113                                == 0)) {
8114                    if (!allowed) {
8115                        // If the caller doesn't have the GET_TASKS permission, then only
8116                        // allow them to see a small subset of tasks -- their own and home.
8117                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8118                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8119                            continue;
8120                        }
8121                    }
8122                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8123                        if (tr.stack != null && tr.stack.isHomeStack()) {
8124                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8125                            continue;
8126                        }
8127                    }
8128                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8129                        // Don't include auto remove tasks that are finished or finishing.
8130                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8131                                + tr);
8132                        continue;
8133                    }
8134                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8135                            && !tr.isAvailable) {
8136                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8137                        continue;
8138                    }
8139
8140                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8141                    if (!detailed) {
8142                        rti.baseIntent.replaceExtras((Bundle)null);
8143                    }
8144
8145                    res.add(rti);
8146                    maxNum--;
8147                }
8148            }
8149            return res;
8150        }
8151    }
8152
8153    private TaskRecord recentTaskForIdLocked(int id) {
8154        final int N = mRecentTasks.size();
8155            for (int i=0; i<N; i++) {
8156                TaskRecord tr = mRecentTasks.get(i);
8157                if (tr.taskId == id) {
8158                    return tr;
8159                }
8160            }
8161            return null;
8162    }
8163
8164    @Override
8165    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8166        synchronized (this) {
8167            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8168                    "getTaskThumbnail()");
8169            TaskRecord tr = recentTaskForIdLocked(id);
8170            if (tr != null) {
8171                return tr.getTaskThumbnailLocked();
8172            }
8173        }
8174        return null;
8175    }
8176
8177    @Override
8178    public int addAppTask(IBinder activityToken, Intent intent,
8179            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8180        final int callingUid = Binder.getCallingUid();
8181        final long callingIdent = Binder.clearCallingIdentity();
8182
8183        try {
8184            synchronized (this) {
8185                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8186                if (r == null) {
8187                    throw new IllegalArgumentException("Activity does not exist; token="
8188                            + activityToken);
8189                }
8190                ComponentName comp = intent.getComponent();
8191                if (comp == null) {
8192                    throw new IllegalArgumentException("Intent " + intent
8193                            + " must specify explicit component");
8194                }
8195                if (thumbnail.getWidth() != mThumbnailWidth
8196                        || thumbnail.getHeight() != mThumbnailHeight) {
8197                    throw new IllegalArgumentException("Bad thumbnail size: got "
8198                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8199                            + mThumbnailWidth + "x" + mThumbnailHeight);
8200                }
8201                if (intent.getSelector() != null) {
8202                    intent.setSelector(null);
8203                }
8204                if (intent.getSourceBounds() != null) {
8205                    intent.setSourceBounds(null);
8206                }
8207                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8208                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8209                        // The caller has added this as an auto-remove task...  that makes no
8210                        // sense, so turn off auto-remove.
8211                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8212                    }
8213                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8214                    // Must be a new task.
8215                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8216                }
8217                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8218                    mLastAddedTaskActivity = null;
8219                }
8220                ActivityInfo ainfo = mLastAddedTaskActivity;
8221                if (ainfo == null) {
8222                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8223                            comp, 0, UserHandle.getUserId(callingUid));
8224                    if (ainfo.applicationInfo.uid != callingUid) {
8225                        throw new SecurityException(
8226                                "Can't add task for another application: target uid="
8227                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8228                    }
8229                }
8230
8231                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8232                        intent, description);
8233
8234                int trimIdx = trimRecentsForTask(task, false);
8235                if (trimIdx >= 0) {
8236                    // If this would have caused a trim, then we'll abort because that
8237                    // means it would be added at the end of the list but then just removed.
8238                    return -1;
8239                }
8240
8241                final int N = mRecentTasks.size();
8242                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8243                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8244                    tr.removedFromRecents(mTaskPersister);
8245                }
8246
8247                task.inRecents = true;
8248                mRecentTasks.add(task);
8249                r.task.stack.addTask(task, false, false);
8250
8251                task.setLastThumbnail(thumbnail);
8252                task.freeLastThumbnail();
8253
8254                return task.taskId;
8255            }
8256        } finally {
8257            Binder.restoreCallingIdentity(callingIdent);
8258        }
8259    }
8260
8261    @Override
8262    public Point getAppTaskThumbnailSize() {
8263        synchronized (this) {
8264            return new Point(mThumbnailWidth,  mThumbnailHeight);
8265        }
8266    }
8267
8268    @Override
8269    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8270        synchronized (this) {
8271            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8272            if (r != null) {
8273                r.setTaskDescription(td);
8274                r.task.updateTaskDescription();
8275            }
8276        }
8277    }
8278
8279    @Override
8280    public Bitmap getTaskDescriptionIcon(String filename) {
8281        if (!FileUtils.isValidExtFilename(filename)
8282                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8283            throw new IllegalArgumentException("Bad filename: " + filename);
8284        }
8285        return mTaskPersister.getTaskDescriptionIcon(filename);
8286    }
8287
8288    @Override
8289    public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8290            throws RemoteException {
8291        if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8292                opts.getCustomInPlaceResId() == 0) {
8293            throw new IllegalArgumentException("Expected in-place ActivityOption " +
8294                    "with valid animation");
8295        }
8296        mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8297        mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8298                opts.getCustomInPlaceResId());
8299        mWindowManager.executeAppTransition();
8300    }
8301
8302    private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8303        mRecentTasks.remove(tr);
8304        tr.removedFromRecents(mTaskPersister);
8305        ComponentName component = tr.getBaseIntent().getComponent();
8306        if (component == null) {
8307            Slog.w(TAG, "No component for base intent of task: " + tr);
8308            return;
8309        }
8310
8311        if (!killProcess) {
8312            return;
8313        }
8314
8315        // Determine if the process(es) for this task should be killed.
8316        final String pkg = component.getPackageName();
8317        ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8318        ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8319        for (int i = 0; i < pmap.size(); i++) {
8320
8321            SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8322            for (int j = 0; j < uids.size(); j++) {
8323                ProcessRecord proc = uids.valueAt(j);
8324                if (proc.userId != tr.userId) {
8325                    // Don't kill process for a different user.
8326                    continue;
8327                }
8328                if (proc == mHomeProcess) {
8329                    // Don't kill the home process along with tasks from the same package.
8330                    continue;
8331                }
8332                if (!proc.pkgList.containsKey(pkg)) {
8333                    // Don't kill process that is not associated with this task.
8334                    continue;
8335                }
8336
8337                for (int k = 0; k < proc.activities.size(); k++) {
8338                    TaskRecord otherTask = proc.activities.get(k).task;
8339                    if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8340                        // Don't kill process(es) that has an activity in a different task that is
8341                        // also in recents.
8342                        return;
8343                    }
8344                }
8345
8346                // Add process to kill list.
8347                procsToKill.add(proc);
8348            }
8349        }
8350
8351        // Find any running services associated with this app and stop if needed.
8352        mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8353
8354        // Kill the running processes.
8355        for (int i = 0; i < procsToKill.size(); i++) {
8356            ProcessRecord pr = procsToKill.get(i);
8357            if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8358                pr.kill("remove task", true);
8359            } else {
8360                pr.waitingToKill = "remove task";
8361            }
8362        }
8363    }
8364
8365    /**
8366     * Removes the task with the specified task id.
8367     *
8368     * @param taskId Identifier of the task to be removed.
8369     * @param killProcess Kill any process associated with the task if possible.
8370     * @return Returns true if the given task was found and removed.
8371     */
8372    private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8373        TaskRecord tr = recentTaskForIdLocked(taskId);
8374        if (tr != null) {
8375            tr.removeTaskActivitiesLocked();
8376            cleanUpRemovedTaskLocked(tr, killProcess);
8377            if (tr.isPersistable) {
8378                notifyTaskPersisterLocked(null, true);
8379            }
8380            return true;
8381        }
8382        return false;
8383    }
8384
8385    @Override
8386    public boolean removeTask(int taskId) {
8387        synchronized (this) {
8388            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8389                    "removeTask()");
8390            long ident = Binder.clearCallingIdentity();
8391            try {
8392                return removeTaskByIdLocked(taskId, true);
8393            } finally {
8394                Binder.restoreCallingIdentity(ident);
8395            }
8396        }
8397    }
8398
8399    /**
8400     * TODO: Add mController hook
8401     */
8402    @Override
8403    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8404        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8405                "moveTaskToFront()");
8406
8407        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8408        synchronized(this) {
8409            moveTaskToFrontLocked(taskId, flags, options);
8410        }
8411    }
8412
8413    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8414        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8415                Binder.getCallingUid(), -1, -1, "Task to front")) {
8416            ActivityOptions.abort(options);
8417            return;
8418        }
8419        final long origId = Binder.clearCallingIdentity();
8420        try {
8421            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8422            if (task == null) {
8423                return;
8424            }
8425            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8426                mStackSupervisor.showLockTaskToast();
8427                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8428                return;
8429            }
8430            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8431            if (prev != null && prev.isRecentsActivity()) {
8432                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8433            }
8434            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8435        } finally {
8436            Binder.restoreCallingIdentity(origId);
8437        }
8438        ActivityOptions.abort(options);
8439    }
8440
8441    @Override
8442    public void moveTaskToBack(int taskId) {
8443        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8444                "moveTaskToBack()");
8445
8446        synchronized(this) {
8447            TaskRecord tr = recentTaskForIdLocked(taskId);
8448            if (tr != null) {
8449                if (tr == mStackSupervisor.mLockTaskModeTask) {
8450                    mStackSupervisor.showLockTaskToast();
8451                    return;
8452                }
8453                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8454                ActivityStack stack = tr.stack;
8455                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8456                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8457                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8458                        return;
8459                    }
8460                }
8461                final long origId = Binder.clearCallingIdentity();
8462                try {
8463                    stack.moveTaskToBackLocked(taskId, null);
8464                } finally {
8465                    Binder.restoreCallingIdentity(origId);
8466                }
8467            }
8468        }
8469    }
8470
8471    /**
8472     * Moves an activity, and all of the other activities within the same task, to the bottom
8473     * of the history stack.  The activity's order within the task is unchanged.
8474     *
8475     * @param token A reference to the activity we wish to move
8476     * @param nonRoot If false then this only works if the activity is the root
8477     *                of a task; if true it will work for any activity in a task.
8478     * @return Returns true if the move completed, false if not.
8479     */
8480    @Override
8481    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8482        enforceNotIsolatedCaller("moveActivityTaskToBack");
8483        synchronized(this) {
8484            final long origId = Binder.clearCallingIdentity();
8485            try {
8486                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8487                if (taskId >= 0) {
8488                    if ((mStackSupervisor.mLockTaskModeTask != null)
8489                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8490                        mStackSupervisor.showLockTaskToast();
8491                        return false;
8492                    }
8493                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8494                }
8495            } finally {
8496                Binder.restoreCallingIdentity(origId);
8497            }
8498        }
8499        return false;
8500    }
8501
8502    @Override
8503    public void moveTaskBackwards(int task) {
8504        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8505                "moveTaskBackwards()");
8506
8507        synchronized(this) {
8508            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8509                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8510                return;
8511            }
8512            final long origId = Binder.clearCallingIdentity();
8513            moveTaskBackwardsLocked(task);
8514            Binder.restoreCallingIdentity(origId);
8515        }
8516    }
8517
8518    private final void moveTaskBackwardsLocked(int task) {
8519        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8520    }
8521
8522    @Override
8523    public IBinder getHomeActivityToken() throws RemoteException {
8524        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8525                "getHomeActivityToken()");
8526        synchronized (this) {
8527            return mStackSupervisor.getHomeActivityToken();
8528        }
8529    }
8530
8531    @Override
8532    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8533            IActivityContainerCallback callback) throws RemoteException {
8534        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8535                "createActivityContainer()");
8536        synchronized (this) {
8537            if (parentActivityToken == null) {
8538                throw new IllegalArgumentException("parent token must not be null");
8539            }
8540            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8541            if (r == null) {
8542                return null;
8543            }
8544            if (callback == null) {
8545                throw new IllegalArgumentException("callback must not be null");
8546            }
8547            return mStackSupervisor.createActivityContainer(r, callback);
8548        }
8549    }
8550
8551    @Override
8552    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8553        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8554                "deleteActivityContainer()");
8555        synchronized (this) {
8556            mStackSupervisor.deleteActivityContainer(container);
8557        }
8558    }
8559
8560    @Override
8561    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8562            throws RemoteException {
8563        synchronized (this) {
8564            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8565            if (stack != null) {
8566                return stack.mActivityContainer;
8567            }
8568            return null;
8569        }
8570    }
8571
8572    @Override
8573    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8574        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8575                "moveTaskToStack()");
8576        if (stackId == HOME_STACK_ID) {
8577            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8578                    new RuntimeException("here").fillInStackTrace());
8579        }
8580        synchronized (this) {
8581            long ident = Binder.clearCallingIdentity();
8582            try {
8583                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8584                        + stackId + " toTop=" + toTop);
8585                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8586            } finally {
8587                Binder.restoreCallingIdentity(ident);
8588            }
8589        }
8590    }
8591
8592    @Override
8593    public void resizeStack(int stackBoxId, Rect bounds) {
8594        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8595                "resizeStackBox()");
8596        long ident = Binder.clearCallingIdentity();
8597        try {
8598            mWindowManager.resizeStack(stackBoxId, bounds);
8599        } finally {
8600            Binder.restoreCallingIdentity(ident);
8601        }
8602    }
8603
8604    @Override
8605    public List<StackInfo> getAllStackInfos() {
8606        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8607                "getAllStackInfos()");
8608        long ident = Binder.clearCallingIdentity();
8609        try {
8610            synchronized (this) {
8611                return mStackSupervisor.getAllStackInfosLocked();
8612            }
8613        } finally {
8614            Binder.restoreCallingIdentity(ident);
8615        }
8616    }
8617
8618    @Override
8619    public StackInfo getStackInfo(int stackId) {
8620        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8621                "getStackInfo()");
8622        long ident = Binder.clearCallingIdentity();
8623        try {
8624            synchronized (this) {
8625                return mStackSupervisor.getStackInfoLocked(stackId);
8626            }
8627        } finally {
8628            Binder.restoreCallingIdentity(ident);
8629        }
8630    }
8631
8632    @Override
8633    public boolean isInHomeStack(int taskId) {
8634        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8635                "getStackInfo()");
8636        long ident = Binder.clearCallingIdentity();
8637        try {
8638            synchronized (this) {
8639                TaskRecord tr = recentTaskForIdLocked(taskId);
8640                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8641            }
8642        } finally {
8643            Binder.restoreCallingIdentity(ident);
8644        }
8645    }
8646
8647    @Override
8648    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8649        synchronized(this) {
8650            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8651        }
8652    }
8653
8654    private boolean isLockTaskAuthorized(String pkg) {
8655        final DevicePolicyManager dpm = (DevicePolicyManager)
8656                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8657        try {
8658            int uid = mContext.getPackageManager().getPackageUid(pkg,
8659                    Binder.getCallingUserHandle().getIdentifier());
8660            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8661        } catch (NameNotFoundException e) {
8662            return false;
8663        }
8664    }
8665
8666    void startLockTaskMode(TaskRecord task) {
8667        final String pkg;
8668        synchronized (this) {
8669            pkg = task.intent.getComponent().getPackageName();
8670        }
8671        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8672        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8673            final TaskRecord taskRecord = task;
8674            mHandler.post(new Runnable() {
8675                @Override
8676                public void run() {
8677                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8678                }
8679            });
8680            return;
8681        }
8682        long ident = Binder.clearCallingIdentity();
8683        try {
8684            synchronized (this) {
8685                // Since we lost lock on task, make sure it is still there.
8686                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8687                if (task != null) {
8688                    if (!isSystemInitiated
8689                            && ((mStackSupervisor.getFocusedStack() == null)
8690                                    || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8691                        throw new IllegalArgumentException("Invalid task, not in foreground");
8692                    }
8693                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8694                }
8695            }
8696        } finally {
8697            Binder.restoreCallingIdentity(ident);
8698        }
8699    }
8700
8701    @Override
8702    public void startLockTaskMode(int taskId) {
8703        final TaskRecord task;
8704        long ident = Binder.clearCallingIdentity();
8705        try {
8706            synchronized (this) {
8707                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8708            }
8709        } finally {
8710            Binder.restoreCallingIdentity(ident);
8711        }
8712        if (task != null) {
8713            startLockTaskMode(task);
8714        }
8715    }
8716
8717    @Override
8718    public void startLockTaskMode(IBinder token) {
8719        final TaskRecord task;
8720        long ident = Binder.clearCallingIdentity();
8721        try {
8722            synchronized (this) {
8723                final ActivityRecord r = ActivityRecord.forToken(token);
8724                if (r == null) {
8725                    return;
8726                }
8727                task = r.task;
8728            }
8729        } finally {
8730            Binder.restoreCallingIdentity(ident);
8731        }
8732        if (task != null) {
8733            startLockTaskMode(task);
8734        }
8735    }
8736
8737    @Override
8738    public void startLockTaskModeOnCurrent() throws RemoteException {
8739        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8740                "startLockTaskModeOnCurrent");
8741        ActivityRecord r = null;
8742        synchronized (this) {
8743            r = mStackSupervisor.topRunningActivityLocked();
8744        }
8745        startLockTaskMode(r.task);
8746    }
8747
8748    @Override
8749    public void stopLockTaskMode() {
8750        // Verify that the user matches the package of the intent for the TaskRecord
8751        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8752        // and stopLockTaskMode.
8753        final int callingUid = Binder.getCallingUid();
8754        if (callingUid != Process.SYSTEM_UID) {
8755            try {
8756                String pkg =
8757                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8758                int uid = mContext.getPackageManager().getPackageUid(pkg,
8759                        Binder.getCallingUserHandle().getIdentifier());
8760                if (uid != callingUid) {
8761                    throw new SecurityException("Invalid uid, expected " + uid);
8762                }
8763            } catch (NameNotFoundException e) {
8764                Log.d(TAG, "stopLockTaskMode " + e);
8765                return;
8766            }
8767        }
8768        long ident = Binder.clearCallingIdentity();
8769        try {
8770            Log.d(TAG, "stopLockTaskMode");
8771            // Stop lock task
8772            synchronized (this) {
8773                mStackSupervisor.setLockTaskModeLocked(null, false);
8774            }
8775        } finally {
8776            Binder.restoreCallingIdentity(ident);
8777        }
8778    }
8779
8780    @Override
8781    public void stopLockTaskModeOnCurrent() throws RemoteException {
8782        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8783                "stopLockTaskModeOnCurrent");
8784        long ident = Binder.clearCallingIdentity();
8785        try {
8786            stopLockTaskMode();
8787        } finally {
8788            Binder.restoreCallingIdentity(ident);
8789        }
8790    }
8791
8792    @Override
8793    public boolean isInLockTaskMode() {
8794        synchronized (this) {
8795            return mStackSupervisor.isInLockTaskMode();
8796        }
8797    }
8798
8799    // =========================================================
8800    // CONTENT PROVIDERS
8801    // =========================================================
8802
8803    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8804        List<ProviderInfo> providers = null;
8805        try {
8806            providers = AppGlobals.getPackageManager().
8807                queryContentProviders(app.processName, app.uid,
8808                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8809        } catch (RemoteException ex) {
8810        }
8811        if (DEBUG_MU)
8812            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8813        int userId = app.userId;
8814        if (providers != null) {
8815            int N = providers.size();
8816            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8817            for (int i=0; i<N; i++) {
8818                ProviderInfo cpi =
8819                    (ProviderInfo)providers.get(i);
8820                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8821                        cpi.name, cpi.flags);
8822                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8823                    // This is a singleton provider, but a user besides the
8824                    // default user is asking to initialize a process it runs
8825                    // in...  well, no, it doesn't actually run in this process,
8826                    // it runs in the process of the default user.  Get rid of it.
8827                    providers.remove(i);
8828                    N--;
8829                    i--;
8830                    continue;
8831                }
8832
8833                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8834                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8835                if (cpr == null) {
8836                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8837                    mProviderMap.putProviderByClass(comp, cpr);
8838                }
8839                if (DEBUG_MU)
8840                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8841                app.pubProviders.put(cpi.name, cpr);
8842                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8843                    // Don't add this if it is a platform component that is marked
8844                    // to run in multiple processes, because this is actually
8845                    // part of the framework so doesn't make sense to track as a
8846                    // separate apk in the process.
8847                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8848                            mProcessStats);
8849                }
8850                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8851            }
8852        }
8853        return providers;
8854    }
8855
8856    /**
8857     * Check if {@link ProcessRecord} has a possible chance at accessing the
8858     * given {@link ProviderInfo}. Final permission checking is always done
8859     * in {@link ContentProvider}.
8860     */
8861    private final String checkContentProviderPermissionLocked(
8862            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8863        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8864        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8865        boolean checkedGrants = false;
8866        if (checkUser) {
8867            // Looking for cross-user grants before enforcing the typical cross-users permissions
8868            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8869            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8870                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8871                    return null;
8872                }
8873                checkedGrants = true;
8874            }
8875            userId = handleIncomingUser(callingPid, callingUid, userId,
8876                    false, ALLOW_NON_FULL,
8877                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8878            if (userId != tmpTargetUserId) {
8879                // When we actually went to determine the final targer user ID, this ended
8880                // up different than our initial check for the authority.  This is because
8881                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8882                // SELF.  So we need to re-check the grants again.
8883                checkedGrants = false;
8884            }
8885        }
8886        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8887                cpi.applicationInfo.uid, cpi.exported)
8888                == PackageManager.PERMISSION_GRANTED) {
8889            return null;
8890        }
8891        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8892                cpi.applicationInfo.uid, cpi.exported)
8893                == PackageManager.PERMISSION_GRANTED) {
8894            return null;
8895        }
8896
8897        PathPermission[] pps = cpi.pathPermissions;
8898        if (pps != null) {
8899            int i = pps.length;
8900            while (i > 0) {
8901                i--;
8902                PathPermission pp = pps[i];
8903                String pprperm = pp.getReadPermission();
8904                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8905                        cpi.applicationInfo.uid, cpi.exported)
8906                        == PackageManager.PERMISSION_GRANTED) {
8907                    return null;
8908                }
8909                String ppwperm = pp.getWritePermission();
8910                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8911                        cpi.applicationInfo.uid, cpi.exported)
8912                        == PackageManager.PERMISSION_GRANTED) {
8913                    return null;
8914                }
8915            }
8916        }
8917        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8918            return null;
8919        }
8920
8921        String msg;
8922        if (!cpi.exported) {
8923            msg = "Permission Denial: opening provider " + cpi.name
8924                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8925                    + ", uid=" + callingUid + ") that is not exported from uid "
8926                    + cpi.applicationInfo.uid;
8927        } else {
8928            msg = "Permission Denial: opening provider " + cpi.name
8929                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8930                    + ", uid=" + callingUid + ") requires "
8931                    + cpi.readPermission + " or " + cpi.writePermission;
8932        }
8933        Slog.w(TAG, msg);
8934        return msg;
8935    }
8936
8937    /**
8938     * Returns if the ContentProvider has granted a uri to callingUid
8939     */
8940    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8941        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8942        if (perms != null) {
8943            for (int i=perms.size()-1; i>=0; i--) {
8944                GrantUri grantUri = perms.keyAt(i);
8945                if (grantUri.sourceUserId == userId || !checkUser) {
8946                    if (matchesProvider(grantUri.uri, cpi)) {
8947                        return true;
8948                    }
8949                }
8950            }
8951        }
8952        return false;
8953    }
8954
8955    /**
8956     * Returns true if the uri authority is one of the authorities specified in the provider.
8957     */
8958    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8959        String uriAuth = uri.getAuthority();
8960        String cpiAuth = cpi.authority;
8961        if (cpiAuth.indexOf(';') == -1) {
8962            return cpiAuth.equals(uriAuth);
8963        }
8964        String[] cpiAuths = cpiAuth.split(";");
8965        int length = cpiAuths.length;
8966        for (int i = 0; i < length; i++) {
8967            if (cpiAuths[i].equals(uriAuth)) return true;
8968        }
8969        return false;
8970    }
8971
8972    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8973            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8974        if (r != null) {
8975            for (int i=0; i<r.conProviders.size(); i++) {
8976                ContentProviderConnection conn = r.conProviders.get(i);
8977                if (conn.provider == cpr) {
8978                    if (DEBUG_PROVIDER) Slog.v(TAG,
8979                            "Adding provider requested by "
8980                            + r.processName + " from process "
8981                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8982                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8983                    if (stable) {
8984                        conn.stableCount++;
8985                        conn.numStableIncs++;
8986                    } else {
8987                        conn.unstableCount++;
8988                        conn.numUnstableIncs++;
8989                    }
8990                    return conn;
8991                }
8992            }
8993            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8994            if (stable) {
8995                conn.stableCount = 1;
8996                conn.numStableIncs = 1;
8997            } else {
8998                conn.unstableCount = 1;
8999                conn.numUnstableIncs = 1;
9000            }
9001            cpr.connections.add(conn);
9002            r.conProviders.add(conn);
9003            return conn;
9004        }
9005        cpr.addExternalProcessHandleLocked(externalProcessToken);
9006        return null;
9007    }
9008
9009    boolean decProviderCountLocked(ContentProviderConnection conn,
9010            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9011        if (conn != null) {
9012            cpr = conn.provider;
9013            if (DEBUG_PROVIDER) Slog.v(TAG,
9014                    "Removing provider requested by "
9015                    + conn.client.processName + " from process "
9016                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9017                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9018            if (stable) {
9019                conn.stableCount--;
9020            } else {
9021                conn.unstableCount--;
9022            }
9023            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9024                cpr.connections.remove(conn);
9025                conn.client.conProviders.remove(conn);
9026                return true;
9027            }
9028            return false;
9029        }
9030        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9031        return false;
9032    }
9033
9034    private void checkTime(long startTime, String where) {
9035        long now = SystemClock.elapsedRealtime();
9036        if ((now-startTime) > 1000) {
9037            // If we are taking more than a second, log about it.
9038            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9039        }
9040    }
9041
9042    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9043            String name, IBinder token, boolean stable, int userId) {
9044        ContentProviderRecord cpr;
9045        ContentProviderConnection conn = null;
9046        ProviderInfo cpi = null;
9047
9048        synchronized(this) {
9049            long startTime = SystemClock.elapsedRealtime();
9050
9051            ProcessRecord r = null;
9052            if (caller != null) {
9053                r = getRecordForAppLocked(caller);
9054                if (r == null) {
9055                    throw new SecurityException(
9056                            "Unable to find app for caller " + caller
9057                          + " (pid=" + Binder.getCallingPid()
9058                          + ") when getting content provider " + name);
9059                }
9060            }
9061
9062            boolean checkCrossUser = true;
9063
9064            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9065
9066            // First check if this content provider has been published...
9067            cpr = mProviderMap.getProviderByName(name, userId);
9068            // If that didn't work, check if it exists for user 0 and then
9069            // verify that it's a singleton provider before using it.
9070            if (cpr == null && userId != UserHandle.USER_OWNER) {
9071                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9072                if (cpr != null) {
9073                    cpi = cpr.info;
9074                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9075                            cpi.name, cpi.flags)
9076                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9077                        userId = UserHandle.USER_OWNER;
9078                        checkCrossUser = false;
9079                    } else {
9080                        cpr = null;
9081                        cpi = null;
9082                    }
9083                }
9084            }
9085
9086            boolean providerRunning = cpr != null;
9087            if (providerRunning) {
9088                cpi = cpr.info;
9089                String msg;
9090                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9091                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9092                        != null) {
9093                    throw new SecurityException(msg);
9094                }
9095                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9096
9097                if (r != null && cpr.canRunHere(r)) {
9098                    // This provider has been published or is in the process
9099                    // of being published...  but it is also allowed to run
9100                    // in the caller's process, so don't make a connection
9101                    // and just let the caller instantiate its own instance.
9102                    ContentProviderHolder holder = cpr.newHolder(null);
9103                    // don't give caller the provider object, it needs
9104                    // to make its own.
9105                    holder.provider = null;
9106                    return holder;
9107                }
9108
9109                final long origId = Binder.clearCallingIdentity();
9110
9111                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9112
9113                // In this case the provider instance already exists, so we can
9114                // return it right away.
9115                conn = incProviderCountLocked(r, cpr, token, stable);
9116                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9117                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9118                        // If this is a perceptible app accessing the provider,
9119                        // make sure to count it as being accessed and thus
9120                        // back up on the LRU list.  This is good because
9121                        // content providers are often expensive to start.
9122                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9123                        updateLruProcessLocked(cpr.proc, false, null);
9124                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9125                    }
9126                }
9127
9128                if (cpr.proc != null) {
9129                    if (false) {
9130                        if (cpr.name.flattenToShortString().equals(
9131                                "com.android.providers.calendar/.CalendarProvider2")) {
9132                            Slog.v(TAG, "****************** KILLING "
9133                                + cpr.name.flattenToShortString());
9134                            Process.killProcess(cpr.proc.pid);
9135                        }
9136                    }
9137                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9138                    boolean success = updateOomAdjLocked(cpr.proc);
9139                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9140                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9141                    // NOTE: there is still a race here where a signal could be
9142                    // pending on the process even though we managed to update its
9143                    // adj level.  Not sure what to do about this, but at least
9144                    // the race is now smaller.
9145                    if (!success) {
9146                        // Uh oh...  it looks like the provider's process
9147                        // has been killed on us.  We need to wait for a new
9148                        // process to be started, and make sure its death
9149                        // doesn't kill our process.
9150                        Slog.i(TAG,
9151                                "Existing provider " + cpr.name.flattenToShortString()
9152                                + " is crashing; detaching " + r);
9153                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9154                        checkTime(startTime, "getContentProviderImpl: before appDied");
9155                        appDiedLocked(cpr.proc);
9156                        checkTime(startTime, "getContentProviderImpl: after appDied");
9157                        if (!lastRef) {
9158                            // This wasn't the last ref our process had on
9159                            // the provider...  we have now been killed, bail.
9160                            return null;
9161                        }
9162                        providerRunning = false;
9163                        conn = null;
9164                    }
9165                }
9166
9167                Binder.restoreCallingIdentity(origId);
9168            }
9169
9170            boolean singleton;
9171            if (!providerRunning) {
9172                try {
9173                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9174                    cpi = AppGlobals.getPackageManager().
9175                        resolveContentProvider(name,
9176                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9177                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9178                } catch (RemoteException ex) {
9179                }
9180                if (cpi == null) {
9181                    return null;
9182                }
9183                // If the provider is a singleton AND
9184                // (it's a call within the same user || the provider is a
9185                // privileged app)
9186                // Then allow connecting to the singleton provider
9187                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9188                        cpi.name, cpi.flags)
9189                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9190                if (singleton) {
9191                    userId = UserHandle.USER_OWNER;
9192                }
9193                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9194                checkTime(startTime, "getContentProviderImpl: got app info for user");
9195
9196                String msg;
9197                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9198                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9199                        != null) {
9200                    throw new SecurityException(msg);
9201                }
9202                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9203
9204                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9205                        && !cpi.processName.equals("system")) {
9206                    // If this content provider does not run in the system
9207                    // process, and the system is not yet ready to run other
9208                    // processes, then fail fast instead of hanging.
9209                    throw new IllegalArgumentException(
9210                            "Attempt to launch content provider before system ready");
9211                }
9212
9213                // Make sure that the user who owns this provider is started.  If not,
9214                // we don't want to allow it to run.
9215                if (mStartedUsers.get(userId) == null) {
9216                    Slog.w(TAG, "Unable to launch app "
9217                            + cpi.applicationInfo.packageName + "/"
9218                            + cpi.applicationInfo.uid + " for provider "
9219                            + name + ": user " + userId + " is stopped");
9220                    return null;
9221                }
9222
9223                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9224                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9225                cpr = mProviderMap.getProviderByClass(comp, userId);
9226                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9227                final boolean firstClass = cpr == null;
9228                if (firstClass) {
9229                    final long ident = Binder.clearCallingIdentity();
9230                    try {
9231                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9232                        ApplicationInfo ai =
9233                            AppGlobals.getPackageManager().
9234                                getApplicationInfo(
9235                                        cpi.applicationInfo.packageName,
9236                                        STOCK_PM_FLAGS, userId);
9237                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9238                        if (ai == null) {
9239                            Slog.w(TAG, "No package info for content provider "
9240                                    + cpi.name);
9241                            return null;
9242                        }
9243                        ai = getAppInfoForUser(ai, userId);
9244                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9245                    } catch (RemoteException ex) {
9246                        // pm is in same process, this will never happen.
9247                    } finally {
9248                        Binder.restoreCallingIdentity(ident);
9249                    }
9250                }
9251
9252                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9253
9254                if (r != null && cpr.canRunHere(r)) {
9255                    // If this is a multiprocess provider, then just return its
9256                    // info and allow the caller to instantiate it.  Only do
9257                    // this if the provider is the same user as the caller's
9258                    // process, or can run as root (so can be in any process).
9259                    return cpr.newHolder(null);
9260                }
9261
9262                if (DEBUG_PROVIDER) {
9263                    RuntimeException e = new RuntimeException("here");
9264                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9265                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9266                }
9267
9268                // This is single process, and our app is now connecting to it.
9269                // See if we are already in the process of launching this
9270                // provider.
9271                final int N = mLaunchingProviders.size();
9272                int i;
9273                for (i=0; i<N; i++) {
9274                    if (mLaunchingProviders.get(i) == cpr) {
9275                        break;
9276                    }
9277                }
9278
9279                // If the provider is not already being launched, then get it
9280                // started.
9281                if (i >= N) {
9282                    final long origId = Binder.clearCallingIdentity();
9283
9284                    try {
9285                        // Content provider is now in use, its package can't be stopped.
9286                        try {
9287                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9288                            AppGlobals.getPackageManager().setPackageStoppedState(
9289                                    cpr.appInfo.packageName, false, userId);
9290                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9291                        } catch (RemoteException e) {
9292                        } catch (IllegalArgumentException e) {
9293                            Slog.w(TAG, "Failed trying to unstop package "
9294                                    + cpr.appInfo.packageName + ": " + e);
9295                        }
9296
9297                        // Use existing process if already started
9298                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9299                        ProcessRecord proc = getProcessRecordLocked(
9300                                cpi.processName, cpr.appInfo.uid, false);
9301                        if (proc != null && proc.thread != null) {
9302                            if (DEBUG_PROVIDER) {
9303                                Slog.d(TAG, "Installing in existing process " + proc);
9304                            }
9305                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9306                            proc.pubProviders.put(cpi.name, cpr);
9307                            try {
9308                                proc.thread.scheduleInstallProvider(cpi);
9309                            } catch (RemoteException e) {
9310                            }
9311                        } else {
9312                            checkTime(startTime, "getContentProviderImpl: before start process");
9313                            proc = startProcessLocked(cpi.processName,
9314                                    cpr.appInfo, false, 0, "content provider",
9315                                    new ComponentName(cpi.applicationInfo.packageName,
9316                                            cpi.name), false, false, false);
9317                            checkTime(startTime, "getContentProviderImpl: after start process");
9318                            if (proc == null) {
9319                                Slog.w(TAG, "Unable to launch app "
9320                                        + cpi.applicationInfo.packageName + "/"
9321                                        + cpi.applicationInfo.uid + " for provider "
9322                                        + name + ": process is bad");
9323                                return null;
9324                            }
9325                        }
9326                        cpr.launchingApp = proc;
9327                        mLaunchingProviders.add(cpr);
9328                    } finally {
9329                        Binder.restoreCallingIdentity(origId);
9330                    }
9331                }
9332
9333                checkTime(startTime, "getContentProviderImpl: updating data structures");
9334
9335                // Make sure the provider is published (the same provider class
9336                // may be published under multiple names).
9337                if (firstClass) {
9338                    mProviderMap.putProviderByClass(comp, cpr);
9339                }
9340
9341                mProviderMap.putProviderByName(name, cpr);
9342                conn = incProviderCountLocked(r, cpr, token, stable);
9343                if (conn != null) {
9344                    conn.waiting = true;
9345                }
9346            }
9347            checkTime(startTime, "getContentProviderImpl: done!");
9348        }
9349
9350        // Wait for the provider to be published...
9351        synchronized (cpr) {
9352            while (cpr.provider == null) {
9353                if (cpr.launchingApp == null) {
9354                    Slog.w(TAG, "Unable to launch app "
9355                            + cpi.applicationInfo.packageName + "/"
9356                            + cpi.applicationInfo.uid + " for provider "
9357                            + name + ": launching app became null");
9358                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9359                            UserHandle.getUserId(cpi.applicationInfo.uid),
9360                            cpi.applicationInfo.packageName,
9361                            cpi.applicationInfo.uid, name);
9362                    return null;
9363                }
9364                try {
9365                    if (DEBUG_MU) {
9366                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9367                                + cpr.launchingApp);
9368                    }
9369                    if (conn != null) {
9370                        conn.waiting = true;
9371                    }
9372                    cpr.wait();
9373                } catch (InterruptedException ex) {
9374                } finally {
9375                    if (conn != null) {
9376                        conn.waiting = false;
9377                    }
9378                }
9379            }
9380        }
9381        return cpr != null ? cpr.newHolder(conn) : null;
9382    }
9383
9384    @Override
9385    public final ContentProviderHolder getContentProvider(
9386            IApplicationThread caller, String name, int userId, boolean stable) {
9387        enforceNotIsolatedCaller("getContentProvider");
9388        if (caller == null) {
9389            String msg = "null IApplicationThread when getting content provider "
9390                    + name;
9391            Slog.w(TAG, msg);
9392            throw new SecurityException(msg);
9393        }
9394        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9395        // with cross-user grant.
9396        return getContentProviderImpl(caller, name, null, stable, userId);
9397    }
9398
9399    public ContentProviderHolder getContentProviderExternal(
9400            String name, int userId, IBinder token) {
9401        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9402            "Do not have permission in call getContentProviderExternal()");
9403        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9404                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9405        return getContentProviderExternalUnchecked(name, token, userId);
9406    }
9407
9408    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9409            IBinder token, int userId) {
9410        return getContentProviderImpl(null, name, token, true, userId);
9411    }
9412
9413    /**
9414     * Drop a content provider from a ProcessRecord's bookkeeping
9415     */
9416    public void removeContentProvider(IBinder connection, boolean stable) {
9417        enforceNotIsolatedCaller("removeContentProvider");
9418        long ident = Binder.clearCallingIdentity();
9419        try {
9420            synchronized (this) {
9421                ContentProviderConnection conn;
9422                try {
9423                    conn = (ContentProviderConnection)connection;
9424                } catch (ClassCastException e) {
9425                    String msg ="removeContentProvider: " + connection
9426                            + " not a ContentProviderConnection";
9427                    Slog.w(TAG, msg);
9428                    throw new IllegalArgumentException(msg);
9429                }
9430                if (conn == null) {
9431                    throw new NullPointerException("connection is null");
9432                }
9433                if (decProviderCountLocked(conn, null, null, stable)) {
9434                    updateOomAdjLocked();
9435                }
9436            }
9437        } finally {
9438            Binder.restoreCallingIdentity(ident);
9439        }
9440    }
9441
9442    public void removeContentProviderExternal(String name, IBinder token) {
9443        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9444            "Do not have permission in call removeContentProviderExternal()");
9445        int userId = UserHandle.getCallingUserId();
9446        long ident = Binder.clearCallingIdentity();
9447        try {
9448            removeContentProviderExternalUnchecked(name, token, userId);
9449        } finally {
9450            Binder.restoreCallingIdentity(ident);
9451        }
9452    }
9453
9454    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9455        synchronized (this) {
9456            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9457            if(cpr == null) {
9458                //remove from mProvidersByClass
9459                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9460                return;
9461            }
9462
9463            //update content provider record entry info
9464            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9465            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9466            if (localCpr.hasExternalProcessHandles()) {
9467                if (localCpr.removeExternalProcessHandleLocked(token)) {
9468                    updateOomAdjLocked();
9469                } else {
9470                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9471                            + " with no external reference for token: "
9472                            + token + ".");
9473                }
9474            } else {
9475                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9476                        + " with no external references.");
9477            }
9478        }
9479    }
9480
9481    public final void publishContentProviders(IApplicationThread caller,
9482            List<ContentProviderHolder> providers) {
9483        if (providers == null) {
9484            return;
9485        }
9486
9487        enforceNotIsolatedCaller("publishContentProviders");
9488        synchronized (this) {
9489            final ProcessRecord r = getRecordForAppLocked(caller);
9490            if (DEBUG_MU)
9491                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9492            if (r == null) {
9493                throw new SecurityException(
9494                        "Unable to find app for caller " + caller
9495                      + " (pid=" + Binder.getCallingPid()
9496                      + ") when publishing content providers");
9497            }
9498
9499            final long origId = Binder.clearCallingIdentity();
9500
9501            final int N = providers.size();
9502            for (int i=0; i<N; i++) {
9503                ContentProviderHolder src = providers.get(i);
9504                if (src == null || src.info == null || src.provider == null) {
9505                    continue;
9506                }
9507                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9508                if (DEBUG_MU)
9509                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9510                if (dst != null) {
9511                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9512                    mProviderMap.putProviderByClass(comp, dst);
9513                    String names[] = dst.info.authority.split(";");
9514                    for (int j = 0; j < names.length; j++) {
9515                        mProviderMap.putProviderByName(names[j], dst);
9516                    }
9517
9518                    int NL = mLaunchingProviders.size();
9519                    int j;
9520                    for (j=0; j<NL; j++) {
9521                        if (mLaunchingProviders.get(j) == dst) {
9522                            mLaunchingProviders.remove(j);
9523                            j--;
9524                            NL--;
9525                        }
9526                    }
9527                    synchronized (dst) {
9528                        dst.provider = src.provider;
9529                        dst.proc = r;
9530                        dst.notifyAll();
9531                    }
9532                    updateOomAdjLocked(r);
9533                }
9534            }
9535
9536            Binder.restoreCallingIdentity(origId);
9537        }
9538    }
9539
9540    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9541        ContentProviderConnection conn;
9542        try {
9543            conn = (ContentProviderConnection)connection;
9544        } catch (ClassCastException e) {
9545            String msg ="refContentProvider: " + connection
9546                    + " not a ContentProviderConnection";
9547            Slog.w(TAG, msg);
9548            throw new IllegalArgumentException(msg);
9549        }
9550        if (conn == null) {
9551            throw new NullPointerException("connection is null");
9552        }
9553
9554        synchronized (this) {
9555            if (stable > 0) {
9556                conn.numStableIncs += stable;
9557            }
9558            stable = conn.stableCount + stable;
9559            if (stable < 0) {
9560                throw new IllegalStateException("stableCount < 0: " + stable);
9561            }
9562
9563            if (unstable > 0) {
9564                conn.numUnstableIncs += unstable;
9565            }
9566            unstable = conn.unstableCount + unstable;
9567            if (unstable < 0) {
9568                throw new IllegalStateException("unstableCount < 0: " + unstable);
9569            }
9570
9571            if ((stable+unstable) <= 0) {
9572                throw new IllegalStateException("ref counts can't go to zero here: stable="
9573                        + stable + " unstable=" + unstable);
9574            }
9575            conn.stableCount = stable;
9576            conn.unstableCount = unstable;
9577            return !conn.dead;
9578        }
9579    }
9580
9581    public void unstableProviderDied(IBinder connection) {
9582        ContentProviderConnection conn;
9583        try {
9584            conn = (ContentProviderConnection)connection;
9585        } catch (ClassCastException e) {
9586            String msg ="refContentProvider: " + connection
9587                    + " not a ContentProviderConnection";
9588            Slog.w(TAG, msg);
9589            throw new IllegalArgumentException(msg);
9590        }
9591        if (conn == null) {
9592            throw new NullPointerException("connection is null");
9593        }
9594
9595        // Safely retrieve the content provider associated with the connection.
9596        IContentProvider provider;
9597        synchronized (this) {
9598            provider = conn.provider.provider;
9599        }
9600
9601        if (provider == null) {
9602            // Um, yeah, we're way ahead of you.
9603            return;
9604        }
9605
9606        // Make sure the caller is being honest with us.
9607        if (provider.asBinder().pingBinder()) {
9608            // Er, no, still looks good to us.
9609            synchronized (this) {
9610                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9611                        + " says " + conn + " died, but we don't agree");
9612                return;
9613            }
9614        }
9615
9616        // Well look at that!  It's dead!
9617        synchronized (this) {
9618            if (conn.provider.provider != provider) {
9619                // But something changed...  good enough.
9620                return;
9621            }
9622
9623            ProcessRecord proc = conn.provider.proc;
9624            if (proc == null || proc.thread == null) {
9625                // Seems like the process is already cleaned up.
9626                return;
9627            }
9628
9629            // As far as we're concerned, this is just like receiving a
9630            // death notification...  just a bit prematurely.
9631            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9632                    + ") early provider death");
9633            final long ident = Binder.clearCallingIdentity();
9634            try {
9635                appDiedLocked(proc);
9636            } finally {
9637                Binder.restoreCallingIdentity(ident);
9638            }
9639        }
9640    }
9641
9642    @Override
9643    public void appNotRespondingViaProvider(IBinder connection) {
9644        enforceCallingPermission(
9645                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9646
9647        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9648        if (conn == null) {
9649            Slog.w(TAG, "ContentProviderConnection is null");
9650            return;
9651        }
9652
9653        final ProcessRecord host = conn.provider.proc;
9654        if (host == null) {
9655            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9656            return;
9657        }
9658
9659        final long token = Binder.clearCallingIdentity();
9660        try {
9661            appNotResponding(host, null, null, false, "ContentProvider not responding");
9662        } finally {
9663            Binder.restoreCallingIdentity(token);
9664        }
9665    }
9666
9667    public final void installSystemProviders() {
9668        List<ProviderInfo> providers;
9669        synchronized (this) {
9670            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9671            providers = generateApplicationProvidersLocked(app);
9672            if (providers != null) {
9673                for (int i=providers.size()-1; i>=0; i--) {
9674                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9675                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9676                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9677                                + ": not system .apk");
9678                        providers.remove(i);
9679                    }
9680                }
9681            }
9682        }
9683        if (providers != null) {
9684            mSystemThread.installSystemProviders(providers);
9685        }
9686
9687        mCoreSettingsObserver = new CoreSettingsObserver(this);
9688
9689        //mUsageStatsService.monitorPackages();
9690    }
9691
9692    /**
9693     * Allows apps to retrieve the MIME type of a URI.
9694     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9695     * users, then it does not need permission to access the ContentProvider.
9696     * Either, it needs cross-user uri grants.
9697     *
9698     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9699     *
9700     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9701     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9702     */
9703    public String getProviderMimeType(Uri uri, int userId) {
9704        enforceNotIsolatedCaller("getProviderMimeType");
9705        final String name = uri.getAuthority();
9706        int callingUid = Binder.getCallingUid();
9707        int callingPid = Binder.getCallingPid();
9708        long ident = 0;
9709        boolean clearedIdentity = false;
9710        userId = unsafeConvertIncomingUser(userId);
9711        if (canClearIdentity(callingPid, callingUid, userId)) {
9712            clearedIdentity = true;
9713            ident = Binder.clearCallingIdentity();
9714        }
9715        ContentProviderHolder holder = null;
9716        try {
9717            holder = getContentProviderExternalUnchecked(name, null, userId);
9718            if (holder != null) {
9719                return holder.provider.getType(uri);
9720            }
9721        } catch (RemoteException e) {
9722            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9723            return null;
9724        } finally {
9725            // We need to clear the identity to call removeContentProviderExternalUnchecked
9726            if (!clearedIdentity) {
9727                ident = Binder.clearCallingIdentity();
9728            }
9729            try {
9730                if (holder != null) {
9731                    removeContentProviderExternalUnchecked(name, null, userId);
9732                }
9733            } finally {
9734                Binder.restoreCallingIdentity(ident);
9735            }
9736        }
9737
9738        return null;
9739    }
9740
9741    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9742        if (UserHandle.getUserId(callingUid) == userId) {
9743            return true;
9744        }
9745        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9746                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9747                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9748                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9749                return true;
9750        }
9751        return false;
9752    }
9753
9754    // =========================================================
9755    // GLOBAL MANAGEMENT
9756    // =========================================================
9757
9758    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9759            boolean isolated, int isolatedUid) {
9760        String proc = customProcess != null ? customProcess : info.processName;
9761        BatteryStatsImpl.Uid.Proc ps = null;
9762        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9763        int uid = info.uid;
9764        if (isolated) {
9765            if (isolatedUid == 0) {
9766                int userId = UserHandle.getUserId(uid);
9767                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9768                while (true) {
9769                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9770                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9771                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9772                    }
9773                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9774                    mNextIsolatedProcessUid++;
9775                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9776                        // No process for this uid, use it.
9777                        break;
9778                    }
9779                    stepsLeft--;
9780                    if (stepsLeft <= 0) {
9781                        return null;
9782                    }
9783                }
9784            } else {
9785                // Special case for startIsolatedProcess (internal only), where
9786                // the uid of the isolated process is specified by the caller.
9787                uid = isolatedUid;
9788            }
9789        }
9790        return new ProcessRecord(stats, info, proc, uid);
9791    }
9792
9793    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9794            String abiOverride) {
9795        ProcessRecord app;
9796        if (!isolated) {
9797            app = getProcessRecordLocked(info.processName, info.uid, true);
9798        } else {
9799            app = null;
9800        }
9801
9802        if (app == null) {
9803            app = newProcessRecordLocked(info, null, isolated, 0);
9804            mProcessNames.put(info.processName, app.uid, app);
9805            if (isolated) {
9806                mIsolatedProcesses.put(app.uid, app);
9807            }
9808            updateLruProcessLocked(app, false, null);
9809            updateOomAdjLocked();
9810        }
9811
9812        // This package really, really can not be stopped.
9813        try {
9814            AppGlobals.getPackageManager().setPackageStoppedState(
9815                    info.packageName, false, UserHandle.getUserId(app.uid));
9816        } catch (RemoteException e) {
9817        } catch (IllegalArgumentException e) {
9818            Slog.w(TAG, "Failed trying to unstop package "
9819                    + info.packageName + ": " + e);
9820        }
9821
9822        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9823                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9824            app.persistent = true;
9825            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9826        }
9827        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9828            mPersistentStartingProcesses.add(app);
9829            startProcessLocked(app, "added application", app.processName, abiOverride,
9830                    null /* entryPoint */, null /* entryPointArgs */);
9831        }
9832
9833        return app;
9834    }
9835
9836    public void unhandledBack() {
9837        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9838                "unhandledBack()");
9839
9840        synchronized(this) {
9841            final long origId = Binder.clearCallingIdentity();
9842            try {
9843                getFocusedStack().unhandledBackLocked();
9844            } finally {
9845                Binder.restoreCallingIdentity(origId);
9846            }
9847        }
9848    }
9849
9850    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9851        enforceNotIsolatedCaller("openContentUri");
9852        final int userId = UserHandle.getCallingUserId();
9853        String name = uri.getAuthority();
9854        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9855        ParcelFileDescriptor pfd = null;
9856        if (cph != null) {
9857            // We record the binder invoker's uid in thread-local storage before
9858            // going to the content provider to open the file.  Later, in the code
9859            // that handles all permissions checks, we look for this uid and use
9860            // that rather than the Activity Manager's own uid.  The effect is that
9861            // we do the check against the caller's permissions even though it looks
9862            // to the content provider like the Activity Manager itself is making
9863            // the request.
9864            sCallerIdentity.set(new Identity(
9865                    Binder.getCallingPid(), Binder.getCallingUid()));
9866            try {
9867                pfd = cph.provider.openFile(null, uri, "r", null);
9868            } catch (FileNotFoundException e) {
9869                // do nothing; pfd will be returned null
9870            } finally {
9871                // Ensure that whatever happens, we clean up the identity state
9872                sCallerIdentity.remove();
9873            }
9874
9875            // We've got the fd now, so we're done with the provider.
9876            removeContentProviderExternalUnchecked(name, null, userId);
9877        } else {
9878            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9879        }
9880        return pfd;
9881    }
9882
9883    // Actually is sleeping or shutting down or whatever else in the future
9884    // is an inactive state.
9885    public boolean isSleepingOrShuttingDown() {
9886        return isSleeping() || mShuttingDown;
9887    }
9888
9889    public boolean isSleeping() {
9890        return mSleeping;
9891    }
9892
9893    void goingToSleep() {
9894        synchronized(this) {
9895            mWentToSleep = true;
9896            goToSleepIfNeededLocked();
9897        }
9898    }
9899
9900    void finishRunningVoiceLocked() {
9901        if (mRunningVoice) {
9902            mRunningVoice = false;
9903            goToSleepIfNeededLocked();
9904        }
9905    }
9906
9907    void goToSleepIfNeededLocked() {
9908        if (mWentToSleep && !mRunningVoice) {
9909            if (!mSleeping) {
9910                mSleeping = true;
9911                mStackSupervisor.goingToSleepLocked();
9912
9913                // Initialize the wake times of all processes.
9914                checkExcessivePowerUsageLocked(false);
9915                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9916                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9917                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9918            }
9919        }
9920    }
9921
9922    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9923        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9924            // Never persist the home stack.
9925            return;
9926        }
9927        mTaskPersister.wakeup(task, flush);
9928    }
9929
9930    @Override
9931    public boolean shutdown(int timeout) {
9932        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9933                != PackageManager.PERMISSION_GRANTED) {
9934            throw new SecurityException("Requires permission "
9935                    + android.Manifest.permission.SHUTDOWN);
9936        }
9937
9938        boolean timedout = false;
9939
9940        synchronized(this) {
9941            mShuttingDown = true;
9942            updateEventDispatchingLocked();
9943            timedout = mStackSupervisor.shutdownLocked(timeout);
9944        }
9945
9946        mAppOpsService.shutdown();
9947        if (mUsageStatsService != null) {
9948            mUsageStatsService.prepareShutdown();
9949        }
9950        mBatteryStatsService.shutdown();
9951        synchronized (this) {
9952            mProcessStats.shutdownLocked();
9953        }
9954        notifyTaskPersisterLocked(null, true);
9955
9956        return timedout;
9957    }
9958
9959    public final void activitySlept(IBinder token) {
9960        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9961
9962        final long origId = Binder.clearCallingIdentity();
9963
9964        synchronized (this) {
9965            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9966            if (r != null) {
9967                mStackSupervisor.activitySleptLocked(r);
9968            }
9969        }
9970
9971        Binder.restoreCallingIdentity(origId);
9972    }
9973
9974    void logLockScreen(String msg) {
9975        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9976                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9977                mWentToSleep + " mSleeping=" + mSleeping);
9978    }
9979
9980    private void comeOutOfSleepIfNeededLocked() {
9981        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9982            if (mSleeping) {
9983                mSleeping = false;
9984                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9985            }
9986        }
9987    }
9988
9989    void wakingUp() {
9990        synchronized(this) {
9991            mWentToSleep = false;
9992            comeOutOfSleepIfNeededLocked();
9993        }
9994    }
9995
9996    void startRunningVoiceLocked() {
9997        if (!mRunningVoice) {
9998            mRunningVoice = true;
9999            comeOutOfSleepIfNeededLocked();
10000        }
10001    }
10002
10003    private void updateEventDispatchingLocked() {
10004        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10005    }
10006
10007    public void setLockScreenShown(boolean shown) {
10008        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10009                != PackageManager.PERMISSION_GRANTED) {
10010            throw new SecurityException("Requires permission "
10011                    + android.Manifest.permission.DEVICE_POWER);
10012        }
10013
10014        synchronized(this) {
10015            long ident = Binder.clearCallingIdentity();
10016            try {
10017                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10018                mLockScreenShown = shown;
10019                comeOutOfSleepIfNeededLocked();
10020            } finally {
10021                Binder.restoreCallingIdentity(ident);
10022            }
10023        }
10024    }
10025
10026    @Override
10027    public void stopAppSwitches() {
10028        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10029                != PackageManager.PERMISSION_GRANTED) {
10030            throw new SecurityException("Requires permission "
10031                    + android.Manifest.permission.STOP_APP_SWITCHES);
10032        }
10033
10034        synchronized(this) {
10035            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10036                    + APP_SWITCH_DELAY_TIME;
10037            mDidAppSwitch = false;
10038            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10039            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10040            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10041        }
10042    }
10043
10044    public void resumeAppSwitches() {
10045        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10046                != PackageManager.PERMISSION_GRANTED) {
10047            throw new SecurityException("Requires permission "
10048                    + android.Manifest.permission.STOP_APP_SWITCHES);
10049        }
10050
10051        synchronized(this) {
10052            // Note that we don't execute any pending app switches... we will
10053            // let those wait until either the timeout, or the next start
10054            // activity request.
10055            mAppSwitchesAllowedTime = 0;
10056        }
10057    }
10058
10059    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10060            int callingPid, int callingUid, String name) {
10061        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10062            return true;
10063        }
10064
10065        int perm = checkComponentPermission(
10066                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10067                sourceUid, -1, true);
10068        if (perm == PackageManager.PERMISSION_GRANTED) {
10069            return true;
10070        }
10071
10072        // If the actual IPC caller is different from the logical source, then
10073        // also see if they are allowed to control app switches.
10074        if (callingUid != -1 && callingUid != sourceUid) {
10075            perm = checkComponentPermission(
10076                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10077                    callingUid, -1, true);
10078            if (perm == PackageManager.PERMISSION_GRANTED) {
10079                return true;
10080            }
10081        }
10082
10083        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10084        return false;
10085    }
10086
10087    public void setDebugApp(String packageName, boolean waitForDebugger,
10088            boolean persistent) {
10089        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10090                "setDebugApp()");
10091
10092        long ident = Binder.clearCallingIdentity();
10093        try {
10094            // Note that this is not really thread safe if there are multiple
10095            // callers into it at the same time, but that's not a situation we
10096            // care about.
10097            if (persistent) {
10098                final ContentResolver resolver = mContext.getContentResolver();
10099                Settings.Global.putString(
10100                    resolver, Settings.Global.DEBUG_APP,
10101                    packageName);
10102                Settings.Global.putInt(
10103                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10104                    waitForDebugger ? 1 : 0);
10105            }
10106
10107            synchronized (this) {
10108                if (!persistent) {
10109                    mOrigDebugApp = mDebugApp;
10110                    mOrigWaitForDebugger = mWaitForDebugger;
10111                }
10112                mDebugApp = packageName;
10113                mWaitForDebugger = waitForDebugger;
10114                mDebugTransient = !persistent;
10115                if (packageName != null) {
10116                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10117                            false, UserHandle.USER_ALL, "set debug app");
10118                }
10119            }
10120        } finally {
10121            Binder.restoreCallingIdentity(ident);
10122        }
10123    }
10124
10125    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10126        synchronized (this) {
10127            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10128            if (!isDebuggable) {
10129                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10130                    throw new SecurityException("Process not debuggable: " + app.packageName);
10131                }
10132            }
10133
10134            mOpenGlTraceApp = processName;
10135        }
10136    }
10137
10138    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10139        synchronized (this) {
10140            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10141            if (!isDebuggable) {
10142                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10143                    throw new SecurityException("Process not debuggable: " + app.packageName);
10144                }
10145            }
10146            mProfileApp = processName;
10147            mProfileFile = profilerInfo.profileFile;
10148            if (mProfileFd != null) {
10149                try {
10150                    mProfileFd.close();
10151                } catch (IOException e) {
10152                }
10153                mProfileFd = null;
10154            }
10155            mProfileFd = profilerInfo.profileFd;
10156            mSamplingInterval = profilerInfo.samplingInterval;
10157            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10158            mProfileType = 0;
10159        }
10160    }
10161
10162    @Override
10163    public void setAlwaysFinish(boolean enabled) {
10164        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10165                "setAlwaysFinish()");
10166
10167        Settings.Global.putInt(
10168                mContext.getContentResolver(),
10169                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10170
10171        synchronized (this) {
10172            mAlwaysFinishActivities = enabled;
10173        }
10174    }
10175
10176    @Override
10177    public void setActivityController(IActivityController controller) {
10178        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10179                "setActivityController()");
10180        synchronized (this) {
10181            mController = controller;
10182            Watchdog.getInstance().setActivityController(controller);
10183        }
10184    }
10185
10186    @Override
10187    public void setUserIsMonkey(boolean userIsMonkey) {
10188        synchronized (this) {
10189            synchronized (mPidsSelfLocked) {
10190                final int callingPid = Binder.getCallingPid();
10191                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10192                if (precessRecord == null) {
10193                    throw new SecurityException("Unknown process: " + callingPid);
10194                }
10195                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10196                    throw new SecurityException("Only an instrumentation process "
10197                            + "with a UiAutomation can call setUserIsMonkey");
10198                }
10199            }
10200            mUserIsMonkey = userIsMonkey;
10201        }
10202    }
10203
10204    @Override
10205    public boolean isUserAMonkey() {
10206        synchronized (this) {
10207            // If there is a controller also implies the user is a monkey.
10208            return (mUserIsMonkey || mController != null);
10209        }
10210    }
10211
10212    public void requestBugReport() {
10213        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10214        SystemProperties.set("ctl.start", "bugreport");
10215    }
10216
10217    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10218        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10219    }
10220
10221    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10222        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10223            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10224        }
10225        return KEY_DISPATCHING_TIMEOUT;
10226    }
10227
10228    @Override
10229    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10230        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10231                != PackageManager.PERMISSION_GRANTED) {
10232            throw new SecurityException("Requires permission "
10233                    + android.Manifest.permission.FILTER_EVENTS);
10234        }
10235        ProcessRecord proc;
10236        long timeout;
10237        synchronized (this) {
10238            synchronized (mPidsSelfLocked) {
10239                proc = mPidsSelfLocked.get(pid);
10240            }
10241            timeout = getInputDispatchingTimeoutLocked(proc);
10242        }
10243
10244        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10245            return -1;
10246        }
10247
10248        return timeout;
10249    }
10250
10251    /**
10252     * Handle input dispatching timeouts.
10253     * Returns whether input dispatching should be aborted or not.
10254     */
10255    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10256            final ActivityRecord activity, final ActivityRecord parent,
10257            final boolean aboveSystem, String reason) {
10258        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10259                != PackageManager.PERMISSION_GRANTED) {
10260            throw new SecurityException("Requires permission "
10261                    + android.Manifest.permission.FILTER_EVENTS);
10262        }
10263
10264        final String annotation;
10265        if (reason == null) {
10266            annotation = "Input dispatching timed out";
10267        } else {
10268            annotation = "Input dispatching timed out (" + reason + ")";
10269        }
10270
10271        if (proc != null) {
10272            synchronized (this) {
10273                if (proc.debugging) {
10274                    return false;
10275                }
10276
10277                if (mDidDexOpt) {
10278                    // Give more time since we were dexopting.
10279                    mDidDexOpt = false;
10280                    return false;
10281                }
10282
10283                if (proc.instrumentationClass != null) {
10284                    Bundle info = new Bundle();
10285                    info.putString("shortMsg", "keyDispatchingTimedOut");
10286                    info.putString("longMsg", annotation);
10287                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10288                    return true;
10289                }
10290            }
10291            mHandler.post(new Runnable() {
10292                @Override
10293                public void run() {
10294                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10295                }
10296            });
10297        }
10298
10299        return true;
10300    }
10301
10302    public Bundle getAssistContextExtras(int requestType) {
10303        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10304                UserHandle.getCallingUserId());
10305        if (pae == null) {
10306            return null;
10307        }
10308        synchronized (pae) {
10309            while (!pae.haveResult) {
10310                try {
10311                    pae.wait();
10312                } catch (InterruptedException e) {
10313                }
10314            }
10315            if (pae.result != null) {
10316                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10317            }
10318        }
10319        synchronized (this) {
10320            mPendingAssistExtras.remove(pae);
10321            mHandler.removeCallbacks(pae);
10322        }
10323        return pae.extras;
10324    }
10325
10326    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10327            int userHandle) {
10328        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10329                "getAssistContextExtras()");
10330        PendingAssistExtras pae;
10331        Bundle extras = new Bundle();
10332        synchronized (this) {
10333            ActivityRecord activity = getFocusedStack().mResumedActivity;
10334            if (activity == null) {
10335                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10336                return null;
10337            }
10338            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10339            if (activity.app == null || activity.app.thread == null) {
10340                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10341                return null;
10342            }
10343            if (activity.app.pid == Binder.getCallingPid()) {
10344                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10345                return null;
10346            }
10347            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10348            try {
10349                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10350                        requestType);
10351                mPendingAssistExtras.add(pae);
10352                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10353            } catch (RemoteException e) {
10354                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10355                return null;
10356            }
10357            return pae;
10358        }
10359    }
10360
10361    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10362        PendingAssistExtras pae = (PendingAssistExtras)token;
10363        synchronized (pae) {
10364            pae.result = extras;
10365            pae.haveResult = true;
10366            pae.notifyAll();
10367            if (pae.intent == null) {
10368                // Caller is just waiting for the result.
10369                return;
10370            }
10371        }
10372
10373        // We are now ready to launch the assist activity.
10374        synchronized (this) {
10375            boolean exists = mPendingAssistExtras.remove(pae);
10376            mHandler.removeCallbacks(pae);
10377            if (!exists) {
10378                // Timed out.
10379                return;
10380            }
10381        }
10382        pae.intent.replaceExtras(extras);
10383        if (pae.hint != null) {
10384            pae.intent.putExtra(pae.hint, true);
10385        }
10386        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10387                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10388                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10389        closeSystemDialogs("assist");
10390        try {
10391            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10392        } catch (ActivityNotFoundException e) {
10393            Slog.w(TAG, "No activity to handle assist action.", e);
10394        }
10395    }
10396
10397    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10398        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10399    }
10400
10401    public void registerProcessObserver(IProcessObserver observer) {
10402        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10403                "registerProcessObserver()");
10404        synchronized (this) {
10405            mProcessObservers.register(observer);
10406        }
10407    }
10408
10409    @Override
10410    public void unregisterProcessObserver(IProcessObserver observer) {
10411        synchronized (this) {
10412            mProcessObservers.unregister(observer);
10413        }
10414    }
10415
10416    @Override
10417    public boolean convertFromTranslucent(IBinder token) {
10418        final long origId = Binder.clearCallingIdentity();
10419        try {
10420            synchronized (this) {
10421                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10422                if (r == null) {
10423                    return false;
10424                }
10425                final boolean translucentChanged = r.changeWindowTranslucency(true);
10426                if (translucentChanged) {
10427                    r.task.stack.releaseBackgroundResources();
10428                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10429                }
10430                mWindowManager.setAppFullscreen(token, true);
10431                return translucentChanged;
10432            }
10433        } finally {
10434            Binder.restoreCallingIdentity(origId);
10435        }
10436    }
10437
10438    @Override
10439    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10440        final long origId = Binder.clearCallingIdentity();
10441        try {
10442            synchronized (this) {
10443                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10444                if (r == null) {
10445                    return false;
10446                }
10447                int index = r.task.mActivities.lastIndexOf(r);
10448                if (index > 0) {
10449                    ActivityRecord under = r.task.mActivities.get(index - 1);
10450                    under.returningOptions = options;
10451                }
10452                final boolean translucentChanged = r.changeWindowTranslucency(false);
10453                if (translucentChanged) {
10454                    r.task.stack.convertToTranslucent(r);
10455                }
10456                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10457                mWindowManager.setAppFullscreen(token, false);
10458                return translucentChanged;
10459            }
10460        } finally {
10461            Binder.restoreCallingIdentity(origId);
10462        }
10463    }
10464
10465    @Override
10466    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10467        final long origId = Binder.clearCallingIdentity();
10468        try {
10469            synchronized (this) {
10470                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10471                if (r != null) {
10472                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10473                }
10474            }
10475            return false;
10476        } finally {
10477            Binder.restoreCallingIdentity(origId);
10478        }
10479    }
10480
10481    @Override
10482    public boolean isBackgroundVisibleBehind(IBinder token) {
10483        final long origId = Binder.clearCallingIdentity();
10484        try {
10485            synchronized (this) {
10486                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10487                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10488                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10489                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10490                return visible;
10491            }
10492        } finally {
10493            Binder.restoreCallingIdentity(origId);
10494        }
10495    }
10496
10497    @Override
10498    public ActivityOptions getActivityOptions(IBinder token) {
10499        final long origId = Binder.clearCallingIdentity();
10500        try {
10501            synchronized (this) {
10502                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10503                if (r != null) {
10504                    final ActivityOptions activityOptions = r.pendingOptions;
10505                    r.pendingOptions = null;
10506                    return activityOptions;
10507                }
10508                return null;
10509            }
10510        } finally {
10511            Binder.restoreCallingIdentity(origId);
10512        }
10513    }
10514
10515    @Override
10516    public void setImmersive(IBinder token, boolean immersive) {
10517        synchronized(this) {
10518            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10519            if (r == null) {
10520                throw new IllegalArgumentException();
10521            }
10522            r.immersive = immersive;
10523
10524            // update associated state if we're frontmost
10525            if (r == mFocusedActivity) {
10526                if (DEBUG_IMMERSIVE) {
10527                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10528                }
10529                applyUpdateLockStateLocked(r);
10530            }
10531        }
10532    }
10533
10534    @Override
10535    public boolean isImmersive(IBinder token) {
10536        synchronized (this) {
10537            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10538            if (r == null) {
10539                throw new IllegalArgumentException();
10540            }
10541            return r.immersive;
10542        }
10543    }
10544
10545    public boolean isTopActivityImmersive() {
10546        enforceNotIsolatedCaller("startActivity");
10547        synchronized (this) {
10548            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10549            return (r != null) ? r.immersive : false;
10550        }
10551    }
10552
10553    @Override
10554    public boolean isTopOfTask(IBinder token) {
10555        synchronized (this) {
10556            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10557            if (r == null) {
10558                throw new IllegalArgumentException();
10559            }
10560            return r.task.getTopActivity() == r;
10561        }
10562    }
10563
10564    public final void enterSafeMode() {
10565        synchronized(this) {
10566            // It only makes sense to do this before the system is ready
10567            // and started launching other packages.
10568            if (!mSystemReady) {
10569                try {
10570                    AppGlobals.getPackageManager().enterSafeMode();
10571                } catch (RemoteException e) {
10572                }
10573            }
10574
10575            mSafeMode = true;
10576        }
10577    }
10578
10579    public final void showSafeModeOverlay() {
10580        View v = LayoutInflater.from(mContext).inflate(
10581                com.android.internal.R.layout.safe_mode, null);
10582        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10583        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10584        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10585        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10586        lp.gravity = Gravity.BOTTOM | Gravity.START;
10587        lp.format = v.getBackground().getOpacity();
10588        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10589                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10590        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10591        ((WindowManager)mContext.getSystemService(
10592                Context.WINDOW_SERVICE)).addView(v, lp);
10593    }
10594
10595    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10596        if (!(sender instanceof PendingIntentRecord)) {
10597            return;
10598        }
10599        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10600        synchronized (stats) {
10601            if (mBatteryStatsService.isOnBattery()) {
10602                mBatteryStatsService.enforceCallingPermission();
10603                PendingIntentRecord rec = (PendingIntentRecord)sender;
10604                int MY_UID = Binder.getCallingUid();
10605                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10606                BatteryStatsImpl.Uid.Pkg pkg =
10607                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10608                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10609                pkg.incWakeupsLocked();
10610            }
10611        }
10612    }
10613
10614    public boolean killPids(int[] pids, String pReason, boolean secure) {
10615        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10616            throw new SecurityException("killPids only available to the system");
10617        }
10618        String reason = (pReason == null) ? "Unknown" : pReason;
10619        // XXX Note: don't acquire main activity lock here, because the window
10620        // manager calls in with its locks held.
10621
10622        boolean killed = false;
10623        synchronized (mPidsSelfLocked) {
10624            int[] types = new int[pids.length];
10625            int worstType = 0;
10626            for (int i=0; i<pids.length; i++) {
10627                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10628                if (proc != null) {
10629                    int type = proc.setAdj;
10630                    types[i] = type;
10631                    if (type > worstType) {
10632                        worstType = type;
10633                    }
10634                }
10635            }
10636
10637            // If the worst oom_adj is somewhere in the cached proc LRU range,
10638            // then constrain it so we will kill all cached procs.
10639            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10640                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10641                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10642            }
10643
10644            // If this is not a secure call, don't let it kill processes that
10645            // are important.
10646            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10647                worstType = ProcessList.SERVICE_ADJ;
10648            }
10649
10650            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10651            for (int i=0; i<pids.length; i++) {
10652                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10653                if (proc == null) {
10654                    continue;
10655                }
10656                int adj = proc.setAdj;
10657                if (adj >= worstType && !proc.killedByAm) {
10658                    proc.kill(reason, true);
10659                    killed = true;
10660                }
10661            }
10662        }
10663        return killed;
10664    }
10665
10666    @Override
10667    public void killUid(int uid, String reason) {
10668        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10669            throw new SecurityException("killUid only available to the system");
10670        }
10671        synchronized (this) {
10672            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10673                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10674                    reason != null ? reason : "kill uid");
10675        }
10676    }
10677
10678    @Override
10679    public boolean killProcessesBelowForeground(String reason) {
10680        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10681            throw new SecurityException("killProcessesBelowForeground() only available to system");
10682        }
10683
10684        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10685    }
10686
10687    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10688        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10689            throw new SecurityException("killProcessesBelowAdj() only available to system");
10690        }
10691
10692        boolean killed = false;
10693        synchronized (mPidsSelfLocked) {
10694            final int size = mPidsSelfLocked.size();
10695            for (int i = 0; i < size; i++) {
10696                final int pid = mPidsSelfLocked.keyAt(i);
10697                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10698                if (proc == null) continue;
10699
10700                final int adj = proc.setAdj;
10701                if (adj > belowAdj && !proc.killedByAm) {
10702                    proc.kill(reason, true);
10703                    killed = true;
10704                }
10705            }
10706        }
10707        return killed;
10708    }
10709
10710    @Override
10711    public void hang(final IBinder who, boolean allowRestart) {
10712        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10713                != PackageManager.PERMISSION_GRANTED) {
10714            throw new SecurityException("Requires permission "
10715                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10716        }
10717
10718        final IBinder.DeathRecipient death = new DeathRecipient() {
10719            @Override
10720            public void binderDied() {
10721                synchronized (this) {
10722                    notifyAll();
10723                }
10724            }
10725        };
10726
10727        try {
10728            who.linkToDeath(death, 0);
10729        } catch (RemoteException e) {
10730            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10731            return;
10732        }
10733
10734        synchronized (this) {
10735            Watchdog.getInstance().setAllowRestart(allowRestart);
10736            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10737            synchronized (death) {
10738                while (who.isBinderAlive()) {
10739                    try {
10740                        death.wait();
10741                    } catch (InterruptedException e) {
10742                    }
10743                }
10744            }
10745            Watchdog.getInstance().setAllowRestart(true);
10746        }
10747    }
10748
10749    @Override
10750    public void restart() {
10751        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10752                != PackageManager.PERMISSION_GRANTED) {
10753            throw new SecurityException("Requires permission "
10754                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10755        }
10756
10757        Log.i(TAG, "Sending shutdown broadcast...");
10758
10759        BroadcastReceiver br = new BroadcastReceiver() {
10760            @Override public void onReceive(Context context, Intent intent) {
10761                // Now the broadcast is done, finish up the low-level shutdown.
10762                Log.i(TAG, "Shutting down activity manager...");
10763                shutdown(10000);
10764                Log.i(TAG, "Shutdown complete, restarting!");
10765                Process.killProcess(Process.myPid());
10766                System.exit(10);
10767            }
10768        };
10769
10770        // First send the high-level shut down broadcast.
10771        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10772        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10773        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10774        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10775        mContext.sendOrderedBroadcastAsUser(intent,
10776                UserHandle.ALL, null, br, mHandler, 0, null, null);
10777        */
10778        br.onReceive(mContext, intent);
10779    }
10780
10781    private long getLowRamTimeSinceIdle(long now) {
10782        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10783    }
10784
10785    @Override
10786    public void performIdleMaintenance() {
10787        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10788                != PackageManager.PERMISSION_GRANTED) {
10789            throw new SecurityException("Requires permission "
10790                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10791        }
10792
10793        synchronized (this) {
10794            final long now = SystemClock.uptimeMillis();
10795            final long timeSinceLastIdle = now - mLastIdleTime;
10796            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10797            mLastIdleTime = now;
10798            mLowRamTimeSinceLastIdle = 0;
10799            if (mLowRamStartTime != 0) {
10800                mLowRamStartTime = now;
10801            }
10802
10803            StringBuilder sb = new StringBuilder(128);
10804            sb.append("Idle maintenance over ");
10805            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10806            sb.append(" low RAM for ");
10807            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10808            Slog.i(TAG, sb.toString());
10809
10810            // If at least 1/3 of our time since the last idle period has been spent
10811            // with RAM low, then we want to kill processes.
10812            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10813
10814            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10815                ProcessRecord proc = mLruProcesses.get(i);
10816                if (proc.notCachedSinceIdle) {
10817                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10818                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10819                        if (doKilling && proc.initialIdlePss != 0
10820                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10821                            proc.kill("idle maint (pss " + proc.lastPss
10822                                    + " from " + proc.initialIdlePss + ")", true);
10823                        }
10824                    }
10825                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10826                    proc.notCachedSinceIdle = true;
10827                    proc.initialIdlePss = 0;
10828                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10829                            isSleeping(), now);
10830                }
10831            }
10832
10833            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10834            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10835        }
10836    }
10837
10838    private void retrieveSettings() {
10839        final ContentResolver resolver = mContext.getContentResolver();
10840        String debugApp = Settings.Global.getString(
10841            resolver, Settings.Global.DEBUG_APP);
10842        boolean waitForDebugger = Settings.Global.getInt(
10843            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10844        boolean alwaysFinishActivities = Settings.Global.getInt(
10845            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10846        boolean forceRtl = Settings.Global.getInt(
10847                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10848        // Transfer any global setting for forcing RTL layout, into a System Property
10849        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10850
10851        Configuration configuration = new Configuration();
10852        Settings.System.getConfiguration(resolver, configuration);
10853        if (forceRtl) {
10854            // This will take care of setting the correct layout direction flags
10855            configuration.setLayoutDirection(configuration.locale);
10856        }
10857
10858        synchronized (this) {
10859            mDebugApp = mOrigDebugApp = debugApp;
10860            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10861            mAlwaysFinishActivities = alwaysFinishActivities;
10862            // This happens before any activities are started, so we can
10863            // change mConfiguration in-place.
10864            updateConfigurationLocked(configuration, null, false, true);
10865            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10866        }
10867    }
10868
10869    /** Loads resources after the current configuration has been set. */
10870    private void loadResourcesOnSystemReady() {
10871        final Resources res = mContext.getResources();
10872        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10873        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10874        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10875    }
10876
10877    public boolean testIsSystemReady() {
10878        // no need to synchronize(this) just to read & return the value
10879        return mSystemReady;
10880    }
10881
10882    private static File getCalledPreBootReceiversFile() {
10883        File dataDir = Environment.getDataDirectory();
10884        File systemDir = new File(dataDir, "system");
10885        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10886        return fname;
10887    }
10888
10889    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10890        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10891        File file = getCalledPreBootReceiversFile();
10892        FileInputStream fis = null;
10893        try {
10894            fis = new FileInputStream(file);
10895            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10896            int fvers = dis.readInt();
10897            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10898                String vers = dis.readUTF();
10899                String codename = dis.readUTF();
10900                String build = dis.readUTF();
10901                if (android.os.Build.VERSION.RELEASE.equals(vers)
10902                        && android.os.Build.VERSION.CODENAME.equals(codename)
10903                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10904                    int num = dis.readInt();
10905                    while (num > 0) {
10906                        num--;
10907                        String pkg = dis.readUTF();
10908                        String cls = dis.readUTF();
10909                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10910                    }
10911                }
10912            }
10913        } catch (FileNotFoundException e) {
10914        } catch (IOException e) {
10915            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10916        } finally {
10917            if (fis != null) {
10918                try {
10919                    fis.close();
10920                } catch (IOException e) {
10921                }
10922            }
10923        }
10924        return lastDoneReceivers;
10925    }
10926
10927    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10928        File file = getCalledPreBootReceiversFile();
10929        FileOutputStream fos = null;
10930        DataOutputStream dos = null;
10931        try {
10932            fos = new FileOutputStream(file);
10933            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10934            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10935            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10936            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10937            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10938            dos.writeInt(list.size());
10939            for (int i=0; i<list.size(); i++) {
10940                dos.writeUTF(list.get(i).getPackageName());
10941                dos.writeUTF(list.get(i).getClassName());
10942            }
10943        } catch (IOException e) {
10944            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10945            file.delete();
10946        } finally {
10947            FileUtils.sync(fos);
10948            if (dos != null) {
10949                try {
10950                    dos.close();
10951                } catch (IOException e) {
10952                    // TODO Auto-generated catch block
10953                    e.printStackTrace();
10954                }
10955            }
10956        }
10957    }
10958
10959    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10960            ArrayList<ComponentName> doneReceivers, int userId) {
10961        boolean waitingUpdate = false;
10962        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10963        List<ResolveInfo> ris = null;
10964        try {
10965            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10966                    intent, null, 0, userId);
10967        } catch (RemoteException e) {
10968        }
10969        if (ris != null) {
10970            for (int i=ris.size()-1; i>=0; i--) {
10971                if ((ris.get(i).activityInfo.applicationInfo.flags
10972                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10973                    ris.remove(i);
10974                }
10975            }
10976            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10977
10978            // For User 0, load the version number. When delivering to a new user, deliver
10979            // to all receivers.
10980            if (userId == UserHandle.USER_OWNER) {
10981                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10982                for (int i=0; i<ris.size(); i++) {
10983                    ActivityInfo ai = ris.get(i).activityInfo;
10984                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10985                    if (lastDoneReceivers.contains(comp)) {
10986                        // We already did the pre boot receiver for this app with the current
10987                        // platform version, so don't do it again...
10988                        ris.remove(i);
10989                        i--;
10990                        // ...however, do keep it as one that has been done, so we don't
10991                        // forget about it when rewriting the file of last done receivers.
10992                        doneReceivers.add(comp);
10993                    }
10994                }
10995            }
10996
10997            // If primary user, send broadcast to all available users, else just to userId
10998            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10999                    : new int[] { userId };
11000            for (int i = 0; i < ris.size(); i++) {
11001                ActivityInfo ai = ris.get(i).activityInfo;
11002                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11003                doneReceivers.add(comp);
11004                intent.setComponent(comp);
11005                for (int j=0; j<users.length; j++) {
11006                    IIntentReceiver finisher = null;
11007                    // On last receiver and user, set up a completion callback
11008                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11009                        finisher = new IIntentReceiver.Stub() {
11010                            public void performReceive(Intent intent, int resultCode,
11011                                    String data, Bundle extras, boolean ordered,
11012                                    boolean sticky, int sendingUser) {
11013                                // The raw IIntentReceiver interface is called
11014                                // with the AM lock held, so redispatch to
11015                                // execute our code without the lock.
11016                                mHandler.post(onFinishCallback);
11017                            }
11018                        };
11019                    }
11020                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11021                            + " for user " + users[j]);
11022                    broadcastIntentLocked(null, null, intent, null, finisher,
11023                            0, null, null, null, AppOpsManager.OP_NONE,
11024                            true, false, MY_PID, Process.SYSTEM_UID,
11025                            users[j]);
11026                    if (finisher != null) {
11027                        waitingUpdate = true;
11028                    }
11029                }
11030            }
11031        }
11032
11033        return waitingUpdate;
11034    }
11035
11036    public void systemReady(final Runnable goingCallback) {
11037        synchronized(this) {
11038            if (mSystemReady) {
11039                // If we're done calling all the receivers, run the next "boot phase" passed in
11040                // by the SystemServer
11041                if (goingCallback != null) {
11042                    goingCallback.run();
11043                }
11044                return;
11045            }
11046
11047            // Make sure we have the current profile info, since it is needed for
11048            // security checks.
11049            updateCurrentProfileIdsLocked();
11050
11051            if (mRecentTasks == null) {
11052                mRecentTasks = mTaskPersister.restoreTasksLocked();
11053                if (!mRecentTasks.isEmpty()) {
11054                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11055                }
11056                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11057                mTaskPersister.startPersisting();
11058            }
11059
11060            // Check to see if there are any update receivers to run.
11061            if (!mDidUpdate) {
11062                if (mWaitingUpdate) {
11063                    return;
11064                }
11065                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11066                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11067                    public void run() {
11068                        synchronized (ActivityManagerService.this) {
11069                            mDidUpdate = true;
11070                        }
11071                        writeLastDonePreBootReceivers(doneReceivers);
11072                        showBootMessage(mContext.getText(
11073                                R.string.android_upgrading_complete),
11074                                false);
11075                        systemReady(goingCallback);
11076                    }
11077                }, doneReceivers, UserHandle.USER_OWNER);
11078
11079                if (mWaitingUpdate) {
11080                    return;
11081                }
11082                mDidUpdate = true;
11083            }
11084
11085            mAppOpsService.systemReady();
11086            mSystemReady = true;
11087        }
11088
11089        ArrayList<ProcessRecord> procsToKill = null;
11090        synchronized(mPidsSelfLocked) {
11091            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11092                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11093                if (!isAllowedWhileBooting(proc.info)){
11094                    if (procsToKill == null) {
11095                        procsToKill = new ArrayList<ProcessRecord>();
11096                    }
11097                    procsToKill.add(proc);
11098                }
11099            }
11100        }
11101
11102        synchronized(this) {
11103            if (procsToKill != null) {
11104                for (int i=procsToKill.size()-1; i>=0; i--) {
11105                    ProcessRecord proc = procsToKill.get(i);
11106                    Slog.i(TAG, "Removing system update proc: " + proc);
11107                    removeProcessLocked(proc, true, false, "system update done");
11108                }
11109            }
11110
11111            // Now that we have cleaned up any update processes, we
11112            // are ready to start launching real processes and know that
11113            // we won't trample on them any more.
11114            mProcessesReady = true;
11115        }
11116
11117        Slog.i(TAG, "System now ready");
11118        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11119            SystemClock.uptimeMillis());
11120
11121        synchronized(this) {
11122            // Make sure we have no pre-ready processes sitting around.
11123
11124            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11125                ResolveInfo ri = mContext.getPackageManager()
11126                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11127                                STOCK_PM_FLAGS);
11128                CharSequence errorMsg = null;
11129                if (ri != null) {
11130                    ActivityInfo ai = ri.activityInfo;
11131                    ApplicationInfo app = ai.applicationInfo;
11132                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11133                        mTopAction = Intent.ACTION_FACTORY_TEST;
11134                        mTopData = null;
11135                        mTopComponent = new ComponentName(app.packageName,
11136                                ai.name);
11137                    } else {
11138                        errorMsg = mContext.getResources().getText(
11139                                com.android.internal.R.string.factorytest_not_system);
11140                    }
11141                } else {
11142                    errorMsg = mContext.getResources().getText(
11143                            com.android.internal.R.string.factorytest_no_action);
11144                }
11145                if (errorMsg != null) {
11146                    mTopAction = null;
11147                    mTopData = null;
11148                    mTopComponent = null;
11149                    Message msg = Message.obtain();
11150                    msg.what = SHOW_FACTORY_ERROR_MSG;
11151                    msg.getData().putCharSequence("msg", errorMsg);
11152                    mHandler.sendMessage(msg);
11153                }
11154            }
11155        }
11156
11157        retrieveSettings();
11158        loadResourcesOnSystemReady();
11159
11160        synchronized (this) {
11161            readGrantedUriPermissionsLocked();
11162        }
11163
11164        if (goingCallback != null) goingCallback.run();
11165
11166        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11167                Integer.toString(mCurrentUserId), mCurrentUserId);
11168        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11169                Integer.toString(mCurrentUserId), mCurrentUserId);
11170        mSystemServiceManager.startUser(mCurrentUserId);
11171
11172        synchronized (this) {
11173            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11174                try {
11175                    List apps = AppGlobals.getPackageManager().
11176                        getPersistentApplications(STOCK_PM_FLAGS);
11177                    if (apps != null) {
11178                        int N = apps.size();
11179                        int i;
11180                        for (i=0; i<N; i++) {
11181                            ApplicationInfo info
11182                                = (ApplicationInfo)apps.get(i);
11183                            if (info != null &&
11184                                    !info.packageName.equals("android")) {
11185                                addAppLocked(info, false, null /* ABI override */);
11186                            }
11187                        }
11188                    }
11189                } catch (RemoteException ex) {
11190                    // pm is in same process, this will never happen.
11191                }
11192            }
11193
11194            // Start up initial activity.
11195            mBooting = true;
11196            startHomeActivityLocked(mCurrentUserId);
11197
11198            try {
11199                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11200                    Message msg = Message.obtain();
11201                    msg.what = SHOW_UID_ERROR_MSG;
11202                    mHandler.sendMessage(msg);
11203                }
11204            } catch (RemoteException e) {
11205            }
11206
11207            long ident = Binder.clearCallingIdentity();
11208            try {
11209                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11210                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11211                        | Intent.FLAG_RECEIVER_FOREGROUND);
11212                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11213                broadcastIntentLocked(null, null, intent,
11214                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11215                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11216                intent = new Intent(Intent.ACTION_USER_STARTING);
11217                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11218                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11219                broadcastIntentLocked(null, null, intent,
11220                        null, new IIntentReceiver.Stub() {
11221                            @Override
11222                            public void performReceive(Intent intent, int resultCode, String data,
11223                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11224                                    throws RemoteException {
11225                            }
11226                        }, 0, null, null,
11227                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11228                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11229            } catch (Throwable t) {
11230                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11231            } finally {
11232                Binder.restoreCallingIdentity(ident);
11233            }
11234            mStackSupervisor.resumeTopActivitiesLocked();
11235            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11236        }
11237    }
11238
11239    private boolean makeAppCrashingLocked(ProcessRecord app,
11240            String shortMsg, String longMsg, String stackTrace) {
11241        app.crashing = true;
11242        app.crashingReport = generateProcessError(app,
11243                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11244        startAppProblemLocked(app);
11245        app.stopFreezingAllLocked();
11246        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11247    }
11248
11249    private void makeAppNotRespondingLocked(ProcessRecord app,
11250            String activity, String shortMsg, String longMsg) {
11251        app.notResponding = true;
11252        app.notRespondingReport = generateProcessError(app,
11253                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11254                activity, shortMsg, longMsg, null);
11255        startAppProblemLocked(app);
11256        app.stopFreezingAllLocked();
11257    }
11258
11259    /**
11260     * Generate a process error record, suitable for attachment to a ProcessRecord.
11261     *
11262     * @param app The ProcessRecord in which the error occurred.
11263     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11264     *                      ActivityManager.AppErrorStateInfo
11265     * @param activity The activity associated with the crash, if known.
11266     * @param shortMsg Short message describing the crash.
11267     * @param longMsg Long message describing the crash.
11268     * @param stackTrace Full crash stack trace, may be null.
11269     *
11270     * @return Returns a fully-formed AppErrorStateInfo record.
11271     */
11272    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11273            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11274        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11275
11276        report.condition = condition;
11277        report.processName = app.processName;
11278        report.pid = app.pid;
11279        report.uid = app.info.uid;
11280        report.tag = activity;
11281        report.shortMsg = shortMsg;
11282        report.longMsg = longMsg;
11283        report.stackTrace = stackTrace;
11284
11285        return report;
11286    }
11287
11288    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11289        synchronized (this) {
11290            app.crashing = false;
11291            app.crashingReport = null;
11292            app.notResponding = false;
11293            app.notRespondingReport = null;
11294            if (app.anrDialog == fromDialog) {
11295                app.anrDialog = null;
11296            }
11297            if (app.waitDialog == fromDialog) {
11298                app.waitDialog = null;
11299            }
11300            if (app.pid > 0 && app.pid != MY_PID) {
11301                handleAppCrashLocked(app, null, null, null);
11302                app.kill("user request after error", true);
11303            }
11304        }
11305    }
11306
11307    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11308            String stackTrace) {
11309        long now = SystemClock.uptimeMillis();
11310
11311        Long crashTime;
11312        if (!app.isolated) {
11313            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11314        } else {
11315            crashTime = null;
11316        }
11317        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11318            // This process loses!
11319            Slog.w(TAG, "Process " + app.info.processName
11320                    + " has crashed too many times: killing!");
11321            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11322                    app.userId, app.info.processName, app.uid);
11323            mStackSupervisor.handleAppCrashLocked(app);
11324            if (!app.persistent) {
11325                // We don't want to start this process again until the user
11326                // explicitly does so...  but for persistent process, we really
11327                // need to keep it running.  If a persistent process is actually
11328                // repeatedly crashing, then badness for everyone.
11329                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11330                        app.info.processName);
11331                if (!app.isolated) {
11332                    // XXX We don't have a way to mark isolated processes
11333                    // as bad, since they don't have a peristent identity.
11334                    mBadProcesses.put(app.info.processName, app.uid,
11335                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11336                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11337                }
11338                app.bad = true;
11339                app.removed = true;
11340                // Don't let services in this process be restarted and potentially
11341                // annoy the user repeatedly.  Unless it is persistent, since those
11342                // processes run critical code.
11343                removeProcessLocked(app, false, false, "crash");
11344                mStackSupervisor.resumeTopActivitiesLocked();
11345                return false;
11346            }
11347            mStackSupervisor.resumeTopActivitiesLocked();
11348        } else {
11349            mStackSupervisor.finishTopRunningActivityLocked(app);
11350        }
11351
11352        // Bump up the crash count of any services currently running in the proc.
11353        for (int i=app.services.size()-1; i>=0; i--) {
11354            // Any services running in the application need to be placed
11355            // back in the pending list.
11356            ServiceRecord sr = app.services.valueAt(i);
11357            sr.crashCount++;
11358        }
11359
11360        // If the crashing process is what we consider to be the "home process" and it has been
11361        // replaced by a third-party app, clear the package preferred activities from packages
11362        // with a home activity running in the process to prevent a repeatedly crashing app
11363        // from blocking the user to manually clear the list.
11364        final ArrayList<ActivityRecord> activities = app.activities;
11365        if (app == mHomeProcess && activities.size() > 0
11366                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11367            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11368                final ActivityRecord r = activities.get(activityNdx);
11369                if (r.isHomeActivity()) {
11370                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11371                    try {
11372                        ActivityThread.getPackageManager()
11373                                .clearPackagePreferredActivities(r.packageName);
11374                    } catch (RemoteException c) {
11375                        // pm is in same process, this will never happen.
11376                    }
11377                }
11378            }
11379        }
11380
11381        if (!app.isolated) {
11382            // XXX Can't keep track of crash times for isolated processes,
11383            // because they don't have a perisistent identity.
11384            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11385        }
11386
11387        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11388        return true;
11389    }
11390
11391    void startAppProblemLocked(ProcessRecord app) {
11392        // If this app is not running under the current user, then we
11393        // can't give it a report button because that would require
11394        // launching the report UI under a different user.
11395        app.errorReportReceiver = null;
11396
11397        for (int userId : mCurrentProfileIds) {
11398            if (app.userId == userId) {
11399                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11400                        mContext, app.info.packageName, app.info.flags);
11401            }
11402        }
11403        skipCurrentReceiverLocked(app);
11404    }
11405
11406    void skipCurrentReceiverLocked(ProcessRecord app) {
11407        for (BroadcastQueue queue : mBroadcastQueues) {
11408            queue.skipCurrentReceiverLocked(app);
11409        }
11410    }
11411
11412    /**
11413     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11414     * The application process will exit immediately after this call returns.
11415     * @param app object of the crashing app, null for the system server
11416     * @param crashInfo describing the exception
11417     */
11418    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11419        ProcessRecord r = findAppProcess(app, "Crash");
11420        final String processName = app == null ? "system_server"
11421                : (r == null ? "unknown" : r.processName);
11422
11423        handleApplicationCrashInner("crash", r, processName, crashInfo);
11424    }
11425
11426    /* Native crash reporting uses this inner version because it needs to be somewhat
11427     * decoupled from the AM-managed cleanup lifecycle
11428     */
11429    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11430            ApplicationErrorReport.CrashInfo crashInfo) {
11431        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11432                UserHandle.getUserId(Binder.getCallingUid()), processName,
11433                r == null ? -1 : r.info.flags,
11434                crashInfo.exceptionClassName,
11435                crashInfo.exceptionMessage,
11436                crashInfo.throwFileName,
11437                crashInfo.throwLineNumber);
11438
11439        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11440
11441        crashApplication(r, crashInfo);
11442    }
11443
11444    public void handleApplicationStrictModeViolation(
11445            IBinder app,
11446            int violationMask,
11447            StrictMode.ViolationInfo info) {
11448        ProcessRecord r = findAppProcess(app, "StrictMode");
11449        if (r == null) {
11450            return;
11451        }
11452
11453        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11454            Integer stackFingerprint = info.hashCode();
11455            boolean logIt = true;
11456            synchronized (mAlreadyLoggedViolatedStacks) {
11457                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11458                    logIt = false;
11459                    // TODO: sub-sample into EventLog for these, with
11460                    // the info.durationMillis?  Then we'd get
11461                    // the relative pain numbers, without logging all
11462                    // the stack traces repeatedly.  We'd want to do
11463                    // likewise in the client code, which also does
11464                    // dup suppression, before the Binder call.
11465                } else {
11466                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11467                        mAlreadyLoggedViolatedStacks.clear();
11468                    }
11469                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11470                }
11471            }
11472            if (logIt) {
11473                logStrictModeViolationToDropBox(r, info);
11474            }
11475        }
11476
11477        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11478            AppErrorResult result = new AppErrorResult();
11479            synchronized (this) {
11480                final long origId = Binder.clearCallingIdentity();
11481
11482                Message msg = Message.obtain();
11483                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11484                HashMap<String, Object> data = new HashMap<String, Object>();
11485                data.put("result", result);
11486                data.put("app", r);
11487                data.put("violationMask", violationMask);
11488                data.put("info", info);
11489                msg.obj = data;
11490                mHandler.sendMessage(msg);
11491
11492                Binder.restoreCallingIdentity(origId);
11493            }
11494            int res = result.get();
11495            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11496        }
11497    }
11498
11499    // Depending on the policy in effect, there could be a bunch of
11500    // these in quick succession so we try to batch these together to
11501    // minimize disk writes, number of dropbox entries, and maximize
11502    // compression, by having more fewer, larger records.
11503    private void logStrictModeViolationToDropBox(
11504            ProcessRecord process,
11505            StrictMode.ViolationInfo info) {
11506        if (info == null) {
11507            return;
11508        }
11509        final boolean isSystemApp = process == null ||
11510                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11511                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11512        final String processName = process == null ? "unknown" : process.processName;
11513        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11514        final DropBoxManager dbox = (DropBoxManager)
11515                mContext.getSystemService(Context.DROPBOX_SERVICE);
11516
11517        // Exit early if the dropbox isn't configured to accept this report type.
11518        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11519
11520        boolean bufferWasEmpty;
11521        boolean needsFlush;
11522        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11523        synchronized (sb) {
11524            bufferWasEmpty = sb.length() == 0;
11525            appendDropBoxProcessHeaders(process, processName, sb);
11526            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11527            sb.append("System-App: ").append(isSystemApp).append("\n");
11528            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11529            if (info.violationNumThisLoop != 0) {
11530                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11531            }
11532            if (info.numAnimationsRunning != 0) {
11533                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11534            }
11535            if (info.broadcastIntentAction != null) {
11536                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11537            }
11538            if (info.durationMillis != -1) {
11539                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11540            }
11541            if (info.numInstances != -1) {
11542                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11543            }
11544            if (info.tags != null) {
11545                for (String tag : info.tags) {
11546                    sb.append("Span-Tag: ").append(tag).append("\n");
11547                }
11548            }
11549            sb.append("\n");
11550            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11551                sb.append(info.crashInfo.stackTrace);
11552            }
11553            sb.append("\n");
11554
11555            // Only buffer up to ~64k.  Various logging bits truncate
11556            // things at 128k.
11557            needsFlush = (sb.length() > 64 * 1024);
11558        }
11559
11560        // Flush immediately if the buffer's grown too large, or this
11561        // is a non-system app.  Non-system apps are isolated with a
11562        // different tag & policy and not batched.
11563        //
11564        // Batching is useful during internal testing with
11565        // StrictMode settings turned up high.  Without batching,
11566        // thousands of separate files could be created on boot.
11567        if (!isSystemApp || needsFlush) {
11568            new Thread("Error dump: " + dropboxTag) {
11569                @Override
11570                public void run() {
11571                    String report;
11572                    synchronized (sb) {
11573                        report = sb.toString();
11574                        sb.delete(0, sb.length());
11575                        sb.trimToSize();
11576                    }
11577                    if (report.length() != 0) {
11578                        dbox.addText(dropboxTag, report);
11579                    }
11580                }
11581            }.start();
11582            return;
11583        }
11584
11585        // System app batching:
11586        if (!bufferWasEmpty) {
11587            // An existing dropbox-writing thread is outstanding, so
11588            // we don't need to start it up.  The existing thread will
11589            // catch the buffer appends we just did.
11590            return;
11591        }
11592
11593        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11594        // (After this point, we shouldn't access AMS internal data structures.)
11595        new Thread("Error dump: " + dropboxTag) {
11596            @Override
11597            public void run() {
11598                // 5 second sleep to let stacks arrive and be batched together
11599                try {
11600                    Thread.sleep(5000);  // 5 seconds
11601                } catch (InterruptedException e) {}
11602
11603                String errorReport;
11604                synchronized (mStrictModeBuffer) {
11605                    errorReport = mStrictModeBuffer.toString();
11606                    if (errorReport.length() == 0) {
11607                        return;
11608                    }
11609                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11610                    mStrictModeBuffer.trimToSize();
11611                }
11612                dbox.addText(dropboxTag, errorReport);
11613            }
11614        }.start();
11615    }
11616
11617    /**
11618     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11619     * @param app object of the crashing app, null for the system server
11620     * @param tag reported by the caller
11621     * @param system whether this wtf is coming from the system
11622     * @param crashInfo describing the context of the error
11623     * @return true if the process should exit immediately (WTF is fatal)
11624     */
11625    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11626            final ApplicationErrorReport.CrashInfo crashInfo) {
11627        final int callingUid = Binder.getCallingUid();
11628        final int callingPid = Binder.getCallingPid();
11629
11630        if (system) {
11631            // If this is coming from the system, we could very well have low-level
11632            // system locks held, so we want to do this all asynchronously.  And we
11633            // never want this to become fatal, so there is that too.
11634            mHandler.post(new Runnable() {
11635                @Override public void run() {
11636                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11637                }
11638            });
11639            return false;
11640        }
11641
11642        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11643                crashInfo);
11644
11645        if (r != null && r.pid != Process.myPid() &&
11646                Settings.Global.getInt(mContext.getContentResolver(),
11647                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11648            crashApplication(r, crashInfo);
11649            return true;
11650        } else {
11651            return false;
11652        }
11653    }
11654
11655    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11656            final ApplicationErrorReport.CrashInfo crashInfo) {
11657        final ProcessRecord r = findAppProcess(app, "WTF");
11658        final String processName = app == null ? "system_server"
11659                : (r == null ? "unknown" : r.processName);
11660
11661        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11662                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11663
11664        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11665
11666        return r;
11667    }
11668
11669    /**
11670     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11671     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11672     */
11673    private ProcessRecord findAppProcess(IBinder app, String reason) {
11674        if (app == null) {
11675            return null;
11676        }
11677
11678        synchronized (this) {
11679            final int NP = mProcessNames.getMap().size();
11680            for (int ip=0; ip<NP; ip++) {
11681                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11682                final int NA = apps.size();
11683                for (int ia=0; ia<NA; ia++) {
11684                    ProcessRecord p = apps.valueAt(ia);
11685                    if (p.thread != null && p.thread.asBinder() == app) {
11686                        return p;
11687                    }
11688                }
11689            }
11690
11691            Slog.w(TAG, "Can't find mystery application for " + reason
11692                    + " from pid=" + Binder.getCallingPid()
11693                    + " uid=" + Binder.getCallingUid() + ": " + app);
11694            return null;
11695        }
11696    }
11697
11698    /**
11699     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11700     * to append various headers to the dropbox log text.
11701     */
11702    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11703            StringBuilder sb) {
11704        // Watchdog thread ends up invoking this function (with
11705        // a null ProcessRecord) to add the stack file to dropbox.
11706        // Do not acquire a lock on this (am) in such cases, as it
11707        // could cause a potential deadlock, if and when watchdog
11708        // is invoked due to unavailability of lock on am and it
11709        // would prevent watchdog from killing system_server.
11710        if (process == null) {
11711            sb.append("Process: ").append(processName).append("\n");
11712            return;
11713        }
11714        // Note: ProcessRecord 'process' is guarded by the service
11715        // instance.  (notably process.pkgList, which could otherwise change
11716        // concurrently during execution of this method)
11717        synchronized (this) {
11718            sb.append("Process: ").append(processName).append("\n");
11719            int flags = process.info.flags;
11720            IPackageManager pm = AppGlobals.getPackageManager();
11721            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11722            for (int ip=0; ip<process.pkgList.size(); ip++) {
11723                String pkg = process.pkgList.keyAt(ip);
11724                sb.append("Package: ").append(pkg);
11725                try {
11726                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11727                    if (pi != null) {
11728                        sb.append(" v").append(pi.versionCode);
11729                        if (pi.versionName != null) {
11730                            sb.append(" (").append(pi.versionName).append(")");
11731                        }
11732                    }
11733                } catch (RemoteException e) {
11734                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11735                }
11736                sb.append("\n");
11737            }
11738        }
11739    }
11740
11741    private static String processClass(ProcessRecord process) {
11742        if (process == null || process.pid == MY_PID) {
11743            return "system_server";
11744        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11745            return "system_app";
11746        } else {
11747            return "data_app";
11748        }
11749    }
11750
11751    /**
11752     * Write a description of an error (crash, WTF, ANR) to the drop box.
11753     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11754     * @param process which caused the error, null means the system server
11755     * @param activity which triggered the error, null if unknown
11756     * @param parent activity related to the error, null if unknown
11757     * @param subject line related to the error, null if absent
11758     * @param report in long form describing the error, null if absent
11759     * @param logFile to include in the report, null if none
11760     * @param crashInfo giving an application stack trace, null if absent
11761     */
11762    public void addErrorToDropBox(String eventType,
11763            ProcessRecord process, String processName, ActivityRecord activity,
11764            ActivityRecord parent, String subject,
11765            final String report, final File logFile,
11766            final ApplicationErrorReport.CrashInfo crashInfo) {
11767        // NOTE -- this must never acquire the ActivityManagerService lock,
11768        // otherwise the watchdog may be prevented from resetting the system.
11769
11770        final String dropboxTag = processClass(process) + "_" + eventType;
11771        final DropBoxManager dbox = (DropBoxManager)
11772                mContext.getSystemService(Context.DROPBOX_SERVICE);
11773
11774        // Exit early if the dropbox isn't configured to accept this report type.
11775        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11776
11777        final StringBuilder sb = new StringBuilder(1024);
11778        appendDropBoxProcessHeaders(process, processName, sb);
11779        if (activity != null) {
11780            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11781        }
11782        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11783            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11784        }
11785        if (parent != null && parent != activity) {
11786            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11787        }
11788        if (subject != null) {
11789            sb.append("Subject: ").append(subject).append("\n");
11790        }
11791        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11792        if (Debug.isDebuggerConnected()) {
11793            sb.append("Debugger: Connected\n");
11794        }
11795        sb.append("\n");
11796
11797        // Do the rest in a worker thread to avoid blocking the caller on I/O
11798        // (After this point, we shouldn't access AMS internal data structures.)
11799        Thread worker = new Thread("Error dump: " + dropboxTag) {
11800            @Override
11801            public void run() {
11802                if (report != null) {
11803                    sb.append(report);
11804                }
11805                if (logFile != null) {
11806                    try {
11807                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11808                                    "\n\n[[TRUNCATED]]"));
11809                    } catch (IOException e) {
11810                        Slog.e(TAG, "Error reading " + logFile, e);
11811                    }
11812                }
11813                if (crashInfo != null && crashInfo.stackTrace != null) {
11814                    sb.append(crashInfo.stackTrace);
11815                }
11816
11817                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11818                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11819                if (lines > 0) {
11820                    sb.append("\n");
11821
11822                    // Merge several logcat streams, and take the last N lines
11823                    InputStreamReader input = null;
11824                    try {
11825                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11826                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11827                                "-b", "crash",
11828                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11829
11830                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11831                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11832                        input = new InputStreamReader(logcat.getInputStream());
11833
11834                        int num;
11835                        char[] buf = new char[8192];
11836                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11837                    } catch (IOException e) {
11838                        Slog.e(TAG, "Error running logcat", e);
11839                    } finally {
11840                        if (input != null) try { input.close(); } catch (IOException e) {}
11841                    }
11842                }
11843
11844                dbox.addText(dropboxTag, sb.toString());
11845            }
11846        };
11847
11848        if (process == null) {
11849            // If process is null, we are being called from some internal code
11850            // and may be about to die -- run this synchronously.
11851            worker.run();
11852        } else {
11853            worker.start();
11854        }
11855    }
11856
11857    /**
11858     * Bring up the "unexpected error" dialog box for a crashing app.
11859     * Deal with edge cases (intercepts from instrumented applications,
11860     * ActivityController, error intent receivers, that sort of thing).
11861     * @param r the application crashing
11862     * @param crashInfo describing the failure
11863     */
11864    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11865        long timeMillis = System.currentTimeMillis();
11866        String shortMsg = crashInfo.exceptionClassName;
11867        String longMsg = crashInfo.exceptionMessage;
11868        String stackTrace = crashInfo.stackTrace;
11869        if (shortMsg != null && longMsg != null) {
11870            longMsg = shortMsg + ": " + longMsg;
11871        } else if (shortMsg != null) {
11872            longMsg = shortMsg;
11873        }
11874
11875        AppErrorResult result = new AppErrorResult();
11876        synchronized (this) {
11877            if (mController != null) {
11878                try {
11879                    String name = r != null ? r.processName : null;
11880                    int pid = r != null ? r.pid : Binder.getCallingPid();
11881                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11882                    if (!mController.appCrashed(name, pid,
11883                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11884                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11885                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11886                            Slog.w(TAG, "Skip killing native crashed app " + name
11887                                    + "(" + pid + ") during testing");
11888                        } else {
11889                            Slog.w(TAG, "Force-killing crashed app " + name
11890                                    + " at watcher's request");
11891                            if (r != null) {
11892                                r.kill("crash", true);
11893                            } else {
11894                                // Huh.
11895                                Process.killProcess(pid);
11896                                Process.killProcessGroup(uid, pid);
11897                            }
11898                        }
11899                        return;
11900                    }
11901                } catch (RemoteException e) {
11902                    mController = null;
11903                    Watchdog.getInstance().setActivityController(null);
11904                }
11905            }
11906
11907            final long origId = Binder.clearCallingIdentity();
11908
11909            // If this process is running instrumentation, finish it.
11910            if (r != null && r.instrumentationClass != null) {
11911                Slog.w(TAG, "Error in app " + r.processName
11912                      + " running instrumentation " + r.instrumentationClass + ":");
11913                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11914                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11915                Bundle info = new Bundle();
11916                info.putString("shortMsg", shortMsg);
11917                info.putString("longMsg", longMsg);
11918                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11919                Binder.restoreCallingIdentity(origId);
11920                return;
11921            }
11922
11923            // If we can't identify the process or it's already exceeded its crash quota,
11924            // quit right away without showing a crash dialog.
11925            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11926                Binder.restoreCallingIdentity(origId);
11927                return;
11928            }
11929
11930            Message msg = Message.obtain();
11931            msg.what = SHOW_ERROR_MSG;
11932            HashMap data = new HashMap();
11933            data.put("result", result);
11934            data.put("app", r);
11935            msg.obj = data;
11936            mHandler.sendMessage(msg);
11937
11938            Binder.restoreCallingIdentity(origId);
11939        }
11940
11941        int res = result.get();
11942
11943        Intent appErrorIntent = null;
11944        synchronized (this) {
11945            if (r != null && !r.isolated) {
11946                // XXX Can't keep track of crash time for isolated processes,
11947                // since they don't have a persistent identity.
11948                mProcessCrashTimes.put(r.info.processName, r.uid,
11949                        SystemClock.uptimeMillis());
11950            }
11951            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11952                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11953            }
11954        }
11955
11956        if (appErrorIntent != null) {
11957            try {
11958                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11959            } catch (ActivityNotFoundException e) {
11960                Slog.w(TAG, "bug report receiver dissappeared", e);
11961            }
11962        }
11963    }
11964
11965    Intent createAppErrorIntentLocked(ProcessRecord r,
11966            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11967        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11968        if (report == null) {
11969            return null;
11970        }
11971        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11972        result.setComponent(r.errorReportReceiver);
11973        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11974        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11975        return result;
11976    }
11977
11978    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11979            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11980        if (r.errorReportReceiver == null) {
11981            return null;
11982        }
11983
11984        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11985            return null;
11986        }
11987
11988        ApplicationErrorReport report = new ApplicationErrorReport();
11989        report.packageName = r.info.packageName;
11990        report.installerPackageName = r.errorReportReceiver.getPackageName();
11991        report.processName = r.processName;
11992        report.time = timeMillis;
11993        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11994
11995        if (r.crashing || r.forceCrashReport) {
11996            report.type = ApplicationErrorReport.TYPE_CRASH;
11997            report.crashInfo = crashInfo;
11998        } else if (r.notResponding) {
11999            report.type = ApplicationErrorReport.TYPE_ANR;
12000            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12001
12002            report.anrInfo.activity = r.notRespondingReport.tag;
12003            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12004            report.anrInfo.info = r.notRespondingReport.longMsg;
12005        }
12006
12007        return report;
12008    }
12009
12010    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12011        enforceNotIsolatedCaller("getProcessesInErrorState");
12012        // assume our apps are happy - lazy create the list
12013        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12014
12015        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12016                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12017        int userId = UserHandle.getUserId(Binder.getCallingUid());
12018
12019        synchronized (this) {
12020
12021            // iterate across all processes
12022            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12023                ProcessRecord app = mLruProcesses.get(i);
12024                if (!allUsers && app.userId != userId) {
12025                    continue;
12026                }
12027                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12028                    // This one's in trouble, so we'll generate a report for it
12029                    // crashes are higher priority (in case there's a crash *and* an anr)
12030                    ActivityManager.ProcessErrorStateInfo report = null;
12031                    if (app.crashing) {
12032                        report = app.crashingReport;
12033                    } else if (app.notResponding) {
12034                        report = app.notRespondingReport;
12035                    }
12036
12037                    if (report != null) {
12038                        if (errList == null) {
12039                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12040                        }
12041                        errList.add(report);
12042                    } else {
12043                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12044                                " crashing = " + app.crashing +
12045                                " notResponding = " + app.notResponding);
12046                    }
12047                }
12048            }
12049        }
12050
12051        return errList;
12052    }
12053
12054    static int procStateToImportance(int procState, int memAdj,
12055            ActivityManager.RunningAppProcessInfo currApp) {
12056        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12057        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12058            currApp.lru = memAdj;
12059        } else {
12060            currApp.lru = 0;
12061        }
12062        return imp;
12063    }
12064
12065    private void fillInProcMemInfo(ProcessRecord app,
12066            ActivityManager.RunningAppProcessInfo outInfo) {
12067        outInfo.pid = app.pid;
12068        outInfo.uid = app.info.uid;
12069        if (mHeavyWeightProcess == app) {
12070            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12071        }
12072        if (app.persistent) {
12073            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12074        }
12075        if (app.activities.size() > 0) {
12076            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12077        }
12078        outInfo.lastTrimLevel = app.trimMemoryLevel;
12079        int adj = app.curAdj;
12080        int procState = app.curProcState;
12081        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12082        outInfo.importanceReasonCode = app.adjTypeCode;
12083        outInfo.processState = app.curProcState;
12084    }
12085
12086    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12087        enforceNotIsolatedCaller("getRunningAppProcesses");
12088        // Lazy instantiation of list
12089        List<ActivityManager.RunningAppProcessInfo> runList = null;
12090        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12091                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12092        int userId = UserHandle.getUserId(Binder.getCallingUid());
12093        synchronized (this) {
12094            // Iterate across all processes
12095            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12096                ProcessRecord app = mLruProcesses.get(i);
12097                if (!allUsers && app.userId != userId) {
12098                    continue;
12099                }
12100                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12101                    // Generate process state info for running application
12102                    ActivityManager.RunningAppProcessInfo currApp =
12103                        new ActivityManager.RunningAppProcessInfo(app.processName,
12104                                app.pid, app.getPackageList());
12105                    fillInProcMemInfo(app, currApp);
12106                    if (app.adjSource instanceof ProcessRecord) {
12107                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12108                        currApp.importanceReasonImportance =
12109                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12110                                        app.adjSourceProcState);
12111                    } else if (app.adjSource instanceof ActivityRecord) {
12112                        ActivityRecord r = (ActivityRecord)app.adjSource;
12113                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12114                    }
12115                    if (app.adjTarget instanceof ComponentName) {
12116                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12117                    }
12118                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12119                    //        + " lru=" + currApp.lru);
12120                    if (runList == null) {
12121                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12122                    }
12123                    runList.add(currApp);
12124                }
12125            }
12126        }
12127        return runList;
12128    }
12129
12130    public List<ApplicationInfo> getRunningExternalApplications() {
12131        enforceNotIsolatedCaller("getRunningExternalApplications");
12132        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12133        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12134        if (runningApps != null && runningApps.size() > 0) {
12135            Set<String> extList = new HashSet<String>();
12136            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12137                if (app.pkgList != null) {
12138                    for (String pkg : app.pkgList) {
12139                        extList.add(pkg);
12140                    }
12141                }
12142            }
12143            IPackageManager pm = AppGlobals.getPackageManager();
12144            for (String pkg : extList) {
12145                try {
12146                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12147                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12148                        retList.add(info);
12149                    }
12150                } catch (RemoteException e) {
12151                }
12152            }
12153        }
12154        return retList;
12155    }
12156
12157    @Override
12158    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12159        enforceNotIsolatedCaller("getMyMemoryState");
12160        synchronized (this) {
12161            ProcessRecord proc;
12162            synchronized (mPidsSelfLocked) {
12163                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12164            }
12165            fillInProcMemInfo(proc, outInfo);
12166        }
12167    }
12168
12169    @Override
12170    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12171        if (checkCallingPermission(android.Manifest.permission.DUMP)
12172                != PackageManager.PERMISSION_GRANTED) {
12173            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12174                    + Binder.getCallingPid()
12175                    + ", uid=" + Binder.getCallingUid()
12176                    + " without permission "
12177                    + android.Manifest.permission.DUMP);
12178            return;
12179        }
12180
12181        boolean dumpAll = false;
12182        boolean dumpClient = false;
12183        String dumpPackage = null;
12184
12185        int opti = 0;
12186        while (opti < args.length) {
12187            String opt = args[opti];
12188            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12189                break;
12190            }
12191            opti++;
12192            if ("-a".equals(opt)) {
12193                dumpAll = true;
12194            } else if ("-c".equals(opt)) {
12195                dumpClient = true;
12196            } else if ("-h".equals(opt)) {
12197                pw.println("Activity manager dump options:");
12198                pw.println("  [-a] [-c] [-h] [cmd] ...");
12199                pw.println("  cmd may be one of:");
12200                pw.println("    a[ctivities]: activity stack state");
12201                pw.println("    r[recents]: recent activities state");
12202                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12203                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12204                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12205                pw.println("    o[om]: out of memory management");
12206                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12207                pw.println("    provider [COMP_SPEC]: provider client-side state");
12208                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12209                pw.println("    service [COMP_SPEC]: service client-side state");
12210                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12211                pw.println("    all: dump all activities");
12212                pw.println("    top: dump the top activity");
12213                pw.println("    write: write all pending state to storage");
12214                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12215                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12216                pw.println("    a partial substring in a component name, a");
12217                pw.println("    hex object identifier.");
12218                pw.println("  -a: include all available server state.");
12219                pw.println("  -c: include client state.");
12220                return;
12221            } else {
12222                pw.println("Unknown argument: " + opt + "; use -h for help");
12223            }
12224        }
12225
12226        long origId = Binder.clearCallingIdentity();
12227        boolean more = false;
12228        // Is the caller requesting to dump a particular piece of data?
12229        if (opti < args.length) {
12230            String cmd = args[opti];
12231            opti++;
12232            if ("activities".equals(cmd) || "a".equals(cmd)) {
12233                synchronized (this) {
12234                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12235                }
12236            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12237                synchronized (this) {
12238                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12239                }
12240            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12241                String[] newArgs;
12242                String name;
12243                if (opti >= args.length) {
12244                    name = null;
12245                    newArgs = EMPTY_STRING_ARRAY;
12246                } else {
12247                    name = args[opti];
12248                    opti++;
12249                    newArgs = new String[args.length - opti];
12250                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12251                            args.length - opti);
12252                }
12253                synchronized (this) {
12254                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12255                }
12256            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12257                String[] newArgs;
12258                String name;
12259                if (opti >= args.length) {
12260                    name = null;
12261                    newArgs = EMPTY_STRING_ARRAY;
12262                } else {
12263                    name = args[opti];
12264                    opti++;
12265                    newArgs = new String[args.length - opti];
12266                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12267                            args.length - opti);
12268                }
12269                synchronized (this) {
12270                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12271                }
12272            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12273                String[] newArgs;
12274                String name;
12275                if (opti >= args.length) {
12276                    name = null;
12277                    newArgs = EMPTY_STRING_ARRAY;
12278                } else {
12279                    name = args[opti];
12280                    opti++;
12281                    newArgs = new String[args.length - opti];
12282                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12283                            args.length - opti);
12284                }
12285                synchronized (this) {
12286                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12287                }
12288            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12289                synchronized (this) {
12290                    dumpOomLocked(fd, pw, args, opti, true);
12291                }
12292            } else if ("provider".equals(cmd)) {
12293                String[] newArgs;
12294                String name;
12295                if (opti >= args.length) {
12296                    name = null;
12297                    newArgs = EMPTY_STRING_ARRAY;
12298                } else {
12299                    name = args[opti];
12300                    opti++;
12301                    newArgs = new String[args.length - opti];
12302                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12303                }
12304                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12305                    pw.println("No providers match: " + name);
12306                    pw.println("Use -h for help.");
12307                }
12308            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12309                synchronized (this) {
12310                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12311                }
12312            } else if ("service".equals(cmd)) {
12313                String[] newArgs;
12314                String name;
12315                if (opti >= args.length) {
12316                    name = null;
12317                    newArgs = EMPTY_STRING_ARRAY;
12318                } else {
12319                    name = args[opti];
12320                    opti++;
12321                    newArgs = new String[args.length - opti];
12322                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12323                            args.length - opti);
12324                }
12325                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12326                    pw.println("No services match: " + name);
12327                    pw.println("Use -h for help.");
12328                }
12329            } else if ("package".equals(cmd)) {
12330                String[] newArgs;
12331                if (opti >= args.length) {
12332                    pw.println("package: no package name specified");
12333                    pw.println("Use -h for help.");
12334                } else {
12335                    dumpPackage = args[opti];
12336                    opti++;
12337                    newArgs = new String[args.length - opti];
12338                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12339                            args.length - opti);
12340                    args = newArgs;
12341                    opti = 0;
12342                    more = true;
12343                }
12344            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12345                synchronized (this) {
12346                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12347                }
12348            } else if ("write".equals(cmd)) {
12349                mTaskPersister.flush();
12350                pw.println("All tasks persisted.");
12351                return;
12352            } else {
12353                // Dumping a single activity?
12354                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12355                    pw.println("Bad activity command, or no activities match: " + cmd);
12356                    pw.println("Use -h for help.");
12357                }
12358            }
12359            if (!more) {
12360                Binder.restoreCallingIdentity(origId);
12361                return;
12362            }
12363        }
12364
12365        // No piece of data specified, dump everything.
12366        synchronized (this) {
12367            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12368            pw.println();
12369            if (dumpAll) {
12370                pw.println("-------------------------------------------------------------------------------");
12371            }
12372            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12373            pw.println();
12374            if (dumpAll) {
12375                pw.println("-------------------------------------------------------------------------------");
12376            }
12377            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12378            pw.println();
12379            if (dumpAll) {
12380                pw.println("-------------------------------------------------------------------------------");
12381            }
12382            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12383            pw.println();
12384            if (dumpAll) {
12385                pw.println("-------------------------------------------------------------------------------");
12386            }
12387            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12388            pw.println();
12389            if (dumpAll) {
12390                pw.println("-------------------------------------------------------------------------------");
12391            }
12392            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12393            pw.println();
12394            if (dumpAll) {
12395                pw.println("-------------------------------------------------------------------------------");
12396            }
12397            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12398        }
12399        Binder.restoreCallingIdentity(origId);
12400    }
12401
12402    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12403            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12404        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12405
12406        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12407                dumpPackage);
12408        boolean needSep = printedAnything;
12409
12410        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12411                dumpPackage, needSep, "  mFocusedActivity: ");
12412        if (printed) {
12413            printedAnything = true;
12414            needSep = false;
12415        }
12416
12417        if (dumpPackage == null) {
12418            if (needSep) {
12419                pw.println();
12420            }
12421            needSep = true;
12422            printedAnything = true;
12423            mStackSupervisor.dump(pw, "  ");
12424        }
12425
12426        if (!printedAnything) {
12427            pw.println("  (nothing)");
12428        }
12429    }
12430
12431    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12432            int opti, boolean dumpAll, String dumpPackage) {
12433        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12434
12435        boolean printedAnything = false;
12436
12437        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12438            boolean printedHeader = false;
12439
12440            final int N = mRecentTasks.size();
12441            for (int i=0; i<N; i++) {
12442                TaskRecord tr = mRecentTasks.get(i);
12443                if (dumpPackage != null) {
12444                    if (tr.realActivity == null ||
12445                            !dumpPackage.equals(tr.realActivity)) {
12446                        continue;
12447                    }
12448                }
12449                if (!printedHeader) {
12450                    pw.println("  Recent tasks:");
12451                    printedHeader = true;
12452                    printedAnything = true;
12453                }
12454                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12455                        pw.println(tr);
12456                if (dumpAll) {
12457                    mRecentTasks.get(i).dump(pw, "    ");
12458                }
12459            }
12460        }
12461
12462        if (!printedAnything) {
12463            pw.println("  (nothing)");
12464        }
12465    }
12466
12467    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12468            int opti, boolean dumpAll, String dumpPackage) {
12469        boolean needSep = false;
12470        boolean printedAnything = false;
12471        int numPers = 0;
12472
12473        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12474
12475        if (dumpAll) {
12476            final int NP = mProcessNames.getMap().size();
12477            for (int ip=0; ip<NP; ip++) {
12478                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12479                final int NA = procs.size();
12480                for (int ia=0; ia<NA; ia++) {
12481                    ProcessRecord r = procs.valueAt(ia);
12482                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12483                        continue;
12484                    }
12485                    if (!needSep) {
12486                        pw.println("  All known processes:");
12487                        needSep = true;
12488                        printedAnything = true;
12489                    }
12490                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12491                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12492                        pw.print(" "); pw.println(r);
12493                    r.dump(pw, "    ");
12494                    if (r.persistent) {
12495                        numPers++;
12496                    }
12497                }
12498            }
12499        }
12500
12501        if (mIsolatedProcesses.size() > 0) {
12502            boolean printed = false;
12503            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12504                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12505                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12506                    continue;
12507                }
12508                if (!printed) {
12509                    if (needSep) {
12510                        pw.println();
12511                    }
12512                    pw.println("  Isolated process list (sorted by uid):");
12513                    printedAnything = true;
12514                    printed = true;
12515                    needSep = true;
12516                }
12517                pw.println(String.format("%sIsolated #%2d: %s",
12518                        "    ", i, r.toString()));
12519            }
12520        }
12521
12522        if (mLruProcesses.size() > 0) {
12523            if (needSep) {
12524                pw.println();
12525            }
12526            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12527                    pw.print(" total, non-act at ");
12528                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12529                    pw.print(", non-svc at ");
12530                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12531                    pw.println("):");
12532            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12533            needSep = true;
12534            printedAnything = true;
12535        }
12536
12537        if (dumpAll || dumpPackage != null) {
12538            synchronized (mPidsSelfLocked) {
12539                boolean printed = false;
12540                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12541                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12542                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12543                        continue;
12544                    }
12545                    if (!printed) {
12546                        if (needSep) pw.println();
12547                        needSep = true;
12548                        pw.println("  PID mappings:");
12549                        printed = true;
12550                        printedAnything = true;
12551                    }
12552                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12553                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12554                }
12555            }
12556        }
12557
12558        if (mForegroundProcesses.size() > 0) {
12559            synchronized (mPidsSelfLocked) {
12560                boolean printed = false;
12561                for (int i=0; i<mForegroundProcesses.size(); i++) {
12562                    ProcessRecord r = mPidsSelfLocked.get(
12563                            mForegroundProcesses.valueAt(i).pid);
12564                    if (dumpPackage != null && (r == null
12565                            || !r.pkgList.containsKey(dumpPackage))) {
12566                        continue;
12567                    }
12568                    if (!printed) {
12569                        if (needSep) pw.println();
12570                        needSep = true;
12571                        pw.println("  Foreground Processes:");
12572                        printed = true;
12573                        printedAnything = true;
12574                    }
12575                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12576                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12577                }
12578            }
12579        }
12580
12581        if (mPersistentStartingProcesses.size() > 0) {
12582            if (needSep) pw.println();
12583            needSep = true;
12584            printedAnything = true;
12585            pw.println("  Persisent processes that are starting:");
12586            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12587                    "Starting Norm", "Restarting PERS", dumpPackage);
12588        }
12589
12590        if (mRemovedProcesses.size() > 0) {
12591            if (needSep) pw.println();
12592            needSep = true;
12593            printedAnything = true;
12594            pw.println("  Processes that are being removed:");
12595            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12596                    "Removed Norm", "Removed PERS", dumpPackage);
12597        }
12598
12599        if (mProcessesOnHold.size() > 0) {
12600            if (needSep) pw.println();
12601            needSep = true;
12602            printedAnything = true;
12603            pw.println("  Processes that are on old until the system is ready:");
12604            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12605                    "OnHold Norm", "OnHold PERS", dumpPackage);
12606        }
12607
12608        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12609
12610        if (mProcessCrashTimes.getMap().size() > 0) {
12611            boolean printed = false;
12612            long now = SystemClock.uptimeMillis();
12613            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12614            final int NP = pmap.size();
12615            for (int ip=0; ip<NP; ip++) {
12616                String pname = pmap.keyAt(ip);
12617                SparseArray<Long> uids = pmap.valueAt(ip);
12618                final int N = uids.size();
12619                for (int i=0; i<N; i++) {
12620                    int puid = uids.keyAt(i);
12621                    ProcessRecord r = mProcessNames.get(pname, puid);
12622                    if (dumpPackage != null && (r == null
12623                            || !r.pkgList.containsKey(dumpPackage))) {
12624                        continue;
12625                    }
12626                    if (!printed) {
12627                        if (needSep) pw.println();
12628                        needSep = true;
12629                        pw.println("  Time since processes crashed:");
12630                        printed = true;
12631                        printedAnything = true;
12632                    }
12633                    pw.print("    Process "); pw.print(pname);
12634                            pw.print(" uid "); pw.print(puid);
12635                            pw.print(": last crashed ");
12636                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12637                            pw.println(" ago");
12638                }
12639            }
12640        }
12641
12642        if (mBadProcesses.getMap().size() > 0) {
12643            boolean printed = false;
12644            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12645            final int NP = pmap.size();
12646            for (int ip=0; ip<NP; ip++) {
12647                String pname = pmap.keyAt(ip);
12648                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12649                final int N = uids.size();
12650                for (int i=0; i<N; i++) {
12651                    int puid = uids.keyAt(i);
12652                    ProcessRecord r = mProcessNames.get(pname, puid);
12653                    if (dumpPackage != null && (r == null
12654                            || !r.pkgList.containsKey(dumpPackage))) {
12655                        continue;
12656                    }
12657                    if (!printed) {
12658                        if (needSep) pw.println();
12659                        needSep = true;
12660                        pw.println("  Bad processes:");
12661                        printedAnything = true;
12662                    }
12663                    BadProcessInfo info = uids.valueAt(i);
12664                    pw.print("    Bad process "); pw.print(pname);
12665                            pw.print(" uid "); pw.print(puid);
12666                            pw.print(": crashed at time "); pw.println(info.time);
12667                    if (info.shortMsg != null) {
12668                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12669                    }
12670                    if (info.longMsg != null) {
12671                        pw.print("      Long msg: "); pw.println(info.longMsg);
12672                    }
12673                    if (info.stack != null) {
12674                        pw.println("      Stack:");
12675                        int lastPos = 0;
12676                        for (int pos=0; pos<info.stack.length(); pos++) {
12677                            if (info.stack.charAt(pos) == '\n') {
12678                                pw.print("        ");
12679                                pw.write(info.stack, lastPos, pos-lastPos);
12680                                pw.println();
12681                                lastPos = pos+1;
12682                            }
12683                        }
12684                        if (lastPos < info.stack.length()) {
12685                            pw.print("        ");
12686                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12687                            pw.println();
12688                        }
12689                    }
12690                }
12691            }
12692        }
12693
12694        if (dumpPackage == null) {
12695            pw.println();
12696            needSep = false;
12697            pw.println("  mStartedUsers:");
12698            for (int i=0; i<mStartedUsers.size(); i++) {
12699                UserStartedState uss = mStartedUsers.valueAt(i);
12700                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12701                        pw.print(": "); uss.dump("", pw);
12702            }
12703            pw.print("  mStartedUserArray: [");
12704            for (int i=0; i<mStartedUserArray.length; i++) {
12705                if (i > 0) pw.print(", ");
12706                pw.print(mStartedUserArray[i]);
12707            }
12708            pw.println("]");
12709            pw.print("  mUserLru: [");
12710            for (int i=0; i<mUserLru.size(); i++) {
12711                if (i > 0) pw.print(", ");
12712                pw.print(mUserLru.get(i));
12713            }
12714            pw.println("]");
12715            if (dumpAll) {
12716                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12717            }
12718            synchronized (mUserProfileGroupIdsSelfLocked) {
12719                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12720                    pw.println("  mUserProfileGroupIds:");
12721                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12722                        pw.print("    User #");
12723                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12724                        pw.print(" -> profile #");
12725                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12726                    }
12727                }
12728            }
12729        }
12730        if (mHomeProcess != null && (dumpPackage == null
12731                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12732            if (needSep) {
12733                pw.println();
12734                needSep = false;
12735            }
12736            pw.println("  mHomeProcess: " + mHomeProcess);
12737        }
12738        if (mPreviousProcess != null && (dumpPackage == null
12739                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12740            if (needSep) {
12741                pw.println();
12742                needSep = false;
12743            }
12744            pw.println("  mPreviousProcess: " + mPreviousProcess);
12745        }
12746        if (dumpAll) {
12747            StringBuilder sb = new StringBuilder(128);
12748            sb.append("  mPreviousProcessVisibleTime: ");
12749            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12750            pw.println(sb);
12751        }
12752        if (mHeavyWeightProcess != null && (dumpPackage == null
12753                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12754            if (needSep) {
12755                pw.println();
12756                needSep = false;
12757            }
12758            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12759        }
12760        if (dumpPackage == null) {
12761            pw.println("  mConfiguration: " + mConfiguration);
12762        }
12763        if (dumpAll) {
12764            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12765            if (mCompatModePackages.getPackages().size() > 0) {
12766                boolean printed = false;
12767                for (Map.Entry<String, Integer> entry
12768                        : mCompatModePackages.getPackages().entrySet()) {
12769                    String pkg = entry.getKey();
12770                    int mode = entry.getValue();
12771                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12772                        continue;
12773                    }
12774                    if (!printed) {
12775                        pw.println("  mScreenCompatPackages:");
12776                        printed = true;
12777                    }
12778                    pw.print("    "); pw.print(pkg); pw.print(": ");
12779                            pw.print(mode); pw.println();
12780                }
12781            }
12782        }
12783        if (dumpPackage == null) {
12784            if (mSleeping || mWentToSleep || mLockScreenShown) {
12785                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12786                        + " mLockScreenShown " + mLockScreenShown);
12787            }
12788            if (mShuttingDown || mRunningVoice) {
12789                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12790            }
12791        }
12792        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12793                || mOrigWaitForDebugger) {
12794            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12795                    || dumpPackage.equals(mOrigDebugApp)) {
12796                if (needSep) {
12797                    pw.println();
12798                    needSep = false;
12799                }
12800                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12801                        + " mDebugTransient=" + mDebugTransient
12802                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12803            }
12804        }
12805        if (mOpenGlTraceApp != null) {
12806            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12807                if (needSep) {
12808                    pw.println();
12809                    needSep = false;
12810                }
12811                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12812            }
12813        }
12814        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12815                || mProfileFd != null) {
12816            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12817                if (needSep) {
12818                    pw.println();
12819                    needSep = false;
12820                }
12821                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12822                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12823                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12824                        + mAutoStopProfiler);
12825                pw.println("  mProfileType=" + mProfileType);
12826            }
12827        }
12828        if (dumpPackage == null) {
12829            if (mAlwaysFinishActivities || mController != null) {
12830                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12831                        + " mController=" + mController);
12832            }
12833            if (dumpAll) {
12834                pw.println("  Total persistent processes: " + numPers);
12835                pw.println("  mProcessesReady=" + mProcessesReady
12836                        + " mSystemReady=" + mSystemReady
12837                        + " mBooted=" + mBooted
12838                        + " mFactoryTest=" + mFactoryTest);
12839                pw.println("  mBooting=" + mBooting
12840                        + " mCallFinishBooting=" + mCallFinishBooting
12841                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12842                pw.print("  mLastPowerCheckRealtime=");
12843                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12844                        pw.println("");
12845                pw.print("  mLastPowerCheckUptime=");
12846                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12847                        pw.println("");
12848                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12849                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12850                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12851                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12852                        + " (" + mLruProcesses.size() + " total)"
12853                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12854                        + " mNumServiceProcs=" + mNumServiceProcs
12855                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12856                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12857                        + " mLastMemoryLevel" + mLastMemoryLevel
12858                        + " mLastNumProcesses" + mLastNumProcesses);
12859                long now = SystemClock.uptimeMillis();
12860                pw.print("  mLastIdleTime=");
12861                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12862                        pw.print(" mLowRamSinceLastIdle=");
12863                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12864                        pw.println();
12865            }
12866        }
12867
12868        if (!printedAnything) {
12869            pw.println("  (nothing)");
12870        }
12871    }
12872
12873    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12874            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12875        if (mProcessesToGc.size() > 0) {
12876            boolean printed = false;
12877            long now = SystemClock.uptimeMillis();
12878            for (int i=0; i<mProcessesToGc.size(); i++) {
12879                ProcessRecord proc = mProcessesToGc.get(i);
12880                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12881                    continue;
12882                }
12883                if (!printed) {
12884                    if (needSep) pw.println();
12885                    needSep = true;
12886                    pw.println("  Processes that are waiting to GC:");
12887                    printed = true;
12888                }
12889                pw.print("    Process "); pw.println(proc);
12890                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12891                        pw.print(", last gced=");
12892                        pw.print(now-proc.lastRequestedGc);
12893                        pw.print(" ms ago, last lowMem=");
12894                        pw.print(now-proc.lastLowMemory);
12895                        pw.println(" ms ago");
12896
12897            }
12898        }
12899        return needSep;
12900    }
12901
12902    void printOomLevel(PrintWriter pw, String name, int adj) {
12903        pw.print("    ");
12904        if (adj >= 0) {
12905            pw.print(' ');
12906            if (adj < 10) pw.print(' ');
12907        } else {
12908            if (adj > -10) pw.print(' ');
12909        }
12910        pw.print(adj);
12911        pw.print(": ");
12912        pw.print(name);
12913        pw.print(" (");
12914        pw.print(mProcessList.getMemLevel(adj)/1024);
12915        pw.println(" kB)");
12916    }
12917
12918    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12919            int opti, boolean dumpAll) {
12920        boolean needSep = false;
12921
12922        if (mLruProcesses.size() > 0) {
12923            if (needSep) pw.println();
12924            needSep = true;
12925            pw.println("  OOM levels:");
12926            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12927            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12928            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
12929            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12930            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12931            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12932            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12933            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12934            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12935            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12936            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12937            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12938            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12939            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12940
12941            if (needSep) pw.println();
12942            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12943                    pw.print(" total, non-act at ");
12944                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12945                    pw.print(", non-svc at ");
12946                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12947                    pw.println("):");
12948            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12949            needSep = true;
12950        }
12951
12952        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12953
12954        pw.println();
12955        pw.println("  mHomeProcess: " + mHomeProcess);
12956        pw.println("  mPreviousProcess: " + mPreviousProcess);
12957        if (mHeavyWeightProcess != null) {
12958            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12959        }
12960
12961        return true;
12962    }
12963
12964    /**
12965     * There are three ways to call this:
12966     *  - no provider specified: dump all the providers
12967     *  - a flattened component name that matched an existing provider was specified as the
12968     *    first arg: dump that one provider
12969     *  - the first arg isn't the flattened component name of an existing provider:
12970     *    dump all providers whose component contains the first arg as a substring
12971     */
12972    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12973            int opti, boolean dumpAll) {
12974        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12975    }
12976
12977    static class ItemMatcher {
12978        ArrayList<ComponentName> components;
12979        ArrayList<String> strings;
12980        ArrayList<Integer> objects;
12981        boolean all;
12982
12983        ItemMatcher() {
12984            all = true;
12985        }
12986
12987        void build(String name) {
12988            ComponentName componentName = ComponentName.unflattenFromString(name);
12989            if (componentName != null) {
12990                if (components == null) {
12991                    components = new ArrayList<ComponentName>();
12992                }
12993                components.add(componentName);
12994                all = false;
12995            } else {
12996                int objectId = 0;
12997                // Not a '/' separated full component name; maybe an object ID?
12998                try {
12999                    objectId = Integer.parseInt(name, 16);
13000                    if (objects == null) {
13001                        objects = new ArrayList<Integer>();
13002                    }
13003                    objects.add(objectId);
13004                    all = false;
13005                } catch (RuntimeException e) {
13006                    // Not an integer; just do string match.
13007                    if (strings == null) {
13008                        strings = new ArrayList<String>();
13009                    }
13010                    strings.add(name);
13011                    all = false;
13012                }
13013            }
13014        }
13015
13016        int build(String[] args, int opti) {
13017            for (; opti<args.length; opti++) {
13018                String name = args[opti];
13019                if ("--".equals(name)) {
13020                    return opti+1;
13021                }
13022                build(name);
13023            }
13024            return opti;
13025        }
13026
13027        boolean match(Object object, ComponentName comp) {
13028            if (all) {
13029                return true;
13030            }
13031            if (components != null) {
13032                for (int i=0; i<components.size(); i++) {
13033                    if (components.get(i).equals(comp)) {
13034                        return true;
13035                    }
13036                }
13037            }
13038            if (objects != null) {
13039                for (int i=0; i<objects.size(); i++) {
13040                    if (System.identityHashCode(object) == objects.get(i)) {
13041                        return true;
13042                    }
13043                }
13044            }
13045            if (strings != null) {
13046                String flat = comp.flattenToString();
13047                for (int i=0; i<strings.size(); i++) {
13048                    if (flat.contains(strings.get(i))) {
13049                        return true;
13050                    }
13051                }
13052            }
13053            return false;
13054        }
13055    }
13056
13057    /**
13058     * There are three things that cmd can be:
13059     *  - a flattened component name that matches an existing activity
13060     *  - the cmd arg isn't the flattened component name of an existing activity:
13061     *    dump all activity whose component contains the cmd as a substring
13062     *  - A hex number of the ActivityRecord object instance.
13063     */
13064    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13065            int opti, boolean dumpAll) {
13066        ArrayList<ActivityRecord> activities;
13067
13068        synchronized (this) {
13069            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13070        }
13071
13072        if (activities.size() <= 0) {
13073            return false;
13074        }
13075
13076        String[] newArgs = new String[args.length - opti];
13077        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13078
13079        TaskRecord lastTask = null;
13080        boolean needSep = false;
13081        for (int i=activities.size()-1; i>=0; i--) {
13082            ActivityRecord r = activities.get(i);
13083            if (needSep) {
13084                pw.println();
13085            }
13086            needSep = true;
13087            synchronized (this) {
13088                if (lastTask != r.task) {
13089                    lastTask = r.task;
13090                    pw.print("TASK "); pw.print(lastTask.affinity);
13091                            pw.print(" id="); pw.println(lastTask.taskId);
13092                    if (dumpAll) {
13093                        lastTask.dump(pw, "  ");
13094                    }
13095                }
13096            }
13097            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13098        }
13099        return true;
13100    }
13101
13102    /**
13103     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13104     * there is a thread associated with the activity.
13105     */
13106    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13107            final ActivityRecord r, String[] args, boolean dumpAll) {
13108        String innerPrefix = prefix + "  ";
13109        synchronized (this) {
13110            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13111                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13112                    pw.print(" pid=");
13113                    if (r.app != null) pw.println(r.app.pid);
13114                    else pw.println("(not running)");
13115            if (dumpAll) {
13116                r.dump(pw, innerPrefix);
13117            }
13118        }
13119        if (r.app != null && r.app.thread != null) {
13120            // flush anything that is already in the PrintWriter since the thread is going
13121            // to write to the file descriptor directly
13122            pw.flush();
13123            try {
13124                TransferPipe tp = new TransferPipe();
13125                try {
13126                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13127                            r.appToken, innerPrefix, args);
13128                    tp.go(fd);
13129                } finally {
13130                    tp.kill();
13131                }
13132            } catch (IOException e) {
13133                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13134            } catch (RemoteException e) {
13135                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13136            }
13137        }
13138    }
13139
13140    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13141            int opti, boolean dumpAll, String dumpPackage) {
13142        boolean needSep = false;
13143        boolean onlyHistory = false;
13144        boolean printedAnything = false;
13145
13146        if ("history".equals(dumpPackage)) {
13147            if (opti < args.length && "-s".equals(args[opti])) {
13148                dumpAll = false;
13149            }
13150            onlyHistory = true;
13151            dumpPackage = null;
13152        }
13153
13154        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13155        if (!onlyHistory && dumpAll) {
13156            if (mRegisteredReceivers.size() > 0) {
13157                boolean printed = false;
13158                Iterator it = mRegisteredReceivers.values().iterator();
13159                while (it.hasNext()) {
13160                    ReceiverList r = (ReceiverList)it.next();
13161                    if (dumpPackage != null && (r.app == null ||
13162                            !dumpPackage.equals(r.app.info.packageName))) {
13163                        continue;
13164                    }
13165                    if (!printed) {
13166                        pw.println("  Registered Receivers:");
13167                        needSep = true;
13168                        printed = true;
13169                        printedAnything = true;
13170                    }
13171                    pw.print("  * "); pw.println(r);
13172                    r.dump(pw, "    ");
13173                }
13174            }
13175
13176            if (mReceiverResolver.dump(pw, needSep ?
13177                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13178                    "    ", dumpPackage, false)) {
13179                needSep = true;
13180                printedAnything = true;
13181            }
13182        }
13183
13184        for (BroadcastQueue q : mBroadcastQueues) {
13185            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13186            printedAnything |= needSep;
13187        }
13188
13189        needSep = true;
13190
13191        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13192            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13193                if (needSep) {
13194                    pw.println();
13195                }
13196                needSep = true;
13197                printedAnything = true;
13198                pw.print("  Sticky broadcasts for user ");
13199                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13200                StringBuilder sb = new StringBuilder(128);
13201                for (Map.Entry<String, ArrayList<Intent>> ent
13202                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13203                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13204                    if (dumpAll) {
13205                        pw.println(":");
13206                        ArrayList<Intent> intents = ent.getValue();
13207                        final int N = intents.size();
13208                        for (int i=0; i<N; i++) {
13209                            sb.setLength(0);
13210                            sb.append("    Intent: ");
13211                            intents.get(i).toShortString(sb, false, true, false, false);
13212                            pw.println(sb.toString());
13213                            Bundle bundle = intents.get(i).getExtras();
13214                            if (bundle != null) {
13215                                pw.print("      ");
13216                                pw.println(bundle.toString());
13217                            }
13218                        }
13219                    } else {
13220                        pw.println("");
13221                    }
13222                }
13223            }
13224        }
13225
13226        if (!onlyHistory && dumpAll) {
13227            pw.println();
13228            for (BroadcastQueue queue : mBroadcastQueues) {
13229                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13230                        + queue.mBroadcastsScheduled);
13231            }
13232            pw.println("  mHandler:");
13233            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13234            needSep = true;
13235            printedAnything = true;
13236        }
13237
13238        if (!printedAnything) {
13239            pw.println("  (nothing)");
13240        }
13241    }
13242
13243    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13244            int opti, boolean dumpAll, String dumpPackage) {
13245        boolean needSep;
13246        boolean printedAnything = false;
13247
13248        ItemMatcher matcher = new ItemMatcher();
13249        matcher.build(args, opti);
13250
13251        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13252
13253        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13254        printedAnything |= needSep;
13255
13256        if (mLaunchingProviders.size() > 0) {
13257            boolean printed = false;
13258            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13259                ContentProviderRecord r = mLaunchingProviders.get(i);
13260                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13261                    continue;
13262                }
13263                if (!printed) {
13264                    if (needSep) pw.println();
13265                    needSep = true;
13266                    pw.println("  Launching content providers:");
13267                    printed = true;
13268                    printedAnything = true;
13269                }
13270                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13271                        pw.println(r);
13272            }
13273        }
13274
13275        if (mGrantedUriPermissions.size() > 0) {
13276            boolean printed = false;
13277            int dumpUid = -2;
13278            if (dumpPackage != null) {
13279                try {
13280                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13281                } catch (NameNotFoundException e) {
13282                    dumpUid = -1;
13283                }
13284            }
13285            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13286                int uid = mGrantedUriPermissions.keyAt(i);
13287                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13288                    continue;
13289                }
13290                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13291                if (!printed) {
13292                    if (needSep) pw.println();
13293                    needSep = true;
13294                    pw.println("  Granted Uri Permissions:");
13295                    printed = true;
13296                    printedAnything = true;
13297                }
13298                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13299                for (UriPermission perm : perms.values()) {
13300                    pw.print("    "); pw.println(perm);
13301                    if (dumpAll) {
13302                        perm.dump(pw, "      ");
13303                    }
13304                }
13305            }
13306        }
13307
13308        if (!printedAnything) {
13309            pw.println("  (nothing)");
13310        }
13311    }
13312
13313    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13314            int opti, boolean dumpAll, String dumpPackage) {
13315        boolean printed = false;
13316
13317        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13318
13319        if (mIntentSenderRecords.size() > 0) {
13320            Iterator<WeakReference<PendingIntentRecord>> it
13321                    = mIntentSenderRecords.values().iterator();
13322            while (it.hasNext()) {
13323                WeakReference<PendingIntentRecord> ref = it.next();
13324                PendingIntentRecord rec = ref != null ? ref.get(): null;
13325                if (dumpPackage != null && (rec == null
13326                        || !dumpPackage.equals(rec.key.packageName))) {
13327                    continue;
13328                }
13329                printed = true;
13330                if (rec != null) {
13331                    pw.print("  * "); pw.println(rec);
13332                    if (dumpAll) {
13333                        rec.dump(pw, "    ");
13334                    }
13335                } else {
13336                    pw.print("  * "); pw.println(ref);
13337                }
13338            }
13339        }
13340
13341        if (!printed) {
13342            pw.println("  (nothing)");
13343        }
13344    }
13345
13346    private static final int dumpProcessList(PrintWriter pw,
13347            ActivityManagerService service, List list,
13348            String prefix, String normalLabel, String persistentLabel,
13349            String dumpPackage) {
13350        int numPers = 0;
13351        final int N = list.size()-1;
13352        for (int i=N; i>=0; i--) {
13353            ProcessRecord r = (ProcessRecord)list.get(i);
13354            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13355                continue;
13356            }
13357            pw.println(String.format("%s%s #%2d: %s",
13358                    prefix, (r.persistent ? persistentLabel : normalLabel),
13359                    i, r.toString()));
13360            if (r.persistent) {
13361                numPers++;
13362            }
13363        }
13364        return numPers;
13365    }
13366
13367    private static final boolean dumpProcessOomList(PrintWriter pw,
13368            ActivityManagerService service, List<ProcessRecord> origList,
13369            String prefix, String normalLabel, String persistentLabel,
13370            boolean inclDetails, String dumpPackage) {
13371
13372        ArrayList<Pair<ProcessRecord, Integer>> list
13373                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13374        for (int i=0; i<origList.size(); i++) {
13375            ProcessRecord r = origList.get(i);
13376            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13377                continue;
13378            }
13379            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13380        }
13381
13382        if (list.size() <= 0) {
13383            return false;
13384        }
13385
13386        Comparator<Pair<ProcessRecord, Integer>> comparator
13387                = new Comparator<Pair<ProcessRecord, Integer>>() {
13388            @Override
13389            public int compare(Pair<ProcessRecord, Integer> object1,
13390                    Pair<ProcessRecord, Integer> object2) {
13391                if (object1.first.setAdj != object2.first.setAdj) {
13392                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13393                }
13394                if (object1.second.intValue() != object2.second.intValue()) {
13395                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13396                }
13397                return 0;
13398            }
13399        };
13400
13401        Collections.sort(list, comparator);
13402
13403        final long curRealtime = SystemClock.elapsedRealtime();
13404        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13405        final long curUptime = SystemClock.uptimeMillis();
13406        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13407
13408        for (int i=list.size()-1; i>=0; i--) {
13409            ProcessRecord r = list.get(i).first;
13410            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13411            char schedGroup;
13412            switch (r.setSchedGroup) {
13413                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13414                    schedGroup = 'B';
13415                    break;
13416                case Process.THREAD_GROUP_DEFAULT:
13417                    schedGroup = 'F';
13418                    break;
13419                default:
13420                    schedGroup = '?';
13421                    break;
13422            }
13423            char foreground;
13424            if (r.foregroundActivities) {
13425                foreground = 'A';
13426            } else if (r.foregroundServices) {
13427                foreground = 'S';
13428            } else {
13429                foreground = ' ';
13430            }
13431            String procState = ProcessList.makeProcStateString(r.curProcState);
13432            pw.print(prefix);
13433            pw.print(r.persistent ? persistentLabel : normalLabel);
13434            pw.print(" #");
13435            int num = (origList.size()-1)-list.get(i).second;
13436            if (num < 10) pw.print(' ');
13437            pw.print(num);
13438            pw.print(": ");
13439            pw.print(oomAdj);
13440            pw.print(' ');
13441            pw.print(schedGroup);
13442            pw.print('/');
13443            pw.print(foreground);
13444            pw.print('/');
13445            pw.print(procState);
13446            pw.print(" trm:");
13447            if (r.trimMemoryLevel < 10) pw.print(' ');
13448            pw.print(r.trimMemoryLevel);
13449            pw.print(' ');
13450            pw.print(r.toShortString());
13451            pw.print(" (");
13452            pw.print(r.adjType);
13453            pw.println(')');
13454            if (r.adjSource != null || r.adjTarget != null) {
13455                pw.print(prefix);
13456                pw.print("    ");
13457                if (r.adjTarget instanceof ComponentName) {
13458                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13459                } else if (r.adjTarget != null) {
13460                    pw.print(r.adjTarget.toString());
13461                } else {
13462                    pw.print("{null}");
13463                }
13464                pw.print("<=");
13465                if (r.adjSource instanceof ProcessRecord) {
13466                    pw.print("Proc{");
13467                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13468                    pw.println("}");
13469                } else if (r.adjSource != null) {
13470                    pw.println(r.adjSource.toString());
13471                } else {
13472                    pw.println("{null}");
13473                }
13474            }
13475            if (inclDetails) {
13476                pw.print(prefix);
13477                pw.print("    ");
13478                pw.print("oom: max="); pw.print(r.maxAdj);
13479                pw.print(" curRaw="); pw.print(r.curRawAdj);
13480                pw.print(" setRaw="); pw.print(r.setRawAdj);
13481                pw.print(" cur="); pw.print(r.curAdj);
13482                pw.print(" set="); pw.println(r.setAdj);
13483                pw.print(prefix);
13484                pw.print("    ");
13485                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13486                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13487                pw.print(" lastPss="); pw.print(r.lastPss);
13488                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13489                pw.print(prefix);
13490                pw.print("    ");
13491                pw.print("cached="); pw.print(r.cached);
13492                pw.print(" empty="); pw.print(r.empty);
13493                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13494
13495                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13496                    if (r.lastWakeTime != 0) {
13497                        long wtime;
13498                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13499                        synchronized (stats) {
13500                            wtime = stats.getProcessWakeTime(r.info.uid,
13501                                    r.pid, curRealtime);
13502                        }
13503                        long timeUsed = wtime - r.lastWakeTime;
13504                        pw.print(prefix);
13505                        pw.print("    ");
13506                        pw.print("keep awake over ");
13507                        TimeUtils.formatDuration(realtimeSince, pw);
13508                        pw.print(" used ");
13509                        TimeUtils.formatDuration(timeUsed, pw);
13510                        pw.print(" (");
13511                        pw.print((timeUsed*100)/realtimeSince);
13512                        pw.println("%)");
13513                    }
13514                    if (r.lastCpuTime != 0) {
13515                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13516                        pw.print(prefix);
13517                        pw.print("    ");
13518                        pw.print("run cpu over ");
13519                        TimeUtils.formatDuration(uptimeSince, pw);
13520                        pw.print(" used ");
13521                        TimeUtils.formatDuration(timeUsed, pw);
13522                        pw.print(" (");
13523                        pw.print((timeUsed*100)/uptimeSince);
13524                        pw.println("%)");
13525                    }
13526                }
13527            }
13528        }
13529        return true;
13530    }
13531
13532    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13533            String[] args) {
13534        ArrayList<ProcessRecord> procs;
13535        synchronized (this) {
13536            if (args != null && args.length > start
13537                    && args[start].charAt(0) != '-') {
13538                procs = new ArrayList<ProcessRecord>();
13539                int pid = -1;
13540                try {
13541                    pid = Integer.parseInt(args[start]);
13542                } catch (NumberFormatException e) {
13543                }
13544                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13545                    ProcessRecord proc = mLruProcesses.get(i);
13546                    if (proc.pid == pid) {
13547                        procs.add(proc);
13548                    } else if (allPkgs && proc.pkgList != null
13549                            && proc.pkgList.containsKey(args[start])) {
13550                        procs.add(proc);
13551                    } else if (proc.processName.equals(args[start])) {
13552                        procs.add(proc);
13553                    }
13554                }
13555                if (procs.size() <= 0) {
13556                    return null;
13557                }
13558            } else {
13559                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13560            }
13561        }
13562        return procs;
13563    }
13564
13565    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13566            PrintWriter pw, String[] args) {
13567        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13568        if (procs == null) {
13569            pw.println("No process found for: " + args[0]);
13570            return;
13571        }
13572
13573        long uptime = SystemClock.uptimeMillis();
13574        long realtime = SystemClock.elapsedRealtime();
13575        pw.println("Applications Graphics Acceleration Info:");
13576        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13577
13578        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13579            ProcessRecord r = procs.get(i);
13580            if (r.thread != null) {
13581                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13582                pw.flush();
13583                try {
13584                    TransferPipe tp = new TransferPipe();
13585                    try {
13586                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13587                        tp.go(fd);
13588                    } finally {
13589                        tp.kill();
13590                    }
13591                } catch (IOException e) {
13592                    pw.println("Failure while dumping the app: " + r);
13593                    pw.flush();
13594                } catch (RemoteException e) {
13595                    pw.println("Got a RemoteException while dumping the app " + r);
13596                    pw.flush();
13597                }
13598            }
13599        }
13600    }
13601
13602    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13603        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13604        if (procs == null) {
13605            pw.println("No process found for: " + args[0]);
13606            return;
13607        }
13608
13609        pw.println("Applications Database Info:");
13610
13611        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13612            ProcessRecord r = procs.get(i);
13613            if (r.thread != null) {
13614                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13615                pw.flush();
13616                try {
13617                    TransferPipe tp = new TransferPipe();
13618                    try {
13619                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13620                        tp.go(fd);
13621                    } finally {
13622                        tp.kill();
13623                    }
13624                } catch (IOException e) {
13625                    pw.println("Failure while dumping the app: " + r);
13626                    pw.flush();
13627                } catch (RemoteException e) {
13628                    pw.println("Got a RemoteException while dumping the app " + r);
13629                    pw.flush();
13630                }
13631            }
13632        }
13633    }
13634
13635    final static class MemItem {
13636        final boolean isProc;
13637        final String label;
13638        final String shortLabel;
13639        final long pss;
13640        final int id;
13641        final boolean hasActivities;
13642        ArrayList<MemItem> subitems;
13643
13644        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13645                boolean _hasActivities) {
13646            isProc = true;
13647            label = _label;
13648            shortLabel = _shortLabel;
13649            pss = _pss;
13650            id = _id;
13651            hasActivities = _hasActivities;
13652        }
13653
13654        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13655            isProc = false;
13656            label = _label;
13657            shortLabel = _shortLabel;
13658            pss = _pss;
13659            id = _id;
13660            hasActivities = false;
13661        }
13662    }
13663
13664    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13665            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13666        if (sort && !isCompact) {
13667            Collections.sort(items, new Comparator<MemItem>() {
13668                @Override
13669                public int compare(MemItem lhs, MemItem rhs) {
13670                    if (lhs.pss < rhs.pss) {
13671                        return 1;
13672                    } else if (lhs.pss > rhs.pss) {
13673                        return -1;
13674                    }
13675                    return 0;
13676                }
13677            });
13678        }
13679
13680        for (int i=0; i<items.size(); i++) {
13681            MemItem mi = items.get(i);
13682            if (!isCompact) {
13683                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13684            } else if (mi.isProc) {
13685                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13686                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13687                pw.println(mi.hasActivities ? ",a" : ",e");
13688            } else {
13689                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13690                pw.println(mi.pss);
13691            }
13692            if (mi.subitems != null) {
13693                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13694                        true, isCompact);
13695            }
13696        }
13697    }
13698
13699    // These are in KB.
13700    static final long[] DUMP_MEM_BUCKETS = new long[] {
13701        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13702        120*1024, 160*1024, 200*1024,
13703        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13704        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13705    };
13706
13707    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13708            boolean stackLike) {
13709        int start = label.lastIndexOf('.');
13710        if (start >= 0) start++;
13711        else start = 0;
13712        int end = label.length();
13713        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13714            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13715                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13716                out.append(bucket);
13717                out.append(stackLike ? "MB." : "MB ");
13718                out.append(label, start, end);
13719                return;
13720            }
13721        }
13722        out.append(memKB/1024);
13723        out.append(stackLike ? "MB." : "MB ");
13724        out.append(label, start, end);
13725    }
13726
13727    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13728            ProcessList.NATIVE_ADJ,
13729            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13730            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13731            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13732            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13733            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13734            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13735    };
13736    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13737            "Native",
13738            "System", "Persistent", "Persistent Service", "Foreground",
13739            "Visible", "Perceptible",
13740            "Heavy Weight", "Backup",
13741            "A Services", "Home",
13742            "Previous", "B Services", "Cached"
13743    };
13744    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13745            "native",
13746            "sys", "pers", "persvc", "fore",
13747            "vis", "percept",
13748            "heavy", "backup",
13749            "servicea", "home",
13750            "prev", "serviceb", "cached"
13751    };
13752
13753    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13754            long realtime, boolean isCheckinRequest, boolean isCompact) {
13755        if (isCheckinRequest || isCompact) {
13756            // short checkin version
13757            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13758        } else {
13759            pw.println("Applications Memory Usage (kB):");
13760            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13761        }
13762    }
13763
13764    private static final int KSM_SHARED = 0;
13765    private static final int KSM_SHARING = 1;
13766    private static final int KSM_UNSHARED = 2;
13767    private static final int KSM_VOLATILE = 3;
13768
13769    private final long[] getKsmInfo() {
13770        long[] longOut = new long[4];
13771        final int[] SINGLE_LONG_FORMAT = new int[] {
13772            Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13773        };
13774        long[] longTmp = new long[1];
13775        Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13776                SINGLE_LONG_FORMAT, null, longTmp, null);
13777        longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13778        longTmp[0] = 0;
13779        Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13780                SINGLE_LONG_FORMAT, null, longTmp, null);
13781        longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13782        longTmp[0] = 0;
13783        Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13784                SINGLE_LONG_FORMAT, null, longTmp, null);
13785        longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13786        longTmp[0] = 0;
13787        Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13788                SINGLE_LONG_FORMAT, null, longTmp, null);
13789        longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
13790        return longOut;
13791    }
13792
13793    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13794            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13795        boolean dumpDetails = false;
13796        boolean dumpFullDetails = false;
13797        boolean dumpDalvik = false;
13798        boolean oomOnly = false;
13799        boolean isCompact = false;
13800        boolean localOnly = false;
13801        boolean packages = false;
13802
13803        int opti = 0;
13804        while (opti < args.length) {
13805            String opt = args[opti];
13806            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13807                break;
13808            }
13809            opti++;
13810            if ("-a".equals(opt)) {
13811                dumpDetails = true;
13812                dumpFullDetails = true;
13813                dumpDalvik = true;
13814            } else if ("-d".equals(opt)) {
13815                dumpDalvik = true;
13816            } else if ("-c".equals(opt)) {
13817                isCompact = true;
13818            } else if ("--oom".equals(opt)) {
13819                oomOnly = true;
13820            } else if ("--local".equals(opt)) {
13821                localOnly = true;
13822            } else if ("--package".equals(opt)) {
13823                packages = true;
13824            } else if ("-h".equals(opt)) {
13825                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13826                pw.println("  -a: include all available information for each process.");
13827                pw.println("  -d: include dalvik details when dumping process details.");
13828                pw.println("  -c: dump in a compact machine-parseable representation.");
13829                pw.println("  --oom: only show processes organized by oom adj.");
13830                pw.println("  --local: only collect details locally, don't call process.");
13831                pw.println("  --package: interpret process arg as package, dumping all");
13832                pw.println("             processes that have loaded that package.");
13833                pw.println("If [process] is specified it can be the name or ");
13834                pw.println("pid of a specific process to dump.");
13835                return;
13836            } else {
13837                pw.println("Unknown argument: " + opt + "; use -h for help");
13838            }
13839        }
13840
13841        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13842        long uptime = SystemClock.uptimeMillis();
13843        long realtime = SystemClock.elapsedRealtime();
13844        final long[] tmpLong = new long[1];
13845
13846        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13847        if (procs == null) {
13848            // No Java processes.  Maybe they want to print a native process.
13849            if (args != null && args.length > opti
13850                    && args[opti].charAt(0) != '-') {
13851                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13852                        = new ArrayList<ProcessCpuTracker.Stats>();
13853                updateCpuStatsNow();
13854                int findPid = -1;
13855                try {
13856                    findPid = Integer.parseInt(args[opti]);
13857                } catch (NumberFormatException e) {
13858                }
13859                synchronized (mProcessCpuTracker) {
13860                    final int N = mProcessCpuTracker.countStats();
13861                    for (int i=0; i<N; i++) {
13862                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13863                        if (st.pid == findPid || (st.baseName != null
13864                                && st.baseName.equals(args[opti]))) {
13865                            nativeProcs.add(st);
13866                        }
13867                    }
13868                }
13869                if (nativeProcs.size() > 0) {
13870                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13871                            isCompact);
13872                    Debug.MemoryInfo mi = null;
13873                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13874                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13875                        final int pid = r.pid;
13876                        if (!isCheckinRequest && dumpDetails) {
13877                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13878                        }
13879                        if (mi == null) {
13880                            mi = new Debug.MemoryInfo();
13881                        }
13882                        if (dumpDetails || (!brief && !oomOnly)) {
13883                            Debug.getMemoryInfo(pid, mi);
13884                        } else {
13885                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13886                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13887                        }
13888                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13889                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13890                        if (isCheckinRequest) {
13891                            pw.println();
13892                        }
13893                    }
13894                    return;
13895                }
13896            }
13897            pw.println("No process found for: " + args[opti]);
13898            return;
13899        }
13900
13901        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
13902            dumpDetails = true;
13903        }
13904
13905        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13906
13907        String[] innerArgs = new String[args.length-opti];
13908        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13909
13910        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13911        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13912        long nativePss=0, dalvikPss=0, otherPss=0;
13913        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13914
13915        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13916        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13917                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13918
13919        long totalPss = 0;
13920        long cachedPss = 0;
13921
13922        Debug.MemoryInfo mi = null;
13923        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13924            final ProcessRecord r = procs.get(i);
13925            final IApplicationThread thread;
13926            final int pid;
13927            final int oomAdj;
13928            final boolean hasActivities;
13929            synchronized (this) {
13930                thread = r.thread;
13931                pid = r.pid;
13932                oomAdj = r.getSetAdjWithServices();
13933                hasActivities = r.activities.size() > 0;
13934            }
13935            if (thread != null) {
13936                if (!isCheckinRequest && dumpDetails) {
13937                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13938                }
13939                if (mi == null) {
13940                    mi = new Debug.MemoryInfo();
13941                }
13942                if (dumpDetails || (!brief && !oomOnly)) {
13943                    Debug.getMemoryInfo(pid, mi);
13944                } else {
13945                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13946                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13947                }
13948                if (dumpDetails) {
13949                    if (localOnly) {
13950                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13951                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13952                        if (isCheckinRequest) {
13953                            pw.println();
13954                        }
13955                    } else {
13956                        try {
13957                            pw.flush();
13958                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13959                                    dumpDalvik, innerArgs);
13960                        } catch (RemoteException e) {
13961                            if (!isCheckinRequest) {
13962                                pw.println("Got RemoteException!");
13963                                pw.flush();
13964                            }
13965                        }
13966                    }
13967                }
13968
13969                final long myTotalPss = mi.getTotalPss();
13970                final long myTotalUss = mi.getTotalUss();
13971
13972                synchronized (this) {
13973                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13974                        // Record this for posterity if the process has been stable.
13975                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13976                    }
13977                }
13978
13979                if (!isCheckinRequest && mi != null) {
13980                    totalPss += myTotalPss;
13981                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13982                            (hasActivities ? " / activities)" : ")"),
13983                            r.processName, myTotalPss, pid, hasActivities);
13984                    procMems.add(pssItem);
13985                    procMemsMap.put(pid, pssItem);
13986
13987                    nativePss += mi.nativePss;
13988                    dalvikPss += mi.dalvikPss;
13989                    otherPss += mi.otherPss;
13990                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13991                        long mem = mi.getOtherPss(j);
13992                        miscPss[j] += mem;
13993                        otherPss -= mem;
13994                    }
13995
13996                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13997                        cachedPss += myTotalPss;
13998                    }
13999
14000                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14001                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14002                                || oomIndex == (oomPss.length-1)) {
14003                            oomPss[oomIndex] += myTotalPss;
14004                            if (oomProcs[oomIndex] == null) {
14005                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14006                            }
14007                            oomProcs[oomIndex].add(pssItem);
14008                            break;
14009                        }
14010                    }
14011                }
14012            }
14013        }
14014
14015        long nativeProcTotalPss = 0;
14016
14017        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14018            // If we are showing aggregations, also look for native processes to
14019            // include so that our aggregations are more accurate.
14020            updateCpuStatsNow();
14021            synchronized (mProcessCpuTracker) {
14022                final int N = mProcessCpuTracker.countStats();
14023                for (int i=0; i<N; i++) {
14024                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14025                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14026                        if (mi == null) {
14027                            mi = new Debug.MemoryInfo();
14028                        }
14029                        if (!brief && !oomOnly) {
14030                            Debug.getMemoryInfo(st.pid, mi);
14031                        } else {
14032                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14033                            mi.nativePrivateDirty = (int)tmpLong[0];
14034                        }
14035
14036                        final long myTotalPss = mi.getTotalPss();
14037                        totalPss += myTotalPss;
14038                        nativeProcTotalPss += myTotalPss;
14039
14040                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14041                                st.name, myTotalPss, st.pid, false);
14042                        procMems.add(pssItem);
14043
14044                        nativePss += mi.nativePss;
14045                        dalvikPss += mi.dalvikPss;
14046                        otherPss += mi.otherPss;
14047                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14048                            long mem = mi.getOtherPss(j);
14049                            miscPss[j] += mem;
14050                            otherPss -= mem;
14051                        }
14052                        oomPss[0] += myTotalPss;
14053                        if (oomProcs[0] == null) {
14054                            oomProcs[0] = new ArrayList<MemItem>();
14055                        }
14056                        oomProcs[0].add(pssItem);
14057                    }
14058                }
14059            }
14060
14061            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14062
14063            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14064            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14065            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14066            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14067                String label = Debug.MemoryInfo.getOtherLabel(j);
14068                catMems.add(new MemItem(label, label, miscPss[j], j));
14069            }
14070
14071            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14072            for (int j=0; j<oomPss.length; j++) {
14073                if (oomPss[j] != 0) {
14074                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14075                            : DUMP_MEM_OOM_LABEL[j];
14076                    MemItem item = new MemItem(label, label, oomPss[j],
14077                            DUMP_MEM_OOM_ADJ[j]);
14078                    item.subitems = oomProcs[j];
14079                    oomMems.add(item);
14080                }
14081            }
14082
14083            if (!brief && !oomOnly && !isCompact) {
14084                pw.println();
14085                pw.println("Total PSS by process:");
14086                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14087                pw.println();
14088            }
14089            if (!isCompact) {
14090                pw.println("Total PSS by OOM adjustment:");
14091            }
14092            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14093            if (!brief && !oomOnly) {
14094                PrintWriter out = categoryPw != null ? categoryPw : pw;
14095                if (!isCompact) {
14096                    out.println();
14097                    out.println("Total PSS by category:");
14098                }
14099                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14100            }
14101            if (!isCompact) {
14102                pw.println();
14103            }
14104            MemInfoReader memInfo = new MemInfoReader();
14105            memInfo.readMemInfo();
14106            if (nativeProcTotalPss > 0) {
14107                synchronized (this) {
14108                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14109                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14110                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14111                }
14112            }
14113            if (!brief) {
14114                if (!isCompact) {
14115                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14116                    pw.print(" kB (status ");
14117                    switch (mLastMemoryLevel) {
14118                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14119                            pw.println("normal)");
14120                            break;
14121                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14122                            pw.println("moderate)");
14123                            break;
14124                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14125                            pw.println("low)");
14126                            break;
14127                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14128                            pw.println("critical)");
14129                            break;
14130                        default:
14131                            pw.print(mLastMemoryLevel);
14132                            pw.println(")");
14133                            break;
14134                    }
14135                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14136                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14137                            pw.print(cachedPss); pw.print(" cached pss + ");
14138                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14139                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14140                } else {
14141                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14142                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14143                            + memInfo.getFreeSizeKb()); pw.print(",");
14144                    pw.println(totalPss - cachedPss);
14145                }
14146            }
14147            if (!isCompact) {
14148                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14149                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14150                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14151                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14152                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14153                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14154                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14155            }
14156            if (!brief) {
14157                if (memInfo.getZramTotalSizeKb() != 0) {
14158                    if (!isCompact) {
14159                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14160                                pw.print(" kB physical used for ");
14161                                pw.print(memInfo.getSwapTotalSizeKb()
14162                                        - memInfo.getSwapFreeSizeKb());
14163                                pw.print(" kB in swap (");
14164                                pw.print(memInfo.getSwapTotalSizeKb());
14165                                pw.println(" kB total swap)");
14166                    } else {
14167                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14168                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14169                                pw.println(memInfo.getSwapFreeSizeKb());
14170                    }
14171                }
14172                final long[] ksm = getKsmInfo();
14173                if (!isCompact) {
14174                    if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14175                            || ksm[KSM_VOLATILE] != 0) {
14176                        pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14177                                pw.print(" kB saved from shared ");
14178                                pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14179                        pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14180                                pw.print(" kB unshared; ");
14181                                pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14182                    }
14183                    pw.print("   Tuning: ");
14184                    pw.print(ActivityManager.staticGetMemoryClass());
14185                    pw.print(" (large ");
14186                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14187                    pw.print("), oom ");
14188                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14189                    pw.print(" kB");
14190                    pw.print(", restore limit ");
14191                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14192                    pw.print(" kB");
14193                    if (ActivityManager.isLowRamDeviceStatic()) {
14194                        pw.print(" (low-ram)");
14195                    }
14196                    if (ActivityManager.isHighEndGfx()) {
14197                        pw.print(" (high-end-gfx)");
14198                    }
14199                    pw.println();
14200                } else {
14201                    pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14202                    pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14203                    pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14204                    pw.print("tuning,");
14205                    pw.print(ActivityManager.staticGetMemoryClass());
14206                    pw.print(',');
14207                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14208                    pw.print(',');
14209                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14210                    if (ActivityManager.isLowRamDeviceStatic()) {
14211                        pw.print(",low-ram");
14212                    }
14213                    if (ActivityManager.isHighEndGfx()) {
14214                        pw.print(",high-end-gfx");
14215                    }
14216                    pw.println();
14217                }
14218            }
14219        }
14220    }
14221
14222    private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14223            String name) {
14224        sb.append("  ");
14225        sb.append(ProcessList.makeOomAdjString(oomAdj));
14226        sb.append(' ');
14227        sb.append(ProcessList.makeProcStateString(procState));
14228        sb.append(' ');
14229        ProcessList.appendRamKb(sb, pss);
14230        sb.append(" kB: ");
14231        sb.append(name);
14232    }
14233
14234    private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14235        appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.name);
14236        sb.append(" (");
14237        sb.append(mi.pid);
14238        sb.append(") ");
14239        sb.append(mi.adjType);
14240        sb.append('\n');
14241        if (mi.adjReason != null) {
14242            sb.append("                      ");
14243            sb.append(mi.adjReason);
14244            sb.append('\n');
14245        }
14246    }
14247
14248    void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14249        final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14250        for (int i=0, N=memInfos.size(); i<N; i++) {
14251            ProcessMemInfo mi = memInfos.get(i);
14252            infoMap.put(mi.pid, mi);
14253        }
14254        updateCpuStatsNow();
14255        synchronized (mProcessCpuTracker) {
14256            final int N = mProcessCpuTracker.countStats();
14257            for (int i=0; i<N; i++) {
14258                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14259                if (st.vsize > 0) {
14260                    long pss = Debug.getPss(st.pid, null);
14261                    if (pss > 0) {
14262                        if (infoMap.indexOfKey(st.pid) < 0) {
14263                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14264                                    ProcessList.NATIVE_ADJ, -1, "native", null);
14265                            mi.pss = pss;
14266                            memInfos.add(mi);
14267                        }
14268                    }
14269                }
14270            }
14271        }
14272
14273        long totalPss = 0;
14274        for (int i=0, N=memInfos.size(); i<N; i++) {
14275            ProcessMemInfo mi = memInfos.get(i);
14276            if (mi.pss == 0) {
14277                mi.pss = Debug.getPss(mi.pid, null);
14278            }
14279            totalPss += mi.pss;
14280        }
14281        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14282            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14283                if (lhs.oomAdj != rhs.oomAdj) {
14284                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14285                }
14286                if (lhs.pss != rhs.pss) {
14287                    return lhs.pss < rhs.pss ? 1 : -1;
14288                }
14289                return 0;
14290            }
14291        });
14292
14293        StringBuilder tag = new StringBuilder(128);
14294        StringBuilder stack = new StringBuilder(128);
14295        tag.append("Low on memory -- ");
14296        appendMemBucket(tag, totalPss, "total", false);
14297        appendMemBucket(stack, totalPss, "total", true);
14298
14299        StringBuilder fullNativeBuilder = new StringBuilder(1024);
14300        StringBuilder shortNativeBuilder = new StringBuilder(1024);
14301        StringBuilder fullJavaBuilder = new StringBuilder(1024);
14302
14303        boolean firstLine = true;
14304        int lastOomAdj = Integer.MIN_VALUE;
14305        long extraNativeRam = 0;
14306        long cachedPss = 0;
14307        for (int i=0, N=memInfos.size(); i<N; i++) {
14308            ProcessMemInfo mi = memInfos.get(i);
14309
14310            if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14311                cachedPss += mi.pss;
14312            }
14313
14314            if (mi.oomAdj != ProcessList.NATIVE_ADJ
14315                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
14316                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
14317                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14318                if (lastOomAdj != mi.oomAdj) {
14319                    lastOomAdj = mi.oomAdj;
14320                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14321                        tag.append(" / ");
14322                    }
14323                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14324                        if (firstLine) {
14325                            stack.append(":");
14326                            firstLine = false;
14327                        }
14328                        stack.append("\n\t at ");
14329                    } else {
14330                        stack.append("$");
14331                    }
14332                } else {
14333                    tag.append(" ");
14334                    stack.append("$");
14335                }
14336                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14337                    appendMemBucket(tag, mi.pss, mi.name, false);
14338                }
14339                appendMemBucket(stack, mi.pss, mi.name, true);
14340                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14341                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14342                    stack.append("(");
14343                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14344                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14345                            stack.append(DUMP_MEM_OOM_LABEL[k]);
14346                            stack.append(":");
14347                            stack.append(DUMP_MEM_OOM_ADJ[k]);
14348                        }
14349                    }
14350                    stack.append(")");
14351                }
14352            }
14353
14354            appendMemInfo(fullNativeBuilder, mi);
14355            if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14356                // The short form only has native processes that are >= 1MB.
14357                if (mi.pss >= 1000) {
14358                    appendMemInfo(shortNativeBuilder, mi);
14359                } else {
14360                    extraNativeRam += mi.pss;
14361                }
14362            } else {
14363                // Short form has all other details, but if we have collected RAM
14364                // from smaller native processes let's dump a summary of that.
14365                if (extraNativeRam > 0) {
14366                    appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14367                            -1, extraNativeRam, "(Other native)");
14368                    shortNativeBuilder.append('\n');
14369                    extraNativeRam = 0;
14370                }
14371                appendMemInfo(fullJavaBuilder, mi);
14372            }
14373        }
14374
14375        fullJavaBuilder.append("           ");
14376        ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14377        fullJavaBuilder.append(" kB: TOTAL\n");
14378
14379        MemInfoReader memInfo = new MemInfoReader();
14380        memInfo.readMemInfo();
14381        final long[] infos = memInfo.getRawInfo();
14382
14383        StringBuilder memInfoBuilder = new StringBuilder(1024);
14384        Debug.getMemInfo(infos);
14385        memInfoBuilder.append("  MemInfo: ");
14386        memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14387        memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14388        memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14389        memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14390        memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14391        memInfoBuilder.append("           ");
14392        memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14393        memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14394        memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14395        memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14396        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14397            memInfoBuilder.append("  ZRAM: ");
14398            memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14399            memInfoBuilder.append(" kB RAM, ");
14400            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14401            memInfoBuilder.append(" kB swap total, ");
14402            memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14403            memInfoBuilder.append(" kB swap free\n");
14404        }
14405        final long[] ksm = getKsmInfo();
14406        if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14407                || ksm[KSM_VOLATILE] != 0) {
14408            memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14409            memInfoBuilder.append(" kB saved from shared ");
14410            memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14411            memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14412            memInfoBuilder.append(" kB unshared; ");
14413            memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14414        }
14415        memInfoBuilder.append("  Free RAM: ");
14416        memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14417                + memInfo.getFreeSizeKb());
14418        memInfoBuilder.append(" kB\n");
14419        memInfoBuilder.append("  Used RAM: ");
14420        memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14421        memInfoBuilder.append(" kB\n");
14422        memInfoBuilder.append("  Lost RAM: ");
14423        memInfoBuilder.append(memInfo.getTotalSizeKb()
14424                - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14425                - memInfo.getKernelUsedSizeKb());
14426        memInfoBuilder.append(" kB\n");
14427        Slog.i(TAG, "Low on memory:");
14428        Slog.i(TAG, shortNativeBuilder.toString());
14429        Slog.i(TAG, fullJavaBuilder.toString());
14430        Slog.i(TAG, memInfoBuilder.toString());
14431
14432        StringBuilder dropBuilder = new StringBuilder(1024);
14433        /*
14434        StringWriter oomSw = new StringWriter();
14435        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14436        StringWriter catSw = new StringWriter();
14437        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14438        String[] emptyArgs = new String[] { };
14439        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14440        oomPw.flush();
14441        String oomString = oomSw.toString();
14442        */
14443        dropBuilder.append("Low on memory:");
14444        dropBuilder.append(stack);
14445        dropBuilder.append('\n');
14446        dropBuilder.append(fullNativeBuilder);
14447        dropBuilder.append(fullJavaBuilder);
14448        dropBuilder.append('\n');
14449        dropBuilder.append(memInfoBuilder);
14450        dropBuilder.append('\n');
14451        /*
14452        dropBuilder.append(oomString);
14453        dropBuilder.append('\n');
14454        */
14455        StringWriter catSw = new StringWriter();
14456        synchronized (ActivityManagerService.this) {
14457            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14458            String[] emptyArgs = new String[] { };
14459            catPw.println();
14460            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14461            catPw.println();
14462            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14463                    false, false, null);
14464            catPw.println();
14465            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14466            catPw.flush();
14467        }
14468        dropBuilder.append(catSw.toString());
14469        addErrorToDropBox("lowmem", null, "system_server", null,
14470                null, tag.toString(), dropBuilder.toString(), null, null);
14471        //Slog.i(TAG, "Sent to dropbox:");
14472        //Slog.i(TAG, dropBuilder.toString());
14473        synchronized (ActivityManagerService.this) {
14474            long now = SystemClock.uptimeMillis();
14475            if (mLastMemUsageReportTime < now) {
14476                mLastMemUsageReportTime = now;
14477            }
14478        }
14479    }
14480
14481    /**
14482     * Searches array of arguments for the specified string
14483     * @param args array of argument strings
14484     * @param value value to search for
14485     * @return true if the value is contained in the array
14486     */
14487    private static boolean scanArgs(String[] args, String value) {
14488        if (args != null) {
14489            for (String arg : args) {
14490                if (value.equals(arg)) {
14491                    return true;
14492                }
14493            }
14494        }
14495        return false;
14496    }
14497
14498    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14499            ContentProviderRecord cpr, boolean always) {
14500        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14501
14502        if (!inLaunching || always) {
14503            synchronized (cpr) {
14504                cpr.launchingApp = null;
14505                cpr.notifyAll();
14506            }
14507            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14508            String names[] = cpr.info.authority.split(";");
14509            for (int j = 0; j < names.length; j++) {
14510                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14511            }
14512        }
14513
14514        for (int i=0; i<cpr.connections.size(); i++) {
14515            ContentProviderConnection conn = cpr.connections.get(i);
14516            if (conn.waiting) {
14517                // If this connection is waiting for the provider, then we don't
14518                // need to mess with its process unless we are always removing
14519                // or for some reason the provider is not currently launching.
14520                if (inLaunching && !always) {
14521                    continue;
14522                }
14523            }
14524            ProcessRecord capp = conn.client;
14525            conn.dead = true;
14526            if (conn.stableCount > 0) {
14527                if (!capp.persistent && capp.thread != null
14528                        && capp.pid != 0
14529                        && capp.pid != MY_PID) {
14530                    capp.kill("depends on provider "
14531                            + cpr.name.flattenToShortString()
14532                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14533                }
14534            } else if (capp.thread != null && conn.provider.provider != null) {
14535                try {
14536                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14537                } catch (RemoteException e) {
14538                }
14539                // In the protocol here, we don't expect the client to correctly
14540                // clean up this connection, we'll just remove it.
14541                cpr.connections.remove(i);
14542                conn.client.conProviders.remove(conn);
14543            }
14544        }
14545
14546        if (inLaunching && always) {
14547            mLaunchingProviders.remove(cpr);
14548        }
14549        return inLaunching;
14550    }
14551
14552    /**
14553     * Main code for cleaning up a process when it has gone away.  This is
14554     * called both as a result of the process dying, or directly when stopping
14555     * a process when running in single process mode.
14556     *
14557     * @return Returns true if the given process has been restarted, so the
14558     * app that was passed in must remain on the process lists.
14559     */
14560    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14561            boolean restarting, boolean allowRestart, int index) {
14562        if (index >= 0) {
14563            removeLruProcessLocked(app);
14564            ProcessList.remove(app.pid);
14565        }
14566
14567        mProcessesToGc.remove(app);
14568        mPendingPssProcesses.remove(app);
14569
14570        // Dismiss any open dialogs.
14571        if (app.crashDialog != null && !app.forceCrashReport) {
14572            app.crashDialog.dismiss();
14573            app.crashDialog = null;
14574        }
14575        if (app.anrDialog != null) {
14576            app.anrDialog.dismiss();
14577            app.anrDialog = null;
14578        }
14579        if (app.waitDialog != null) {
14580            app.waitDialog.dismiss();
14581            app.waitDialog = null;
14582        }
14583
14584        app.crashing = false;
14585        app.notResponding = false;
14586
14587        app.resetPackageList(mProcessStats);
14588        app.unlinkDeathRecipient();
14589        app.makeInactive(mProcessStats);
14590        app.waitingToKill = null;
14591        app.forcingToForeground = null;
14592        updateProcessForegroundLocked(app, false, false);
14593        app.foregroundActivities = false;
14594        app.hasShownUi = false;
14595        app.treatLikeActivity = false;
14596        app.hasAboveClient = false;
14597        app.hasClientActivities = false;
14598
14599        mServices.killServicesLocked(app, allowRestart);
14600
14601        boolean restart = false;
14602
14603        // Remove published content providers.
14604        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14605            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14606            final boolean always = app.bad || !allowRestart;
14607            if (removeDyingProviderLocked(app, cpr, always) || always) {
14608                // We left the provider in the launching list, need to
14609                // restart it.
14610                restart = true;
14611            }
14612
14613            cpr.provider = null;
14614            cpr.proc = null;
14615        }
14616        app.pubProviders.clear();
14617
14618        // Take care of any launching providers waiting for this process.
14619        if (checkAppInLaunchingProvidersLocked(app, false)) {
14620            restart = true;
14621        }
14622
14623        // Unregister from connected content providers.
14624        if (!app.conProviders.isEmpty()) {
14625            for (int i=0; i<app.conProviders.size(); i++) {
14626                ContentProviderConnection conn = app.conProviders.get(i);
14627                conn.provider.connections.remove(conn);
14628            }
14629            app.conProviders.clear();
14630        }
14631
14632        // At this point there may be remaining entries in mLaunchingProviders
14633        // where we were the only one waiting, so they are no longer of use.
14634        // Look for these and clean up if found.
14635        // XXX Commented out for now.  Trying to figure out a way to reproduce
14636        // the actual situation to identify what is actually going on.
14637        if (false) {
14638            for (int i=0; i<mLaunchingProviders.size(); i++) {
14639                ContentProviderRecord cpr = (ContentProviderRecord)
14640                        mLaunchingProviders.get(i);
14641                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14642                    synchronized (cpr) {
14643                        cpr.launchingApp = null;
14644                        cpr.notifyAll();
14645                    }
14646                }
14647            }
14648        }
14649
14650        skipCurrentReceiverLocked(app);
14651
14652        // Unregister any receivers.
14653        for (int i=app.receivers.size()-1; i>=0; i--) {
14654            removeReceiverLocked(app.receivers.valueAt(i));
14655        }
14656        app.receivers.clear();
14657
14658        // If the app is undergoing backup, tell the backup manager about it
14659        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14660            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14661                    + mBackupTarget.appInfo + " died during backup");
14662            try {
14663                IBackupManager bm = IBackupManager.Stub.asInterface(
14664                        ServiceManager.getService(Context.BACKUP_SERVICE));
14665                bm.agentDisconnected(app.info.packageName);
14666            } catch (RemoteException e) {
14667                // can't happen; backup manager is local
14668            }
14669        }
14670
14671        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14672            ProcessChangeItem item = mPendingProcessChanges.get(i);
14673            if (item.pid == app.pid) {
14674                mPendingProcessChanges.remove(i);
14675                mAvailProcessChanges.add(item);
14676            }
14677        }
14678        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14679
14680        // If the caller is restarting this app, then leave it in its
14681        // current lists and let the caller take care of it.
14682        if (restarting) {
14683            return false;
14684        }
14685
14686        if (!app.persistent || app.isolated) {
14687            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14688                    "Removing non-persistent process during cleanup: " + app);
14689            mProcessNames.remove(app.processName, app.uid);
14690            mIsolatedProcesses.remove(app.uid);
14691            if (mHeavyWeightProcess == app) {
14692                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14693                        mHeavyWeightProcess.userId, 0));
14694                mHeavyWeightProcess = null;
14695            }
14696        } else if (!app.removed) {
14697            // This app is persistent, so we need to keep its record around.
14698            // If it is not already on the pending app list, add it there
14699            // and start a new process for it.
14700            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14701                mPersistentStartingProcesses.add(app);
14702                restart = true;
14703            }
14704        }
14705        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14706                "Clean-up removing on hold: " + app);
14707        mProcessesOnHold.remove(app);
14708
14709        if (app == mHomeProcess) {
14710            mHomeProcess = null;
14711        }
14712        if (app == mPreviousProcess) {
14713            mPreviousProcess = null;
14714        }
14715
14716        if (restart && !app.isolated) {
14717            // We have components that still need to be running in the
14718            // process, so re-launch it.
14719            if (index < 0) {
14720                ProcessList.remove(app.pid);
14721            }
14722            mProcessNames.put(app.processName, app.uid, app);
14723            startProcessLocked(app, "restart", app.processName);
14724            return true;
14725        } else if (app.pid > 0 && app.pid != MY_PID) {
14726            // Goodbye!
14727            boolean removed;
14728            synchronized (mPidsSelfLocked) {
14729                mPidsSelfLocked.remove(app.pid);
14730                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14731            }
14732            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14733            if (app.isolated) {
14734                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14735            }
14736            app.setPid(0);
14737        }
14738        return false;
14739    }
14740
14741    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14742        // Look through the content providers we are waiting to have launched,
14743        // and if any run in this process then either schedule a restart of
14744        // the process or kill the client waiting for it if this process has
14745        // gone bad.
14746        int NL = mLaunchingProviders.size();
14747        boolean restart = false;
14748        for (int i=0; i<NL; i++) {
14749            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14750            if (cpr.launchingApp == app) {
14751                if (!alwaysBad && !app.bad) {
14752                    restart = true;
14753                } else {
14754                    removeDyingProviderLocked(app, cpr, true);
14755                    // cpr should have been removed from mLaunchingProviders
14756                    NL = mLaunchingProviders.size();
14757                    i--;
14758                }
14759            }
14760        }
14761        return restart;
14762    }
14763
14764    // =========================================================
14765    // SERVICES
14766    // =========================================================
14767
14768    @Override
14769    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14770            int flags) {
14771        enforceNotIsolatedCaller("getServices");
14772        synchronized (this) {
14773            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14774        }
14775    }
14776
14777    @Override
14778    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14779        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14780        synchronized (this) {
14781            return mServices.getRunningServiceControlPanelLocked(name);
14782        }
14783    }
14784
14785    @Override
14786    public ComponentName startService(IApplicationThread caller, Intent service,
14787            String resolvedType, int userId) {
14788        enforceNotIsolatedCaller("startService");
14789        // Refuse possible leaked file descriptors
14790        if (service != null && service.hasFileDescriptors() == true) {
14791            throw new IllegalArgumentException("File descriptors passed in Intent");
14792        }
14793
14794        if (DEBUG_SERVICE)
14795            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14796        synchronized(this) {
14797            final int callingPid = Binder.getCallingPid();
14798            final int callingUid = Binder.getCallingUid();
14799            final long origId = Binder.clearCallingIdentity();
14800            ComponentName res = mServices.startServiceLocked(caller, service,
14801                    resolvedType, callingPid, callingUid, userId);
14802            Binder.restoreCallingIdentity(origId);
14803            return res;
14804        }
14805    }
14806
14807    ComponentName startServiceInPackage(int uid,
14808            Intent service, String resolvedType, int userId) {
14809        synchronized(this) {
14810            if (DEBUG_SERVICE)
14811                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14812            final long origId = Binder.clearCallingIdentity();
14813            ComponentName res = mServices.startServiceLocked(null, service,
14814                    resolvedType, -1, uid, userId);
14815            Binder.restoreCallingIdentity(origId);
14816            return res;
14817        }
14818    }
14819
14820    @Override
14821    public int stopService(IApplicationThread caller, Intent service,
14822            String resolvedType, int userId) {
14823        enforceNotIsolatedCaller("stopService");
14824        // Refuse possible leaked file descriptors
14825        if (service != null && service.hasFileDescriptors() == true) {
14826            throw new IllegalArgumentException("File descriptors passed in Intent");
14827        }
14828
14829        synchronized(this) {
14830            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14831        }
14832    }
14833
14834    @Override
14835    public IBinder peekService(Intent service, String resolvedType) {
14836        enforceNotIsolatedCaller("peekService");
14837        // Refuse possible leaked file descriptors
14838        if (service != null && service.hasFileDescriptors() == true) {
14839            throw new IllegalArgumentException("File descriptors passed in Intent");
14840        }
14841        synchronized(this) {
14842            return mServices.peekServiceLocked(service, resolvedType);
14843        }
14844    }
14845
14846    @Override
14847    public boolean stopServiceToken(ComponentName className, IBinder token,
14848            int startId) {
14849        synchronized(this) {
14850            return mServices.stopServiceTokenLocked(className, token, startId);
14851        }
14852    }
14853
14854    @Override
14855    public void setServiceForeground(ComponentName className, IBinder token,
14856            int id, Notification notification, boolean removeNotification) {
14857        synchronized(this) {
14858            mServices.setServiceForegroundLocked(className, token, id, notification,
14859                    removeNotification);
14860        }
14861    }
14862
14863    @Override
14864    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14865            boolean requireFull, String name, String callerPackage) {
14866        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14867                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14868    }
14869
14870    int unsafeConvertIncomingUser(int userId) {
14871        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14872                ? mCurrentUserId : userId;
14873    }
14874
14875    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14876            int allowMode, String name, String callerPackage) {
14877        final int callingUserId = UserHandle.getUserId(callingUid);
14878        if (callingUserId == userId) {
14879            return userId;
14880        }
14881
14882        // Note that we may be accessing mCurrentUserId outside of a lock...
14883        // shouldn't be a big deal, if this is being called outside
14884        // of a locked context there is intrinsically a race with
14885        // the value the caller will receive and someone else changing it.
14886        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14887        // we will switch to the calling user if access to the current user fails.
14888        int targetUserId = unsafeConvertIncomingUser(userId);
14889
14890        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14891            final boolean allow;
14892            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14893                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14894                // If the caller has this permission, they always pass go.  And collect $200.
14895                allow = true;
14896            } else if (allowMode == ALLOW_FULL_ONLY) {
14897                // We require full access, sucks to be you.
14898                allow = false;
14899            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14900                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14901                // If the caller does not have either permission, they are always doomed.
14902                allow = false;
14903            } else if (allowMode == ALLOW_NON_FULL) {
14904                // We are blanket allowing non-full access, you lucky caller!
14905                allow = true;
14906            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14907                // We may or may not allow this depending on whether the two users are
14908                // in the same profile.
14909                synchronized (mUserProfileGroupIdsSelfLocked) {
14910                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14911                            UserInfo.NO_PROFILE_GROUP_ID);
14912                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14913                            UserInfo.NO_PROFILE_GROUP_ID);
14914                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14915                            && callingProfile == targetProfile;
14916                }
14917            } else {
14918                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14919            }
14920            if (!allow) {
14921                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14922                    // In this case, they would like to just execute as their
14923                    // owner user instead of failing.
14924                    targetUserId = callingUserId;
14925                } else {
14926                    StringBuilder builder = new StringBuilder(128);
14927                    builder.append("Permission Denial: ");
14928                    builder.append(name);
14929                    if (callerPackage != null) {
14930                        builder.append(" from ");
14931                        builder.append(callerPackage);
14932                    }
14933                    builder.append(" asks to run as user ");
14934                    builder.append(userId);
14935                    builder.append(" but is calling from user ");
14936                    builder.append(UserHandle.getUserId(callingUid));
14937                    builder.append("; this requires ");
14938                    builder.append(INTERACT_ACROSS_USERS_FULL);
14939                    if (allowMode != ALLOW_FULL_ONLY) {
14940                        builder.append(" or ");
14941                        builder.append(INTERACT_ACROSS_USERS);
14942                    }
14943                    String msg = builder.toString();
14944                    Slog.w(TAG, msg);
14945                    throw new SecurityException(msg);
14946                }
14947            }
14948        }
14949        if (!allowAll && targetUserId < 0) {
14950            throw new IllegalArgumentException(
14951                    "Call does not support special user #" + targetUserId);
14952        }
14953        // Check shell permission
14954        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14955            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14956                    targetUserId)) {
14957                throw new SecurityException("Shell does not have permission to access user "
14958                        + targetUserId + "\n " + Debug.getCallers(3));
14959            }
14960        }
14961        return targetUserId;
14962    }
14963
14964    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14965            String className, int flags) {
14966        boolean result = false;
14967        // For apps that don't have pre-defined UIDs, check for permission
14968        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14969            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14970                if (ActivityManager.checkUidPermission(
14971                        INTERACT_ACROSS_USERS,
14972                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14973                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14974                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14975                            + " requests FLAG_SINGLE_USER, but app does not hold "
14976                            + INTERACT_ACROSS_USERS;
14977                    Slog.w(TAG, msg);
14978                    throw new SecurityException(msg);
14979                }
14980                // Permission passed
14981                result = true;
14982            }
14983        } else if ("system".equals(componentProcessName)) {
14984            result = true;
14985        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14986            // Phone app and persistent apps are allowed to export singleuser providers.
14987            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14988                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14989        }
14990        if (DEBUG_MU) {
14991            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14992                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14993        }
14994        return result;
14995    }
14996
14997    /**
14998     * Checks to see if the caller is in the same app as the singleton
14999     * component, or the component is in a special app. It allows special apps
15000     * to export singleton components but prevents exporting singleton
15001     * components for regular apps.
15002     */
15003    boolean isValidSingletonCall(int callingUid, int componentUid) {
15004        int componentAppId = UserHandle.getAppId(componentUid);
15005        return UserHandle.isSameApp(callingUid, componentUid)
15006                || componentAppId == Process.SYSTEM_UID
15007                || componentAppId == Process.PHONE_UID
15008                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15009                        == PackageManager.PERMISSION_GRANTED;
15010    }
15011
15012    public int bindService(IApplicationThread caller, IBinder token,
15013            Intent service, String resolvedType,
15014            IServiceConnection connection, int flags, int userId) {
15015        enforceNotIsolatedCaller("bindService");
15016
15017        // Refuse possible leaked file descriptors
15018        if (service != null && service.hasFileDescriptors() == true) {
15019            throw new IllegalArgumentException("File descriptors passed in Intent");
15020        }
15021
15022        synchronized(this) {
15023            return mServices.bindServiceLocked(caller, token, service, resolvedType,
15024                    connection, flags, userId);
15025        }
15026    }
15027
15028    public boolean unbindService(IServiceConnection connection) {
15029        synchronized (this) {
15030            return mServices.unbindServiceLocked(connection);
15031        }
15032    }
15033
15034    public void publishService(IBinder token, Intent intent, IBinder service) {
15035        // Refuse possible leaked file descriptors
15036        if (intent != null && intent.hasFileDescriptors() == true) {
15037            throw new IllegalArgumentException("File descriptors passed in Intent");
15038        }
15039
15040        synchronized(this) {
15041            if (!(token instanceof ServiceRecord)) {
15042                throw new IllegalArgumentException("Invalid service token");
15043            }
15044            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15045        }
15046    }
15047
15048    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15049        // Refuse possible leaked file descriptors
15050        if (intent != null && intent.hasFileDescriptors() == true) {
15051            throw new IllegalArgumentException("File descriptors passed in Intent");
15052        }
15053
15054        synchronized(this) {
15055            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15056        }
15057    }
15058
15059    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15060        synchronized(this) {
15061            if (!(token instanceof ServiceRecord)) {
15062                throw new IllegalArgumentException("Invalid service token");
15063            }
15064            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15065        }
15066    }
15067
15068    // =========================================================
15069    // BACKUP AND RESTORE
15070    // =========================================================
15071
15072    // Cause the target app to be launched if necessary and its backup agent
15073    // instantiated.  The backup agent will invoke backupAgentCreated() on the
15074    // activity manager to announce its creation.
15075    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15076        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15077        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15078
15079        synchronized(this) {
15080            // !!! TODO: currently no check here that we're already bound
15081            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15082            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15083            synchronized (stats) {
15084                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15085            }
15086
15087            // Backup agent is now in use, its package can't be stopped.
15088            try {
15089                AppGlobals.getPackageManager().setPackageStoppedState(
15090                        app.packageName, false, UserHandle.getUserId(app.uid));
15091            } catch (RemoteException e) {
15092            } catch (IllegalArgumentException e) {
15093                Slog.w(TAG, "Failed trying to unstop package "
15094                        + app.packageName + ": " + e);
15095            }
15096
15097            BackupRecord r = new BackupRecord(ss, app, backupMode);
15098            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15099                    ? new ComponentName(app.packageName, app.backupAgentName)
15100                    : new ComponentName("android", "FullBackupAgent");
15101            // startProcessLocked() returns existing proc's record if it's already running
15102            ProcessRecord proc = startProcessLocked(app.processName, app,
15103                    false, 0, "backup", hostingName, false, false, false);
15104            if (proc == null) {
15105                Slog.e(TAG, "Unable to start backup agent process " + r);
15106                return false;
15107            }
15108
15109            r.app = proc;
15110            mBackupTarget = r;
15111            mBackupAppName = app.packageName;
15112
15113            // Try not to kill the process during backup
15114            updateOomAdjLocked(proc);
15115
15116            // If the process is already attached, schedule the creation of the backup agent now.
15117            // If it is not yet live, this will be done when it attaches to the framework.
15118            if (proc.thread != null) {
15119                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15120                try {
15121                    proc.thread.scheduleCreateBackupAgent(app,
15122                            compatibilityInfoForPackageLocked(app), backupMode);
15123                } catch (RemoteException e) {
15124                    // Will time out on the backup manager side
15125                }
15126            } else {
15127                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15128            }
15129            // Invariants: at this point, the target app process exists and the application
15130            // is either already running or in the process of coming up.  mBackupTarget and
15131            // mBackupAppName describe the app, so that when it binds back to the AM we
15132            // know that it's scheduled for a backup-agent operation.
15133        }
15134
15135        return true;
15136    }
15137
15138    @Override
15139    public void clearPendingBackup() {
15140        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15141        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15142
15143        synchronized (this) {
15144            mBackupTarget = null;
15145            mBackupAppName = null;
15146        }
15147    }
15148
15149    // A backup agent has just come up
15150    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15151        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15152                + " = " + agent);
15153
15154        synchronized(this) {
15155            if (!agentPackageName.equals(mBackupAppName)) {
15156                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15157                return;
15158            }
15159        }
15160
15161        long oldIdent = Binder.clearCallingIdentity();
15162        try {
15163            IBackupManager bm = IBackupManager.Stub.asInterface(
15164                    ServiceManager.getService(Context.BACKUP_SERVICE));
15165            bm.agentConnected(agentPackageName, agent);
15166        } catch (RemoteException e) {
15167            // can't happen; the backup manager service is local
15168        } catch (Exception e) {
15169            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15170            e.printStackTrace();
15171        } finally {
15172            Binder.restoreCallingIdentity(oldIdent);
15173        }
15174    }
15175
15176    // done with this agent
15177    public void unbindBackupAgent(ApplicationInfo appInfo) {
15178        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15179        if (appInfo == null) {
15180            Slog.w(TAG, "unbind backup agent for null app");
15181            return;
15182        }
15183
15184        synchronized(this) {
15185            try {
15186                if (mBackupAppName == null) {
15187                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15188                    return;
15189                }
15190
15191                if (!mBackupAppName.equals(appInfo.packageName)) {
15192                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15193                    return;
15194                }
15195
15196                // Not backing this app up any more; reset its OOM adjustment
15197                final ProcessRecord proc = mBackupTarget.app;
15198                updateOomAdjLocked(proc);
15199
15200                // If the app crashed during backup, 'thread' will be null here
15201                if (proc.thread != null) {
15202                    try {
15203                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15204                                compatibilityInfoForPackageLocked(appInfo));
15205                    } catch (Exception e) {
15206                        Slog.e(TAG, "Exception when unbinding backup agent:");
15207                        e.printStackTrace();
15208                    }
15209                }
15210            } finally {
15211                mBackupTarget = null;
15212                mBackupAppName = null;
15213            }
15214        }
15215    }
15216    // =========================================================
15217    // BROADCASTS
15218    // =========================================================
15219
15220    private final List getStickiesLocked(String action, IntentFilter filter,
15221            List cur, int userId) {
15222        final ContentResolver resolver = mContext.getContentResolver();
15223        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15224        if (stickies == null) {
15225            return cur;
15226        }
15227        final ArrayList<Intent> list = stickies.get(action);
15228        if (list == null) {
15229            return cur;
15230        }
15231        int N = list.size();
15232        for (int i=0; i<N; i++) {
15233            Intent intent = list.get(i);
15234            if (filter.match(resolver, intent, true, TAG) >= 0) {
15235                if (cur == null) {
15236                    cur = new ArrayList<Intent>();
15237                }
15238                cur.add(intent);
15239            }
15240        }
15241        return cur;
15242    }
15243
15244    boolean isPendingBroadcastProcessLocked(int pid) {
15245        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15246                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15247    }
15248
15249    void skipPendingBroadcastLocked(int pid) {
15250            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15251            for (BroadcastQueue queue : mBroadcastQueues) {
15252                queue.skipPendingBroadcastLocked(pid);
15253            }
15254    }
15255
15256    // The app just attached; send any pending broadcasts that it should receive
15257    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15258        boolean didSomething = false;
15259        for (BroadcastQueue queue : mBroadcastQueues) {
15260            didSomething |= queue.sendPendingBroadcastsLocked(app);
15261        }
15262        return didSomething;
15263    }
15264
15265    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15266            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15267        enforceNotIsolatedCaller("registerReceiver");
15268        int callingUid;
15269        int callingPid;
15270        synchronized(this) {
15271            ProcessRecord callerApp = null;
15272            if (caller != null) {
15273                callerApp = getRecordForAppLocked(caller);
15274                if (callerApp == null) {
15275                    throw new SecurityException(
15276                            "Unable to find app for caller " + caller
15277                            + " (pid=" + Binder.getCallingPid()
15278                            + ") when registering receiver " + receiver);
15279                }
15280                if (callerApp.info.uid != Process.SYSTEM_UID &&
15281                        !callerApp.pkgList.containsKey(callerPackage) &&
15282                        !"android".equals(callerPackage)) {
15283                    throw new SecurityException("Given caller package " + callerPackage
15284                            + " is not running in process " + callerApp);
15285                }
15286                callingUid = callerApp.info.uid;
15287                callingPid = callerApp.pid;
15288            } else {
15289                callerPackage = null;
15290                callingUid = Binder.getCallingUid();
15291                callingPid = Binder.getCallingPid();
15292            }
15293
15294            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15295                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15296
15297            List allSticky = null;
15298
15299            // Look for any matching sticky broadcasts...
15300            Iterator actions = filter.actionsIterator();
15301            if (actions != null) {
15302                while (actions.hasNext()) {
15303                    String action = (String)actions.next();
15304                    allSticky = getStickiesLocked(action, filter, allSticky,
15305                            UserHandle.USER_ALL);
15306                    allSticky = getStickiesLocked(action, filter, allSticky,
15307                            UserHandle.getUserId(callingUid));
15308                }
15309            } else {
15310                allSticky = getStickiesLocked(null, filter, allSticky,
15311                        UserHandle.USER_ALL);
15312                allSticky = getStickiesLocked(null, filter, allSticky,
15313                        UserHandle.getUserId(callingUid));
15314            }
15315
15316            // The first sticky in the list is returned directly back to
15317            // the client.
15318            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15319
15320            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15321                    + ": " + sticky);
15322
15323            if (receiver == null) {
15324                return sticky;
15325            }
15326
15327            ReceiverList rl
15328                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15329            if (rl == null) {
15330                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15331                        userId, receiver);
15332                if (rl.app != null) {
15333                    rl.app.receivers.add(rl);
15334                } else {
15335                    try {
15336                        receiver.asBinder().linkToDeath(rl, 0);
15337                    } catch (RemoteException e) {
15338                        return sticky;
15339                    }
15340                    rl.linkedToDeath = true;
15341                }
15342                mRegisteredReceivers.put(receiver.asBinder(), rl);
15343            } else if (rl.uid != callingUid) {
15344                throw new IllegalArgumentException(
15345                        "Receiver requested to register for uid " + callingUid
15346                        + " was previously registered for uid " + rl.uid);
15347            } else if (rl.pid != callingPid) {
15348                throw new IllegalArgumentException(
15349                        "Receiver requested to register for pid " + callingPid
15350                        + " was previously registered for pid " + rl.pid);
15351            } else if (rl.userId != userId) {
15352                throw new IllegalArgumentException(
15353                        "Receiver requested to register for user " + userId
15354                        + " was previously registered for user " + rl.userId);
15355            }
15356            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15357                    permission, callingUid, userId);
15358            rl.add(bf);
15359            if (!bf.debugCheck()) {
15360                Slog.w(TAG, "==> For Dynamic broadast");
15361            }
15362            mReceiverResolver.addFilter(bf);
15363
15364            // Enqueue broadcasts for all existing stickies that match
15365            // this filter.
15366            if (allSticky != null) {
15367                ArrayList receivers = new ArrayList();
15368                receivers.add(bf);
15369
15370                int N = allSticky.size();
15371                for (int i=0; i<N; i++) {
15372                    Intent intent = (Intent)allSticky.get(i);
15373                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15374                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15375                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15376                            null, null, false, true, true, -1);
15377                    queue.enqueueParallelBroadcastLocked(r);
15378                    queue.scheduleBroadcastsLocked();
15379                }
15380            }
15381
15382            return sticky;
15383        }
15384    }
15385
15386    public void unregisterReceiver(IIntentReceiver receiver) {
15387        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15388
15389        final long origId = Binder.clearCallingIdentity();
15390        try {
15391            boolean doTrim = false;
15392
15393            synchronized(this) {
15394                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15395                if (rl != null) {
15396                    if (rl.curBroadcast != null) {
15397                        BroadcastRecord r = rl.curBroadcast;
15398                        final boolean doNext = finishReceiverLocked(
15399                                receiver.asBinder(), r.resultCode, r.resultData,
15400                                r.resultExtras, r.resultAbort);
15401                        if (doNext) {
15402                            doTrim = true;
15403                            r.queue.processNextBroadcast(false);
15404                        }
15405                    }
15406
15407                    if (rl.app != null) {
15408                        rl.app.receivers.remove(rl);
15409                    }
15410                    removeReceiverLocked(rl);
15411                    if (rl.linkedToDeath) {
15412                        rl.linkedToDeath = false;
15413                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15414                    }
15415                }
15416            }
15417
15418            // If we actually concluded any broadcasts, we might now be able
15419            // to trim the recipients' apps from our working set
15420            if (doTrim) {
15421                trimApplications();
15422                return;
15423            }
15424
15425        } finally {
15426            Binder.restoreCallingIdentity(origId);
15427        }
15428    }
15429
15430    void removeReceiverLocked(ReceiverList rl) {
15431        mRegisteredReceivers.remove(rl.receiver.asBinder());
15432        int N = rl.size();
15433        for (int i=0; i<N; i++) {
15434            mReceiverResolver.removeFilter(rl.get(i));
15435        }
15436    }
15437
15438    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15439        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15440            ProcessRecord r = mLruProcesses.get(i);
15441            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15442                try {
15443                    r.thread.dispatchPackageBroadcast(cmd, packages);
15444                } catch (RemoteException ex) {
15445                }
15446            }
15447        }
15448    }
15449
15450    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15451            int callingUid, int[] users) {
15452        List<ResolveInfo> receivers = null;
15453        try {
15454            HashSet<ComponentName> singleUserReceivers = null;
15455            boolean scannedFirstReceivers = false;
15456            for (int user : users) {
15457                // Skip users that have Shell restrictions
15458                if (callingUid == Process.SHELL_UID
15459                        && getUserManagerLocked().hasUserRestriction(
15460                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15461                    continue;
15462                }
15463                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15464                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15465                if (user != 0 && newReceivers != null) {
15466                    // If this is not the primary user, we need to check for
15467                    // any receivers that should be filtered out.
15468                    for (int i=0; i<newReceivers.size(); i++) {
15469                        ResolveInfo ri = newReceivers.get(i);
15470                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15471                            newReceivers.remove(i);
15472                            i--;
15473                        }
15474                    }
15475                }
15476                if (newReceivers != null && newReceivers.size() == 0) {
15477                    newReceivers = null;
15478                }
15479                if (receivers == null) {
15480                    receivers = newReceivers;
15481                } else if (newReceivers != null) {
15482                    // We need to concatenate the additional receivers
15483                    // found with what we have do far.  This would be easy,
15484                    // but we also need to de-dup any receivers that are
15485                    // singleUser.
15486                    if (!scannedFirstReceivers) {
15487                        // Collect any single user receivers we had already retrieved.
15488                        scannedFirstReceivers = true;
15489                        for (int i=0; i<receivers.size(); i++) {
15490                            ResolveInfo ri = receivers.get(i);
15491                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15492                                ComponentName cn = new ComponentName(
15493                                        ri.activityInfo.packageName, ri.activityInfo.name);
15494                                if (singleUserReceivers == null) {
15495                                    singleUserReceivers = new HashSet<ComponentName>();
15496                                }
15497                                singleUserReceivers.add(cn);
15498                            }
15499                        }
15500                    }
15501                    // Add the new results to the existing results, tracking
15502                    // and de-dupping single user receivers.
15503                    for (int i=0; i<newReceivers.size(); i++) {
15504                        ResolveInfo ri = newReceivers.get(i);
15505                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15506                            ComponentName cn = new ComponentName(
15507                                    ri.activityInfo.packageName, ri.activityInfo.name);
15508                            if (singleUserReceivers == null) {
15509                                singleUserReceivers = new HashSet<ComponentName>();
15510                            }
15511                            if (!singleUserReceivers.contains(cn)) {
15512                                singleUserReceivers.add(cn);
15513                                receivers.add(ri);
15514                            }
15515                        } else {
15516                            receivers.add(ri);
15517                        }
15518                    }
15519                }
15520            }
15521        } catch (RemoteException ex) {
15522            // pm is in same process, this will never happen.
15523        }
15524        return receivers;
15525    }
15526
15527    private final int broadcastIntentLocked(ProcessRecord callerApp,
15528            String callerPackage, Intent intent, String resolvedType,
15529            IIntentReceiver resultTo, int resultCode, String resultData,
15530            Bundle map, String requiredPermission, int appOp,
15531            boolean ordered, boolean sticky, int callingPid, int callingUid,
15532            int userId) {
15533        intent = new Intent(intent);
15534
15535        // By default broadcasts do not go to stopped apps.
15536        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15537
15538        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15539            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15540            + " ordered=" + ordered + " userid=" + userId);
15541        if ((resultTo != null) && !ordered) {
15542            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15543        }
15544
15545        userId = handleIncomingUser(callingPid, callingUid, userId,
15546                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15547
15548        // Make sure that the user who is receiving this broadcast is started.
15549        // If not, we will just skip it.
15550
15551        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15552            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15553                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15554                Slog.w(TAG, "Skipping broadcast of " + intent
15555                        + ": user " + userId + " is stopped");
15556                return ActivityManager.BROADCAST_SUCCESS;
15557            }
15558        }
15559
15560        /*
15561         * Prevent non-system code (defined here to be non-persistent
15562         * processes) from sending protected broadcasts.
15563         */
15564        int callingAppId = UserHandle.getAppId(callingUid);
15565        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15566            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15567            || callingAppId == Process.NFC_UID || callingUid == 0) {
15568            // Always okay.
15569        } else if (callerApp == null || !callerApp.persistent) {
15570            try {
15571                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15572                        intent.getAction())) {
15573                    String msg = "Permission Denial: not allowed to send broadcast "
15574                            + intent.getAction() + " from pid="
15575                            + callingPid + ", uid=" + callingUid;
15576                    Slog.w(TAG, msg);
15577                    throw new SecurityException(msg);
15578                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15579                    // Special case for compatibility: we don't want apps to send this,
15580                    // but historically it has not been protected and apps may be using it
15581                    // to poke their own app widget.  So, instead of making it protected,
15582                    // just limit it to the caller.
15583                    if (callerApp == null) {
15584                        String msg = "Permission Denial: not allowed to send broadcast "
15585                                + intent.getAction() + " from unknown caller.";
15586                        Slog.w(TAG, msg);
15587                        throw new SecurityException(msg);
15588                    } else if (intent.getComponent() != null) {
15589                        // They are good enough to send to an explicit component...  verify
15590                        // it is being sent to the calling app.
15591                        if (!intent.getComponent().getPackageName().equals(
15592                                callerApp.info.packageName)) {
15593                            String msg = "Permission Denial: not allowed to send broadcast "
15594                                    + intent.getAction() + " to "
15595                                    + intent.getComponent().getPackageName() + " from "
15596                                    + callerApp.info.packageName;
15597                            Slog.w(TAG, msg);
15598                            throw new SecurityException(msg);
15599                        }
15600                    } else {
15601                        // Limit broadcast to their own package.
15602                        intent.setPackage(callerApp.info.packageName);
15603                    }
15604                }
15605            } catch (RemoteException e) {
15606                Slog.w(TAG, "Remote exception", e);
15607                return ActivityManager.BROADCAST_SUCCESS;
15608            }
15609        }
15610
15611        // Handle special intents: if this broadcast is from the package
15612        // manager about a package being removed, we need to remove all of
15613        // its activities from the history stack.
15614        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15615                intent.getAction());
15616        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15617                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15618                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15619                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15620                || uidRemoved) {
15621            if (checkComponentPermission(
15622                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15623                    callingPid, callingUid, -1, true)
15624                    == PackageManager.PERMISSION_GRANTED) {
15625                if (uidRemoved) {
15626                    final Bundle intentExtras = intent.getExtras();
15627                    final int uid = intentExtras != null
15628                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15629                    if (uid >= 0) {
15630                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15631                        synchronized (bs) {
15632                            bs.removeUidStatsLocked(uid);
15633                        }
15634                        mAppOpsService.uidRemoved(uid);
15635                    }
15636                } else {
15637                    // If resources are unavailable just force stop all
15638                    // those packages and flush the attribute cache as well.
15639                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15640                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15641                        if (list != null && (list.length > 0)) {
15642                            for (String pkg : list) {
15643                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15644                                        "storage unmount");
15645                            }
15646                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15647                            sendPackageBroadcastLocked(
15648                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15649                        }
15650                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15651                            intent.getAction())) {
15652                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15653                    } else {
15654                        Uri data = intent.getData();
15655                        String ssp;
15656                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15657                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15658                                    intent.getAction());
15659                            boolean fullUninstall = removed &&
15660                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15661                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15662                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15663                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15664                                        false, fullUninstall, userId,
15665                                        removed ? "pkg removed" : "pkg changed");
15666                            }
15667                            if (removed) {
15668                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15669                                        new String[] {ssp}, userId);
15670                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15671                                    mAppOpsService.packageRemoved(
15672                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15673
15674                                    // Remove all permissions granted from/to this package
15675                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15676                                }
15677                            }
15678                        }
15679                    }
15680                }
15681            } else {
15682                String msg = "Permission Denial: " + intent.getAction()
15683                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15684                        + ", uid=" + callingUid + ")"
15685                        + " requires "
15686                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15687                Slog.w(TAG, msg);
15688                throw new SecurityException(msg);
15689            }
15690
15691        // Special case for adding a package: by default turn on compatibility
15692        // mode.
15693        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15694            Uri data = intent.getData();
15695            String ssp;
15696            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15697                mCompatModePackages.handlePackageAddedLocked(ssp,
15698                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15699            }
15700        }
15701
15702        /*
15703         * If this is the time zone changed action, queue up a message that will reset the timezone
15704         * of all currently running processes. This message will get queued up before the broadcast
15705         * happens.
15706         */
15707        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15708            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15709        }
15710
15711        /*
15712         * If the user set the time, let all running processes know.
15713         */
15714        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15715            final int is24Hour = intent.getBooleanExtra(
15716                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15717            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15718            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15719            synchronized (stats) {
15720                stats.noteCurrentTimeChangedLocked();
15721            }
15722        }
15723
15724        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15725            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15726        }
15727
15728        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15729            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15730            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15731        }
15732
15733        // Add to the sticky list if requested.
15734        if (sticky) {
15735            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15736                    callingPid, callingUid)
15737                    != PackageManager.PERMISSION_GRANTED) {
15738                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15739                        + callingPid + ", uid=" + callingUid
15740                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15741                Slog.w(TAG, msg);
15742                throw new SecurityException(msg);
15743            }
15744            if (requiredPermission != null) {
15745                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15746                        + " and enforce permission " + requiredPermission);
15747                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15748            }
15749            if (intent.getComponent() != null) {
15750                throw new SecurityException(
15751                        "Sticky broadcasts can't target a specific component");
15752            }
15753            // We use userId directly here, since the "all" target is maintained
15754            // as a separate set of sticky broadcasts.
15755            if (userId != UserHandle.USER_ALL) {
15756                // But first, if this is not a broadcast to all users, then
15757                // make sure it doesn't conflict with an existing broadcast to
15758                // all users.
15759                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15760                        UserHandle.USER_ALL);
15761                if (stickies != null) {
15762                    ArrayList<Intent> list = stickies.get(intent.getAction());
15763                    if (list != null) {
15764                        int N = list.size();
15765                        int i;
15766                        for (i=0; i<N; i++) {
15767                            if (intent.filterEquals(list.get(i))) {
15768                                throw new IllegalArgumentException(
15769                                        "Sticky broadcast " + intent + " for user "
15770                                        + userId + " conflicts with existing global broadcast");
15771                            }
15772                        }
15773                    }
15774                }
15775            }
15776            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15777            if (stickies == null) {
15778                stickies = new ArrayMap<String, ArrayList<Intent>>();
15779                mStickyBroadcasts.put(userId, stickies);
15780            }
15781            ArrayList<Intent> list = stickies.get(intent.getAction());
15782            if (list == null) {
15783                list = new ArrayList<Intent>();
15784                stickies.put(intent.getAction(), list);
15785            }
15786            int N = list.size();
15787            int i;
15788            for (i=0; i<N; i++) {
15789                if (intent.filterEquals(list.get(i))) {
15790                    // This sticky already exists, replace it.
15791                    list.set(i, new Intent(intent));
15792                    break;
15793                }
15794            }
15795            if (i >= N) {
15796                list.add(new Intent(intent));
15797            }
15798        }
15799
15800        int[] users;
15801        if (userId == UserHandle.USER_ALL) {
15802            // Caller wants broadcast to go to all started users.
15803            users = mStartedUserArray;
15804        } else {
15805            // Caller wants broadcast to go to one specific user.
15806            users = new int[] {userId};
15807        }
15808
15809        // Figure out who all will receive this broadcast.
15810        List receivers = null;
15811        List<BroadcastFilter> registeredReceivers = null;
15812        // Need to resolve the intent to interested receivers...
15813        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15814                 == 0) {
15815            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15816        }
15817        if (intent.getComponent() == null) {
15818            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15819                // Query one target user at a time, excluding shell-restricted users
15820                UserManagerService ums = getUserManagerLocked();
15821                for (int i = 0; i < users.length; i++) {
15822                    if (ums.hasUserRestriction(
15823                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15824                        continue;
15825                    }
15826                    List<BroadcastFilter> registeredReceiversForUser =
15827                            mReceiverResolver.queryIntent(intent,
15828                                    resolvedType, false, users[i]);
15829                    if (registeredReceivers == null) {
15830                        registeredReceivers = registeredReceiversForUser;
15831                    } else if (registeredReceiversForUser != null) {
15832                        registeredReceivers.addAll(registeredReceiversForUser);
15833                    }
15834                }
15835            } else {
15836                registeredReceivers = mReceiverResolver.queryIntent(intent,
15837                        resolvedType, false, userId);
15838            }
15839        }
15840
15841        final boolean replacePending =
15842                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15843
15844        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15845                + " replacePending=" + replacePending);
15846
15847        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15848        if (!ordered && NR > 0) {
15849            // If we are not serializing this broadcast, then send the
15850            // registered receivers separately so they don't wait for the
15851            // components to be launched.
15852            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15853            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15854                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15855                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15856                    ordered, sticky, false, userId);
15857            if (DEBUG_BROADCAST) Slog.v(
15858                    TAG, "Enqueueing parallel broadcast " + r);
15859            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15860            if (!replaced) {
15861                queue.enqueueParallelBroadcastLocked(r);
15862                queue.scheduleBroadcastsLocked();
15863            }
15864            registeredReceivers = null;
15865            NR = 0;
15866        }
15867
15868        // Merge into one list.
15869        int ir = 0;
15870        if (receivers != null) {
15871            // A special case for PACKAGE_ADDED: do not allow the package
15872            // being added to see this broadcast.  This prevents them from
15873            // using this as a back door to get run as soon as they are
15874            // installed.  Maybe in the future we want to have a special install
15875            // broadcast or such for apps, but we'd like to deliberately make
15876            // this decision.
15877            String skipPackages[] = null;
15878            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15879                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15880                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15881                Uri data = intent.getData();
15882                if (data != null) {
15883                    String pkgName = data.getSchemeSpecificPart();
15884                    if (pkgName != null) {
15885                        skipPackages = new String[] { pkgName };
15886                    }
15887                }
15888            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15889                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15890            }
15891            if (skipPackages != null && (skipPackages.length > 0)) {
15892                for (String skipPackage : skipPackages) {
15893                    if (skipPackage != null) {
15894                        int NT = receivers.size();
15895                        for (int it=0; it<NT; it++) {
15896                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15897                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15898                                receivers.remove(it);
15899                                it--;
15900                                NT--;
15901                            }
15902                        }
15903                    }
15904                }
15905            }
15906
15907            int NT = receivers != null ? receivers.size() : 0;
15908            int it = 0;
15909            ResolveInfo curt = null;
15910            BroadcastFilter curr = null;
15911            while (it < NT && ir < NR) {
15912                if (curt == null) {
15913                    curt = (ResolveInfo)receivers.get(it);
15914                }
15915                if (curr == null) {
15916                    curr = registeredReceivers.get(ir);
15917                }
15918                if (curr.getPriority() >= curt.priority) {
15919                    // Insert this broadcast record into the final list.
15920                    receivers.add(it, curr);
15921                    ir++;
15922                    curr = null;
15923                    it++;
15924                    NT++;
15925                } else {
15926                    // Skip to the next ResolveInfo in the final list.
15927                    it++;
15928                    curt = null;
15929                }
15930            }
15931        }
15932        while (ir < NR) {
15933            if (receivers == null) {
15934                receivers = new ArrayList();
15935            }
15936            receivers.add(registeredReceivers.get(ir));
15937            ir++;
15938        }
15939
15940        if ((receivers != null && receivers.size() > 0)
15941                || resultTo != null) {
15942            BroadcastQueue queue = broadcastQueueForIntent(intent);
15943            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15944                    callerPackage, callingPid, callingUid, resolvedType,
15945                    requiredPermission, appOp, receivers, resultTo, resultCode,
15946                    resultData, map, ordered, sticky, false, userId);
15947            if (DEBUG_BROADCAST) Slog.v(
15948                    TAG, "Enqueueing ordered broadcast " + r
15949                    + ": prev had " + queue.mOrderedBroadcasts.size());
15950            if (DEBUG_BROADCAST) {
15951                int seq = r.intent.getIntExtra("seq", -1);
15952                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15953            }
15954            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15955            if (!replaced) {
15956                queue.enqueueOrderedBroadcastLocked(r);
15957                queue.scheduleBroadcastsLocked();
15958            }
15959        }
15960
15961        return ActivityManager.BROADCAST_SUCCESS;
15962    }
15963
15964    final Intent verifyBroadcastLocked(Intent intent) {
15965        // Refuse possible leaked file descriptors
15966        if (intent != null && intent.hasFileDescriptors() == true) {
15967            throw new IllegalArgumentException("File descriptors passed in Intent");
15968        }
15969
15970        int flags = intent.getFlags();
15971
15972        if (!mProcessesReady) {
15973            // if the caller really truly claims to know what they're doing, go
15974            // ahead and allow the broadcast without launching any receivers
15975            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15976                intent = new Intent(intent);
15977                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15978            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15979                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15980                        + " before boot completion");
15981                throw new IllegalStateException("Cannot broadcast before boot completed");
15982            }
15983        }
15984
15985        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15986            throw new IllegalArgumentException(
15987                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15988        }
15989
15990        return intent;
15991    }
15992
15993    public final int broadcastIntent(IApplicationThread caller,
15994            Intent intent, String resolvedType, IIntentReceiver resultTo,
15995            int resultCode, String resultData, Bundle map,
15996            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15997        enforceNotIsolatedCaller("broadcastIntent");
15998        synchronized(this) {
15999            intent = verifyBroadcastLocked(intent);
16000
16001            final ProcessRecord callerApp = getRecordForAppLocked(caller);
16002            final int callingPid = Binder.getCallingPid();
16003            final int callingUid = Binder.getCallingUid();
16004            final long origId = Binder.clearCallingIdentity();
16005            int res = broadcastIntentLocked(callerApp,
16006                    callerApp != null ? callerApp.info.packageName : null,
16007                    intent, resolvedType, resultTo,
16008                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16009                    callingPid, callingUid, userId);
16010            Binder.restoreCallingIdentity(origId);
16011            return res;
16012        }
16013    }
16014
16015    int broadcastIntentInPackage(String packageName, int uid,
16016            Intent intent, String resolvedType, IIntentReceiver resultTo,
16017            int resultCode, String resultData, Bundle map,
16018            String requiredPermission, boolean serialized, boolean sticky, int userId) {
16019        synchronized(this) {
16020            intent = verifyBroadcastLocked(intent);
16021
16022            final long origId = Binder.clearCallingIdentity();
16023            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16024                    resultTo, resultCode, resultData, map, requiredPermission,
16025                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16026            Binder.restoreCallingIdentity(origId);
16027            return res;
16028        }
16029    }
16030
16031    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16032        // Refuse possible leaked file descriptors
16033        if (intent != null && intent.hasFileDescriptors() == true) {
16034            throw new IllegalArgumentException("File descriptors passed in Intent");
16035        }
16036
16037        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16038                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16039
16040        synchronized(this) {
16041            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16042                    != PackageManager.PERMISSION_GRANTED) {
16043                String msg = "Permission Denial: unbroadcastIntent() from pid="
16044                        + Binder.getCallingPid()
16045                        + ", uid=" + Binder.getCallingUid()
16046                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16047                Slog.w(TAG, msg);
16048                throw new SecurityException(msg);
16049            }
16050            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16051            if (stickies != null) {
16052                ArrayList<Intent> list = stickies.get(intent.getAction());
16053                if (list != null) {
16054                    int N = list.size();
16055                    int i;
16056                    for (i=0; i<N; i++) {
16057                        if (intent.filterEquals(list.get(i))) {
16058                            list.remove(i);
16059                            break;
16060                        }
16061                    }
16062                    if (list.size() <= 0) {
16063                        stickies.remove(intent.getAction());
16064                    }
16065                }
16066                if (stickies.size() <= 0) {
16067                    mStickyBroadcasts.remove(userId);
16068                }
16069            }
16070        }
16071    }
16072
16073    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16074            String resultData, Bundle resultExtras, boolean resultAbort) {
16075        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16076        if (r == null) {
16077            Slog.w(TAG, "finishReceiver called but not found on queue");
16078            return false;
16079        }
16080
16081        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16082    }
16083
16084    void backgroundServicesFinishedLocked(int userId) {
16085        for (BroadcastQueue queue : mBroadcastQueues) {
16086            queue.backgroundServicesFinishedLocked(userId);
16087        }
16088    }
16089
16090    public void finishReceiver(IBinder who, int resultCode, String resultData,
16091            Bundle resultExtras, boolean resultAbort) {
16092        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16093
16094        // Refuse possible leaked file descriptors
16095        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16096            throw new IllegalArgumentException("File descriptors passed in Bundle");
16097        }
16098
16099        final long origId = Binder.clearCallingIdentity();
16100        try {
16101            boolean doNext = false;
16102            BroadcastRecord r;
16103
16104            synchronized(this) {
16105                r = broadcastRecordForReceiverLocked(who);
16106                if (r != null) {
16107                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16108                        resultData, resultExtras, resultAbort, true);
16109                }
16110            }
16111
16112            if (doNext) {
16113                r.queue.processNextBroadcast(false);
16114            }
16115            trimApplications();
16116        } finally {
16117            Binder.restoreCallingIdentity(origId);
16118        }
16119    }
16120
16121    // =========================================================
16122    // INSTRUMENTATION
16123    // =========================================================
16124
16125    public boolean startInstrumentation(ComponentName className,
16126            String profileFile, int flags, Bundle arguments,
16127            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16128            int userId, String abiOverride) {
16129        enforceNotIsolatedCaller("startInstrumentation");
16130        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16131                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16132        // Refuse possible leaked file descriptors
16133        if (arguments != null && arguments.hasFileDescriptors()) {
16134            throw new IllegalArgumentException("File descriptors passed in Bundle");
16135        }
16136
16137        synchronized(this) {
16138            InstrumentationInfo ii = null;
16139            ApplicationInfo ai = null;
16140            try {
16141                ii = mContext.getPackageManager().getInstrumentationInfo(
16142                    className, STOCK_PM_FLAGS);
16143                ai = AppGlobals.getPackageManager().getApplicationInfo(
16144                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16145            } catch (PackageManager.NameNotFoundException e) {
16146            } catch (RemoteException e) {
16147            }
16148            if (ii == null) {
16149                reportStartInstrumentationFailure(watcher, className,
16150                        "Unable to find instrumentation info for: " + className);
16151                return false;
16152            }
16153            if (ai == null) {
16154                reportStartInstrumentationFailure(watcher, className,
16155                        "Unable to find instrumentation target package: " + ii.targetPackage);
16156                return false;
16157            }
16158
16159            int match = mContext.getPackageManager().checkSignatures(
16160                    ii.targetPackage, ii.packageName);
16161            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16162                String msg = "Permission Denial: starting instrumentation "
16163                        + className + " from pid="
16164                        + Binder.getCallingPid()
16165                        + ", uid=" + Binder.getCallingPid()
16166                        + " not allowed because package " + ii.packageName
16167                        + " does not have a signature matching the target "
16168                        + ii.targetPackage;
16169                reportStartInstrumentationFailure(watcher, className, msg);
16170                throw new SecurityException(msg);
16171            }
16172
16173            final long origId = Binder.clearCallingIdentity();
16174            // Instrumentation can kill and relaunch even persistent processes
16175            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16176                    "start instr");
16177            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16178            app.instrumentationClass = className;
16179            app.instrumentationInfo = ai;
16180            app.instrumentationProfileFile = profileFile;
16181            app.instrumentationArguments = arguments;
16182            app.instrumentationWatcher = watcher;
16183            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16184            app.instrumentationResultClass = className;
16185            Binder.restoreCallingIdentity(origId);
16186        }
16187
16188        return true;
16189    }
16190
16191    /**
16192     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16193     * error to the logs, but if somebody is watching, send the report there too.  This enables
16194     * the "am" command to report errors with more information.
16195     *
16196     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16197     * @param cn The component name of the instrumentation.
16198     * @param report The error report.
16199     */
16200    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16201            ComponentName cn, String report) {
16202        Slog.w(TAG, report);
16203        try {
16204            if (watcher != null) {
16205                Bundle results = new Bundle();
16206                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16207                results.putString("Error", report);
16208                watcher.instrumentationStatus(cn, -1, results);
16209            }
16210        } catch (RemoteException e) {
16211            Slog.w(TAG, e);
16212        }
16213    }
16214
16215    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16216        if (app.instrumentationWatcher != null) {
16217            try {
16218                // NOTE:  IInstrumentationWatcher *must* be oneway here
16219                app.instrumentationWatcher.instrumentationFinished(
16220                    app.instrumentationClass,
16221                    resultCode,
16222                    results);
16223            } catch (RemoteException e) {
16224            }
16225        }
16226        if (app.instrumentationUiAutomationConnection != null) {
16227            try {
16228                app.instrumentationUiAutomationConnection.shutdown();
16229            } catch (RemoteException re) {
16230                /* ignore */
16231            }
16232            // Only a UiAutomation can set this flag and now that
16233            // it is finished we make sure it is reset to its default.
16234            mUserIsMonkey = false;
16235        }
16236        app.instrumentationWatcher = null;
16237        app.instrumentationUiAutomationConnection = null;
16238        app.instrumentationClass = null;
16239        app.instrumentationInfo = null;
16240        app.instrumentationProfileFile = null;
16241        app.instrumentationArguments = null;
16242
16243        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16244                "finished inst");
16245    }
16246
16247    public void finishInstrumentation(IApplicationThread target,
16248            int resultCode, Bundle results) {
16249        int userId = UserHandle.getCallingUserId();
16250        // Refuse possible leaked file descriptors
16251        if (results != null && results.hasFileDescriptors()) {
16252            throw new IllegalArgumentException("File descriptors passed in Intent");
16253        }
16254
16255        synchronized(this) {
16256            ProcessRecord app = getRecordForAppLocked(target);
16257            if (app == null) {
16258                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16259                return;
16260            }
16261            final long origId = Binder.clearCallingIdentity();
16262            finishInstrumentationLocked(app, resultCode, results);
16263            Binder.restoreCallingIdentity(origId);
16264        }
16265    }
16266
16267    // =========================================================
16268    // CONFIGURATION
16269    // =========================================================
16270
16271    public ConfigurationInfo getDeviceConfigurationInfo() {
16272        ConfigurationInfo config = new ConfigurationInfo();
16273        synchronized (this) {
16274            config.reqTouchScreen = mConfiguration.touchscreen;
16275            config.reqKeyboardType = mConfiguration.keyboard;
16276            config.reqNavigation = mConfiguration.navigation;
16277            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16278                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16279                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16280            }
16281            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16282                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16283                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16284            }
16285            config.reqGlEsVersion = GL_ES_VERSION;
16286        }
16287        return config;
16288    }
16289
16290    ActivityStack getFocusedStack() {
16291        return mStackSupervisor.getFocusedStack();
16292    }
16293
16294    public Configuration getConfiguration() {
16295        Configuration ci;
16296        synchronized(this) {
16297            ci = new Configuration(mConfiguration);
16298        }
16299        return ci;
16300    }
16301
16302    public void updatePersistentConfiguration(Configuration values) {
16303        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16304                "updateConfiguration()");
16305        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16306                "updateConfiguration()");
16307        if (values == null) {
16308            throw new NullPointerException("Configuration must not be null");
16309        }
16310
16311        synchronized(this) {
16312            final long origId = Binder.clearCallingIdentity();
16313            updateConfigurationLocked(values, null, true, false);
16314            Binder.restoreCallingIdentity(origId);
16315        }
16316    }
16317
16318    public void updateConfiguration(Configuration values) {
16319        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16320                "updateConfiguration()");
16321
16322        synchronized(this) {
16323            if (values == null && mWindowManager != null) {
16324                // sentinel: fetch the current configuration from the window manager
16325                values = mWindowManager.computeNewConfiguration();
16326            }
16327
16328            if (mWindowManager != null) {
16329                mProcessList.applyDisplaySize(mWindowManager);
16330            }
16331
16332            final long origId = Binder.clearCallingIdentity();
16333            if (values != null) {
16334                Settings.System.clearConfiguration(values);
16335            }
16336            updateConfigurationLocked(values, null, false, false);
16337            Binder.restoreCallingIdentity(origId);
16338        }
16339    }
16340
16341    /**
16342     * Do either or both things: (1) change the current configuration, and (2)
16343     * make sure the given activity is running with the (now) current
16344     * configuration.  Returns true if the activity has been left running, or
16345     * false if <var>starting</var> is being destroyed to match the new
16346     * configuration.
16347     * @param persistent TODO
16348     */
16349    boolean updateConfigurationLocked(Configuration values,
16350            ActivityRecord starting, boolean persistent, boolean initLocale) {
16351        int changes = 0;
16352
16353        if (values != null) {
16354            Configuration newConfig = new Configuration(mConfiguration);
16355            changes = newConfig.updateFrom(values);
16356            if (changes != 0) {
16357                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16358                    Slog.i(TAG, "Updating configuration to: " + values);
16359                }
16360
16361                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16362
16363                if (values.locale != null && !initLocale) {
16364                    saveLocaleLocked(values.locale,
16365                                     !values.locale.equals(mConfiguration.locale),
16366                                     values.userSetLocale);
16367                }
16368
16369                mConfigurationSeq++;
16370                if (mConfigurationSeq <= 0) {
16371                    mConfigurationSeq = 1;
16372                }
16373                newConfig.seq = mConfigurationSeq;
16374                mConfiguration = newConfig;
16375                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16376                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16377                //mUsageStatsService.noteStartConfig(newConfig);
16378
16379                final Configuration configCopy = new Configuration(mConfiguration);
16380
16381                // TODO: If our config changes, should we auto dismiss any currently
16382                // showing dialogs?
16383                mShowDialogs = shouldShowDialogs(newConfig);
16384
16385                AttributeCache ac = AttributeCache.instance();
16386                if (ac != null) {
16387                    ac.updateConfiguration(configCopy);
16388                }
16389
16390                // Make sure all resources in our process are updated
16391                // right now, so that anyone who is going to retrieve
16392                // resource values after we return will be sure to get
16393                // the new ones.  This is especially important during
16394                // boot, where the first config change needs to guarantee
16395                // all resources have that config before following boot
16396                // code is executed.
16397                mSystemThread.applyConfigurationToResources(configCopy);
16398
16399                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16400                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16401                    msg.obj = new Configuration(configCopy);
16402                    mHandler.sendMessage(msg);
16403                }
16404
16405                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16406                    ProcessRecord app = mLruProcesses.get(i);
16407                    try {
16408                        if (app.thread != null) {
16409                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16410                                    + app.processName + " new config " + mConfiguration);
16411                            app.thread.scheduleConfigurationChanged(configCopy);
16412                        }
16413                    } catch (Exception e) {
16414                    }
16415                }
16416                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16417                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16418                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16419                        | Intent.FLAG_RECEIVER_FOREGROUND);
16420                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16421                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16422                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16423                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16424                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16425                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16426                    broadcastIntentLocked(null, null, intent,
16427                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16428                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16429                }
16430            }
16431        }
16432
16433        boolean kept = true;
16434        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16435        // mainStack is null during startup.
16436        if (mainStack != null) {
16437            if (changes != 0 && starting == null) {
16438                // If the configuration changed, and the caller is not already
16439                // in the process of starting an activity, then find the top
16440                // activity to check if its configuration needs to change.
16441                starting = mainStack.topRunningActivityLocked(null);
16442            }
16443
16444            if (starting != null) {
16445                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16446                // And we need to make sure at this point that all other activities
16447                // are made visible with the correct configuration.
16448                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16449            }
16450        }
16451
16452        if (values != null && mWindowManager != null) {
16453            mWindowManager.setNewConfiguration(mConfiguration);
16454        }
16455
16456        return kept;
16457    }
16458
16459    /**
16460     * Decide based on the configuration whether we should shouw the ANR,
16461     * crash, etc dialogs.  The idea is that if there is no affordnace to
16462     * press the on-screen buttons, we shouldn't show the dialog.
16463     *
16464     * A thought: SystemUI might also want to get told about this, the Power
16465     * dialog / global actions also might want different behaviors.
16466     */
16467    private static final boolean shouldShowDialogs(Configuration config) {
16468        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16469                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16470    }
16471
16472    /**
16473     * Save the locale.  You must be inside a synchronized (this) block.
16474     */
16475    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16476        if(isDiff) {
16477            SystemProperties.set("user.language", l.getLanguage());
16478            SystemProperties.set("user.region", l.getCountry());
16479        }
16480
16481        if(isPersist) {
16482            SystemProperties.set("persist.sys.language", l.getLanguage());
16483            SystemProperties.set("persist.sys.country", l.getCountry());
16484            SystemProperties.set("persist.sys.localevar", l.getVariant());
16485
16486            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16487        }
16488    }
16489
16490    @Override
16491    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16492        synchronized (this) {
16493            ActivityRecord srec = ActivityRecord.forToken(token);
16494            if (srec.task != null && srec.task.stack != null) {
16495                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16496            }
16497        }
16498        return false;
16499    }
16500
16501    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16502            Intent resultData) {
16503
16504        synchronized (this) {
16505            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16506            if (stack != null) {
16507                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16508            }
16509            return false;
16510        }
16511    }
16512
16513    public int getLaunchedFromUid(IBinder activityToken) {
16514        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16515        if (srec == null) {
16516            return -1;
16517        }
16518        return srec.launchedFromUid;
16519    }
16520
16521    public String getLaunchedFromPackage(IBinder activityToken) {
16522        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16523        if (srec == null) {
16524            return null;
16525        }
16526        return srec.launchedFromPackage;
16527    }
16528
16529    // =========================================================
16530    // LIFETIME MANAGEMENT
16531    // =========================================================
16532
16533    // Returns which broadcast queue the app is the current [or imminent] receiver
16534    // on, or 'null' if the app is not an active broadcast recipient.
16535    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16536        BroadcastRecord r = app.curReceiver;
16537        if (r != null) {
16538            return r.queue;
16539        }
16540
16541        // It's not the current receiver, but it might be starting up to become one
16542        synchronized (this) {
16543            for (BroadcastQueue queue : mBroadcastQueues) {
16544                r = queue.mPendingBroadcast;
16545                if (r != null && r.curApp == app) {
16546                    // found it; report which queue it's in
16547                    return queue;
16548                }
16549            }
16550        }
16551
16552        return null;
16553    }
16554
16555    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16556            boolean doingAll, long now) {
16557        if (mAdjSeq == app.adjSeq) {
16558            // This adjustment has already been computed.
16559            return app.curRawAdj;
16560        }
16561
16562        if (app.thread == null) {
16563            app.adjSeq = mAdjSeq;
16564            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16565            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16566            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16567        }
16568
16569        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16570        app.adjSource = null;
16571        app.adjTarget = null;
16572        app.empty = false;
16573        app.cached = false;
16574
16575        final int activitiesSize = app.activities.size();
16576
16577        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16578            // The max adjustment doesn't allow this app to be anything
16579            // below foreground, so it is not worth doing work for it.
16580            app.adjType = "fixed";
16581            app.adjSeq = mAdjSeq;
16582            app.curRawAdj = app.maxAdj;
16583            app.foregroundActivities = false;
16584            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16585            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16586            // System processes can do UI, and when they do we want to have
16587            // them trim their memory after the user leaves the UI.  To
16588            // facilitate this, here we need to determine whether or not it
16589            // is currently showing UI.
16590            app.systemNoUi = true;
16591            if (app == TOP_APP) {
16592                app.systemNoUi = false;
16593            } else if (activitiesSize > 0) {
16594                for (int j = 0; j < activitiesSize; j++) {
16595                    final ActivityRecord r = app.activities.get(j);
16596                    if (r.visible) {
16597                        app.systemNoUi = false;
16598                    }
16599                }
16600            }
16601            if (!app.systemNoUi) {
16602                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16603            }
16604            return (app.curAdj=app.maxAdj);
16605        }
16606
16607        app.systemNoUi = false;
16608
16609        // Determine the importance of the process, starting with most
16610        // important to least, and assign an appropriate OOM adjustment.
16611        int adj;
16612        int schedGroup;
16613        int procState;
16614        boolean foregroundActivities = false;
16615        BroadcastQueue queue;
16616        if (app == TOP_APP) {
16617            // The last app on the list is the foreground app.
16618            adj = ProcessList.FOREGROUND_APP_ADJ;
16619            schedGroup = Process.THREAD_GROUP_DEFAULT;
16620            app.adjType = "top-activity";
16621            foregroundActivities = true;
16622            procState = ActivityManager.PROCESS_STATE_TOP;
16623        } else if (app.instrumentationClass != null) {
16624            // Don't want to kill running instrumentation.
16625            adj = ProcessList.FOREGROUND_APP_ADJ;
16626            schedGroup = Process.THREAD_GROUP_DEFAULT;
16627            app.adjType = "instrumentation";
16628            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16629        } else if ((queue = isReceivingBroadcast(app)) != null) {
16630            // An app that is currently receiving a broadcast also
16631            // counts as being in the foreground for OOM killer purposes.
16632            // It's placed in a sched group based on the nature of the
16633            // broadcast as reflected by which queue it's active in.
16634            adj = ProcessList.FOREGROUND_APP_ADJ;
16635            schedGroup = (queue == mFgBroadcastQueue)
16636                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16637            app.adjType = "broadcast";
16638            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16639        } else if (app.executingServices.size() > 0) {
16640            // An app that is currently executing a service callback also
16641            // counts as being in the foreground.
16642            adj = ProcessList.FOREGROUND_APP_ADJ;
16643            schedGroup = app.execServicesFg ?
16644                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16645            app.adjType = "exec-service";
16646            procState = ActivityManager.PROCESS_STATE_SERVICE;
16647            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16648        } else {
16649            // As far as we know the process is empty.  We may change our mind later.
16650            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16651            // At this point we don't actually know the adjustment.  Use the cached adj
16652            // value that the caller wants us to.
16653            adj = cachedAdj;
16654            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16655            app.cached = true;
16656            app.empty = true;
16657            app.adjType = "cch-empty";
16658        }
16659
16660        // Examine all activities if not already foreground.
16661        if (!foregroundActivities && activitiesSize > 0) {
16662            for (int j = 0; j < activitiesSize; j++) {
16663                final ActivityRecord r = app.activities.get(j);
16664                if (r.app != app) {
16665                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16666                            + app + "?!?");
16667                    continue;
16668                }
16669                if (r.visible) {
16670                    // App has a visible activity; only upgrade adjustment.
16671                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16672                        adj = ProcessList.VISIBLE_APP_ADJ;
16673                        app.adjType = "visible";
16674                    }
16675                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16676                        procState = ActivityManager.PROCESS_STATE_TOP;
16677                    }
16678                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16679                    app.cached = false;
16680                    app.empty = false;
16681                    foregroundActivities = true;
16682                    break;
16683                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16684                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16685                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16686                        app.adjType = "pausing";
16687                    }
16688                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16689                        procState = ActivityManager.PROCESS_STATE_TOP;
16690                    }
16691                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16692                    app.cached = false;
16693                    app.empty = false;
16694                    foregroundActivities = true;
16695                } else if (r.state == ActivityState.STOPPING) {
16696                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16697                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16698                        app.adjType = "stopping";
16699                    }
16700                    // For the process state, we will at this point consider the
16701                    // process to be cached.  It will be cached either as an activity
16702                    // or empty depending on whether the activity is finishing.  We do
16703                    // this so that we can treat the process as cached for purposes of
16704                    // memory trimming (determing current memory level, trim command to
16705                    // send to process) since there can be an arbitrary number of stopping
16706                    // processes and they should soon all go into the cached state.
16707                    if (!r.finishing) {
16708                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16709                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16710                        }
16711                    }
16712                    app.cached = false;
16713                    app.empty = false;
16714                    foregroundActivities = true;
16715                } else {
16716                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16717                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16718                        app.adjType = "cch-act";
16719                    }
16720                }
16721            }
16722        }
16723
16724        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16725            if (app.foregroundServices) {
16726                // The user is aware of this app, so make it visible.
16727                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16728                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16729                app.cached = false;
16730                app.adjType = "fg-service";
16731                schedGroup = Process.THREAD_GROUP_DEFAULT;
16732            } else if (app.forcingToForeground != null) {
16733                // The user is aware of this app, so make it visible.
16734                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16735                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16736                app.cached = false;
16737                app.adjType = "force-fg";
16738                app.adjSource = app.forcingToForeground;
16739                schedGroup = Process.THREAD_GROUP_DEFAULT;
16740            }
16741        }
16742
16743        if (app == mHeavyWeightProcess) {
16744            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16745                // We don't want to kill the current heavy-weight process.
16746                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16747                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16748                app.cached = false;
16749                app.adjType = "heavy";
16750            }
16751            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16752                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16753            }
16754        }
16755
16756        if (app == mHomeProcess) {
16757            if (adj > ProcessList.HOME_APP_ADJ) {
16758                // This process is hosting what we currently consider to be the
16759                // home app, so we don't want to let it go into the background.
16760                adj = ProcessList.HOME_APP_ADJ;
16761                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16762                app.cached = false;
16763                app.adjType = "home";
16764            }
16765            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16766                procState = ActivityManager.PROCESS_STATE_HOME;
16767            }
16768        }
16769
16770        if (app == mPreviousProcess && app.activities.size() > 0) {
16771            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16772                // This was the previous process that showed UI to the user.
16773                // We want to try to keep it around more aggressively, to give
16774                // a good experience around switching between two apps.
16775                adj = ProcessList.PREVIOUS_APP_ADJ;
16776                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16777                app.cached = false;
16778                app.adjType = "previous";
16779            }
16780            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16781                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16782            }
16783        }
16784
16785        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16786                + " reason=" + app.adjType);
16787
16788        // By default, we use the computed adjustment.  It may be changed if
16789        // there are applications dependent on our services or providers, but
16790        // this gives us a baseline and makes sure we don't get into an
16791        // infinite recursion.
16792        app.adjSeq = mAdjSeq;
16793        app.curRawAdj = adj;
16794        app.hasStartedServices = false;
16795
16796        if (mBackupTarget != null && app == mBackupTarget.app) {
16797            // If possible we want to avoid killing apps while they're being backed up
16798            if (adj > ProcessList.BACKUP_APP_ADJ) {
16799                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16800                adj = ProcessList.BACKUP_APP_ADJ;
16801                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16802                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16803                }
16804                app.adjType = "backup";
16805                app.cached = false;
16806            }
16807            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16808                procState = ActivityManager.PROCESS_STATE_BACKUP;
16809            }
16810        }
16811
16812        boolean mayBeTop = false;
16813
16814        for (int is = app.services.size()-1;
16815                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16816                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16817                        || procState > ActivityManager.PROCESS_STATE_TOP);
16818                is--) {
16819            ServiceRecord s = app.services.valueAt(is);
16820            if (s.startRequested) {
16821                app.hasStartedServices = true;
16822                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16823                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16824                }
16825                if (app.hasShownUi && app != mHomeProcess) {
16826                    // If this process has shown some UI, let it immediately
16827                    // go to the LRU list because it may be pretty heavy with
16828                    // UI stuff.  We'll tag it with a label just to help
16829                    // debug and understand what is going on.
16830                    if (adj > ProcessList.SERVICE_ADJ) {
16831                        app.adjType = "cch-started-ui-services";
16832                    }
16833                } else {
16834                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16835                        // This service has seen some activity within
16836                        // recent memory, so we will keep its process ahead
16837                        // of the background processes.
16838                        if (adj > ProcessList.SERVICE_ADJ) {
16839                            adj = ProcessList.SERVICE_ADJ;
16840                            app.adjType = "started-services";
16841                            app.cached = false;
16842                        }
16843                    }
16844                    // If we have let the service slide into the background
16845                    // state, still have some text describing what it is doing
16846                    // even though the service no longer has an impact.
16847                    if (adj > ProcessList.SERVICE_ADJ) {
16848                        app.adjType = "cch-started-services";
16849                    }
16850                }
16851            }
16852            for (int conni = s.connections.size()-1;
16853                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16854                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16855                            || procState > ActivityManager.PROCESS_STATE_TOP);
16856                    conni--) {
16857                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16858                for (int i = 0;
16859                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16860                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16861                                || procState > ActivityManager.PROCESS_STATE_TOP);
16862                        i++) {
16863                    // XXX should compute this based on the max of
16864                    // all connected clients.
16865                    ConnectionRecord cr = clist.get(i);
16866                    if (cr.binding.client == app) {
16867                        // Binding to ourself is not interesting.
16868                        continue;
16869                    }
16870                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16871                        ProcessRecord client = cr.binding.client;
16872                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16873                                TOP_APP, doingAll, now);
16874                        int clientProcState = client.curProcState;
16875                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16876                            // If the other app is cached for any reason, for purposes here
16877                            // we are going to consider it empty.  The specific cached state
16878                            // doesn't propagate except under certain conditions.
16879                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16880                        }
16881                        String adjType = null;
16882                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16883                            // Not doing bind OOM management, so treat
16884                            // this guy more like a started service.
16885                            if (app.hasShownUi && app != mHomeProcess) {
16886                                // If this process has shown some UI, let it immediately
16887                                // go to the LRU list because it may be pretty heavy with
16888                                // UI stuff.  We'll tag it with a label just to help
16889                                // debug and understand what is going on.
16890                                if (adj > clientAdj) {
16891                                    adjType = "cch-bound-ui-services";
16892                                }
16893                                app.cached = false;
16894                                clientAdj = adj;
16895                                clientProcState = procState;
16896                            } else {
16897                                if (now >= (s.lastActivity
16898                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16899                                    // This service has not seen activity within
16900                                    // recent memory, so allow it to drop to the
16901                                    // LRU list if there is no other reason to keep
16902                                    // it around.  We'll also tag it with a label just
16903                                    // to help debug and undertand what is going on.
16904                                    if (adj > clientAdj) {
16905                                        adjType = "cch-bound-services";
16906                                    }
16907                                    clientAdj = adj;
16908                                }
16909                            }
16910                        }
16911                        if (adj > clientAdj) {
16912                            // If this process has recently shown UI, and
16913                            // the process that is binding to it is less
16914                            // important than being visible, then we don't
16915                            // care about the binding as much as we care
16916                            // about letting this process get into the LRU
16917                            // list to be killed and restarted if needed for
16918                            // memory.
16919                            if (app.hasShownUi && app != mHomeProcess
16920                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16921                                adjType = "cch-bound-ui-services";
16922                            } else {
16923                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16924                                        |Context.BIND_IMPORTANT)) != 0) {
16925                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16926                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16927                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16928                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16929                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16930                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16931                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16932                                    adj = clientAdj;
16933                                } else {
16934                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16935                                        adj = ProcessList.VISIBLE_APP_ADJ;
16936                                    }
16937                                }
16938                                if (!client.cached) {
16939                                    app.cached = false;
16940                                }
16941                                adjType = "service";
16942                            }
16943                        }
16944                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16945                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16946                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16947                            }
16948                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16949                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16950                                    // Special handling of clients who are in the top state.
16951                                    // We *may* want to consider this process to be in the
16952                                    // top state as well, but only if there is not another
16953                                    // reason for it to be running.  Being on the top is a
16954                                    // special state, meaning you are specifically running
16955                                    // for the current top app.  If the process is already
16956                                    // running in the background for some other reason, it
16957                                    // is more important to continue considering it to be
16958                                    // in the background state.
16959                                    mayBeTop = true;
16960                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16961                                } else {
16962                                    // Special handling for above-top states (persistent
16963                                    // processes).  These should not bring the current process
16964                                    // into the top state, since they are not on top.  Instead
16965                                    // give them the best state after that.
16966                                    clientProcState =
16967                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16968                                }
16969                            }
16970                        } else {
16971                            if (clientProcState <
16972                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16973                                clientProcState =
16974                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16975                            }
16976                        }
16977                        if (procState > clientProcState) {
16978                            procState = clientProcState;
16979                        }
16980                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16981                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16982                            app.pendingUiClean = true;
16983                        }
16984                        if (adjType != null) {
16985                            app.adjType = adjType;
16986                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16987                                    .REASON_SERVICE_IN_USE;
16988                            app.adjSource = cr.binding.client;
16989                            app.adjSourceProcState = clientProcState;
16990                            app.adjTarget = s.name;
16991                        }
16992                    }
16993                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16994                        app.treatLikeActivity = true;
16995                    }
16996                    final ActivityRecord a = cr.activity;
16997                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16998                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16999                                (a.visible || a.state == ActivityState.RESUMED
17000                                 || a.state == ActivityState.PAUSING)) {
17001                            adj = ProcessList.FOREGROUND_APP_ADJ;
17002                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17003                                schedGroup = Process.THREAD_GROUP_DEFAULT;
17004                            }
17005                            app.cached = false;
17006                            app.adjType = "service";
17007                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17008                                    .REASON_SERVICE_IN_USE;
17009                            app.adjSource = a;
17010                            app.adjSourceProcState = procState;
17011                            app.adjTarget = s.name;
17012                        }
17013                    }
17014                }
17015            }
17016        }
17017
17018        for (int provi = app.pubProviders.size()-1;
17019                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17020                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17021                        || procState > ActivityManager.PROCESS_STATE_TOP);
17022                provi--) {
17023            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17024            for (int i = cpr.connections.size()-1;
17025                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17026                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17027                            || procState > ActivityManager.PROCESS_STATE_TOP);
17028                    i--) {
17029                ContentProviderConnection conn = cpr.connections.get(i);
17030                ProcessRecord client = conn.client;
17031                if (client == app) {
17032                    // Being our own client is not interesting.
17033                    continue;
17034                }
17035                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17036                int clientProcState = client.curProcState;
17037                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17038                    // If the other app is cached for any reason, for purposes here
17039                    // we are going to consider it empty.
17040                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17041                }
17042                if (adj > clientAdj) {
17043                    if (app.hasShownUi && app != mHomeProcess
17044                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17045                        app.adjType = "cch-ui-provider";
17046                    } else {
17047                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17048                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17049                        app.adjType = "provider";
17050                    }
17051                    app.cached &= client.cached;
17052                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17053                            .REASON_PROVIDER_IN_USE;
17054                    app.adjSource = client;
17055                    app.adjSourceProcState = clientProcState;
17056                    app.adjTarget = cpr.name;
17057                }
17058                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17059                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17060                        // Special handling of clients who are in the top state.
17061                        // We *may* want to consider this process to be in the
17062                        // top state as well, but only if there is not another
17063                        // reason for it to be running.  Being on the top is a
17064                        // special state, meaning you are specifically running
17065                        // for the current top app.  If the process is already
17066                        // running in the background for some other reason, it
17067                        // is more important to continue considering it to be
17068                        // in the background state.
17069                        mayBeTop = true;
17070                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17071                    } else {
17072                        // Special handling for above-top states (persistent
17073                        // processes).  These should not bring the current process
17074                        // into the top state, since they are not on top.  Instead
17075                        // give them the best state after that.
17076                        clientProcState =
17077                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17078                    }
17079                }
17080                if (procState > clientProcState) {
17081                    procState = clientProcState;
17082                }
17083                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17084                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17085                }
17086            }
17087            // If the provider has external (non-framework) process
17088            // dependencies, ensure that its adjustment is at least
17089            // FOREGROUND_APP_ADJ.
17090            if (cpr.hasExternalProcessHandles()) {
17091                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17092                    adj = ProcessList.FOREGROUND_APP_ADJ;
17093                    schedGroup = Process.THREAD_GROUP_DEFAULT;
17094                    app.cached = false;
17095                    app.adjType = "provider";
17096                    app.adjTarget = cpr.name;
17097                }
17098                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17099                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17100                }
17101            }
17102        }
17103
17104        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17105            // A client of one of our services or providers is in the top state.  We
17106            // *may* want to be in the top state, but not if we are already running in
17107            // the background for some other reason.  For the decision here, we are going
17108            // to pick out a few specific states that we want to remain in when a client
17109            // is top (states that tend to be longer-term) and otherwise allow it to go
17110            // to the top state.
17111            switch (procState) {
17112                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17113                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17114                case ActivityManager.PROCESS_STATE_SERVICE:
17115                    // These all are longer-term states, so pull them up to the top
17116                    // of the background states, but not all the way to the top state.
17117                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17118                    break;
17119                default:
17120                    // Otherwise, top is a better choice, so take it.
17121                    procState = ActivityManager.PROCESS_STATE_TOP;
17122                    break;
17123            }
17124        }
17125
17126        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17127            if (app.hasClientActivities) {
17128                // This is a cached process, but with client activities.  Mark it so.
17129                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17130                app.adjType = "cch-client-act";
17131            } else if (app.treatLikeActivity) {
17132                // This is a cached process, but somebody wants us to treat it like it has
17133                // an activity, okay!
17134                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17135                app.adjType = "cch-as-act";
17136            }
17137        }
17138
17139        if (adj == ProcessList.SERVICE_ADJ) {
17140            if (doingAll) {
17141                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17142                mNewNumServiceProcs++;
17143                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17144                if (!app.serviceb) {
17145                    // This service isn't far enough down on the LRU list to
17146                    // normally be a B service, but if we are low on RAM and it
17147                    // is large we want to force it down since we would prefer to
17148                    // keep launcher over it.
17149                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17150                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17151                        app.serviceHighRam = true;
17152                        app.serviceb = true;
17153                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17154                    } else {
17155                        mNewNumAServiceProcs++;
17156                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17157                    }
17158                } else {
17159                    app.serviceHighRam = false;
17160                }
17161            }
17162            if (app.serviceb) {
17163                adj = ProcessList.SERVICE_B_ADJ;
17164            }
17165        }
17166
17167        app.curRawAdj = adj;
17168
17169        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17170        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17171        if (adj > app.maxAdj) {
17172            adj = app.maxAdj;
17173            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17174                schedGroup = Process.THREAD_GROUP_DEFAULT;
17175            }
17176        }
17177
17178        // Do final modification to adj.  Everything we do between here and applying
17179        // the final setAdj must be done in this function, because we will also use
17180        // it when computing the final cached adj later.  Note that we don't need to
17181        // worry about this for max adj above, since max adj will always be used to
17182        // keep it out of the cached vaues.
17183        app.curAdj = app.modifyRawOomAdj(adj);
17184        app.curSchedGroup = schedGroup;
17185        app.curProcState = procState;
17186        app.foregroundActivities = foregroundActivities;
17187
17188        return app.curRawAdj;
17189    }
17190
17191    /**
17192     * Schedule PSS collection of a process.
17193     */
17194    void requestPssLocked(ProcessRecord proc, int procState) {
17195        if (mPendingPssProcesses.contains(proc)) {
17196            return;
17197        }
17198        if (mPendingPssProcesses.size() == 0) {
17199            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17200        }
17201        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17202        proc.pssProcState = procState;
17203        mPendingPssProcesses.add(proc);
17204    }
17205
17206    /**
17207     * Schedule PSS collection of all processes.
17208     */
17209    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17210        if (!always) {
17211            if (now < (mLastFullPssTime +
17212                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17213                return;
17214            }
17215        }
17216        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17217        mLastFullPssTime = now;
17218        mFullPssPending = true;
17219        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17220        mPendingPssProcesses.clear();
17221        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17222            ProcessRecord app = mLruProcesses.get(i);
17223            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17224                app.pssProcState = app.setProcState;
17225                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17226                        isSleeping(), now);
17227                mPendingPssProcesses.add(app);
17228            }
17229        }
17230        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17231    }
17232
17233    /**
17234     * Ask a given process to GC right now.
17235     */
17236    final void performAppGcLocked(ProcessRecord app) {
17237        try {
17238            app.lastRequestedGc = SystemClock.uptimeMillis();
17239            if (app.thread != null) {
17240                if (app.reportLowMemory) {
17241                    app.reportLowMemory = false;
17242                    app.thread.scheduleLowMemory();
17243                } else {
17244                    app.thread.processInBackground();
17245                }
17246            }
17247        } catch (Exception e) {
17248            // whatever.
17249        }
17250    }
17251
17252    /**
17253     * Returns true if things are idle enough to perform GCs.
17254     */
17255    private final boolean canGcNowLocked() {
17256        boolean processingBroadcasts = false;
17257        for (BroadcastQueue q : mBroadcastQueues) {
17258            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17259                processingBroadcasts = true;
17260            }
17261        }
17262        return !processingBroadcasts
17263                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17264    }
17265
17266    /**
17267     * Perform GCs on all processes that are waiting for it, but only
17268     * if things are idle.
17269     */
17270    final void performAppGcsLocked() {
17271        final int N = mProcessesToGc.size();
17272        if (N <= 0) {
17273            return;
17274        }
17275        if (canGcNowLocked()) {
17276            while (mProcessesToGc.size() > 0) {
17277                ProcessRecord proc = mProcessesToGc.remove(0);
17278                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17279                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17280                            <= SystemClock.uptimeMillis()) {
17281                        // To avoid spamming the system, we will GC processes one
17282                        // at a time, waiting a few seconds between each.
17283                        performAppGcLocked(proc);
17284                        scheduleAppGcsLocked();
17285                        return;
17286                    } else {
17287                        // It hasn't been long enough since we last GCed this
17288                        // process...  put it in the list to wait for its time.
17289                        addProcessToGcListLocked(proc);
17290                        break;
17291                    }
17292                }
17293            }
17294
17295            scheduleAppGcsLocked();
17296        }
17297    }
17298
17299    /**
17300     * If all looks good, perform GCs on all processes waiting for them.
17301     */
17302    final void performAppGcsIfAppropriateLocked() {
17303        if (canGcNowLocked()) {
17304            performAppGcsLocked();
17305            return;
17306        }
17307        // Still not idle, wait some more.
17308        scheduleAppGcsLocked();
17309    }
17310
17311    /**
17312     * Schedule the execution of all pending app GCs.
17313     */
17314    final void scheduleAppGcsLocked() {
17315        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17316
17317        if (mProcessesToGc.size() > 0) {
17318            // Schedule a GC for the time to the next process.
17319            ProcessRecord proc = mProcessesToGc.get(0);
17320            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17321
17322            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17323            long now = SystemClock.uptimeMillis();
17324            if (when < (now+GC_TIMEOUT)) {
17325                when = now + GC_TIMEOUT;
17326            }
17327            mHandler.sendMessageAtTime(msg, when);
17328        }
17329    }
17330
17331    /**
17332     * Add a process to the array of processes waiting to be GCed.  Keeps the
17333     * list in sorted order by the last GC time.  The process can't already be
17334     * on the list.
17335     */
17336    final void addProcessToGcListLocked(ProcessRecord proc) {
17337        boolean added = false;
17338        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17339            if (mProcessesToGc.get(i).lastRequestedGc <
17340                    proc.lastRequestedGc) {
17341                added = true;
17342                mProcessesToGc.add(i+1, proc);
17343                break;
17344            }
17345        }
17346        if (!added) {
17347            mProcessesToGc.add(0, proc);
17348        }
17349    }
17350
17351    /**
17352     * Set up to ask a process to GC itself.  This will either do it
17353     * immediately, or put it on the list of processes to gc the next
17354     * time things are idle.
17355     */
17356    final void scheduleAppGcLocked(ProcessRecord app) {
17357        long now = SystemClock.uptimeMillis();
17358        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17359            return;
17360        }
17361        if (!mProcessesToGc.contains(app)) {
17362            addProcessToGcListLocked(app);
17363            scheduleAppGcsLocked();
17364        }
17365    }
17366
17367    final void checkExcessivePowerUsageLocked(boolean doKills) {
17368        updateCpuStatsNow();
17369
17370        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17371        boolean doWakeKills = doKills;
17372        boolean doCpuKills = doKills;
17373        if (mLastPowerCheckRealtime == 0) {
17374            doWakeKills = false;
17375        }
17376        if (mLastPowerCheckUptime == 0) {
17377            doCpuKills = false;
17378        }
17379        if (stats.isScreenOn()) {
17380            doWakeKills = false;
17381        }
17382        final long curRealtime = SystemClock.elapsedRealtime();
17383        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17384        final long curUptime = SystemClock.uptimeMillis();
17385        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17386        mLastPowerCheckRealtime = curRealtime;
17387        mLastPowerCheckUptime = curUptime;
17388        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17389            doWakeKills = false;
17390        }
17391        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17392            doCpuKills = false;
17393        }
17394        int i = mLruProcesses.size();
17395        while (i > 0) {
17396            i--;
17397            ProcessRecord app = mLruProcesses.get(i);
17398            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17399                long wtime;
17400                synchronized (stats) {
17401                    wtime = stats.getProcessWakeTime(app.info.uid,
17402                            app.pid, curRealtime);
17403                }
17404                long wtimeUsed = wtime - app.lastWakeTime;
17405                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17406                if (DEBUG_POWER) {
17407                    StringBuilder sb = new StringBuilder(128);
17408                    sb.append("Wake for ");
17409                    app.toShortString(sb);
17410                    sb.append(": over ");
17411                    TimeUtils.formatDuration(realtimeSince, sb);
17412                    sb.append(" used ");
17413                    TimeUtils.formatDuration(wtimeUsed, sb);
17414                    sb.append(" (");
17415                    sb.append((wtimeUsed*100)/realtimeSince);
17416                    sb.append("%)");
17417                    Slog.i(TAG, sb.toString());
17418                    sb.setLength(0);
17419                    sb.append("CPU for ");
17420                    app.toShortString(sb);
17421                    sb.append(": over ");
17422                    TimeUtils.formatDuration(uptimeSince, sb);
17423                    sb.append(" used ");
17424                    TimeUtils.formatDuration(cputimeUsed, sb);
17425                    sb.append(" (");
17426                    sb.append((cputimeUsed*100)/uptimeSince);
17427                    sb.append("%)");
17428                    Slog.i(TAG, sb.toString());
17429                }
17430                // If a process has held a wake lock for more
17431                // than 50% of the time during this period,
17432                // that sounds bad.  Kill!
17433                if (doWakeKills && realtimeSince > 0
17434                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17435                    synchronized (stats) {
17436                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17437                                realtimeSince, wtimeUsed);
17438                    }
17439                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17440                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17441                } else if (doCpuKills && uptimeSince > 0
17442                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17443                    synchronized (stats) {
17444                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17445                                uptimeSince, cputimeUsed);
17446                    }
17447                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17448                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17449                } else {
17450                    app.lastWakeTime = wtime;
17451                    app.lastCpuTime = app.curCpuTime;
17452                }
17453            }
17454        }
17455    }
17456
17457    private final boolean applyOomAdjLocked(ProcessRecord app,
17458            ProcessRecord TOP_APP, boolean doingAll, long now) {
17459        boolean success = true;
17460
17461        if (app.curRawAdj != app.setRawAdj) {
17462            app.setRawAdj = app.curRawAdj;
17463        }
17464
17465        int changes = 0;
17466
17467        if (app.curAdj != app.setAdj) {
17468            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17469            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17470                TAG, "Set " + app.pid + " " + app.processName +
17471                " adj " + app.curAdj + ": " + app.adjType);
17472            app.setAdj = app.curAdj;
17473        }
17474
17475        if (app.setSchedGroup != app.curSchedGroup) {
17476            app.setSchedGroup = app.curSchedGroup;
17477            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17478                    "Setting process group of " + app.processName
17479                    + " to " + app.curSchedGroup);
17480            if (app.waitingToKill != null &&
17481                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17482                app.kill(app.waitingToKill, true);
17483                success = false;
17484            } else {
17485                if (true) {
17486                    long oldId = Binder.clearCallingIdentity();
17487                    try {
17488                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17489                    } catch (Exception e) {
17490                        Slog.w(TAG, "Failed setting process group of " + app.pid
17491                                + " to " + app.curSchedGroup);
17492                        e.printStackTrace();
17493                    } finally {
17494                        Binder.restoreCallingIdentity(oldId);
17495                    }
17496                } else {
17497                    if (app.thread != null) {
17498                        try {
17499                            app.thread.setSchedulingGroup(app.curSchedGroup);
17500                        } catch (RemoteException e) {
17501                        }
17502                    }
17503                }
17504                Process.setSwappiness(app.pid,
17505                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17506            }
17507        }
17508        if (app.repForegroundActivities != app.foregroundActivities) {
17509            app.repForegroundActivities = app.foregroundActivities;
17510            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17511        }
17512        if (app.repProcState != app.curProcState) {
17513            app.repProcState = app.curProcState;
17514            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17515            if (app.thread != null) {
17516                try {
17517                    if (false) {
17518                        //RuntimeException h = new RuntimeException("here");
17519                        Slog.i(TAG, "Sending new process state " + app.repProcState
17520                                + " to " + app /*, h*/);
17521                    }
17522                    app.thread.setProcessState(app.repProcState);
17523                } catch (RemoteException e) {
17524                }
17525            }
17526        }
17527        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17528                app.setProcState)) {
17529            app.lastStateTime = now;
17530            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17531                    isSleeping(), now);
17532            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17533                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17534                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17535                    + (app.nextPssTime-now) + ": " + app);
17536        } else {
17537            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17538                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17539                requestPssLocked(app, app.setProcState);
17540                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17541                        isSleeping(), now);
17542            } else if (false && DEBUG_PSS) {
17543                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17544            }
17545        }
17546        if (app.setProcState != app.curProcState) {
17547            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17548                    "Proc state change of " + app.processName
17549                    + " to " + app.curProcState);
17550            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17551            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17552            if (setImportant && !curImportant) {
17553                // This app is no longer something we consider important enough to allow to
17554                // use arbitrary amounts of battery power.  Note
17555                // its current wake lock time to later know to kill it if
17556                // it is not behaving well.
17557                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17558                synchronized (stats) {
17559                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17560                            app.pid, SystemClock.elapsedRealtime());
17561                }
17562                app.lastCpuTime = app.curCpuTime;
17563
17564            }
17565            app.setProcState = app.curProcState;
17566            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17567                app.notCachedSinceIdle = false;
17568            }
17569            if (!doingAll) {
17570                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17571            } else {
17572                app.procStateChanged = true;
17573            }
17574        }
17575
17576        if (changes != 0) {
17577            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17578            int i = mPendingProcessChanges.size()-1;
17579            ProcessChangeItem item = null;
17580            while (i >= 0) {
17581                item = mPendingProcessChanges.get(i);
17582                if (item.pid == app.pid) {
17583                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17584                    break;
17585                }
17586                i--;
17587            }
17588            if (i < 0) {
17589                // No existing item in pending changes; need a new one.
17590                final int NA = mAvailProcessChanges.size();
17591                if (NA > 0) {
17592                    item = mAvailProcessChanges.remove(NA-1);
17593                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17594                } else {
17595                    item = new ProcessChangeItem();
17596                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17597                }
17598                item.changes = 0;
17599                item.pid = app.pid;
17600                item.uid = app.info.uid;
17601                if (mPendingProcessChanges.size() == 0) {
17602                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17603                            "*** Enqueueing dispatch processes changed!");
17604                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17605                }
17606                mPendingProcessChanges.add(item);
17607            }
17608            item.changes |= changes;
17609            item.processState = app.repProcState;
17610            item.foregroundActivities = app.repForegroundActivities;
17611            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17612                    + Integer.toHexString(System.identityHashCode(item))
17613                    + " " + app.toShortString() + ": changes=" + item.changes
17614                    + " procState=" + item.processState
17615                    + " foreground=" + item.foregroundActivities
17616                    + " type=" + app.adjType + " source=" + app.adjSource
17617                    + " target=" + app.adjTarget);
17618        }
17619
17620        return success;
17621    }
17622
17623    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17624        if (proc.thread != null) {
17625            if (proc.baseProcessTracker != null) {
17626                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17627            }
17628            if (proc.repProcState >= 0) {
17629                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17630                        proc.repProcState);
17631            }
17632        }
17633    }
17634
17635    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17636            ProcessRecord TOP_APP, boolean doingAll, long now) {
17637        if (app.thread == null) {
17638            return false;
17639        }
17640
17641        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17642
17643        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17644    }
17645
17646    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17647            boolean oomAdj) {
17648        if (isForeground != proc.foregroundServices) {
17649            proc.foregroundServices = isForeground;
17650            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17651                    proc.info.uid);
17652            if (isForeground) {
17653                if (curProcs == null) {
17654                    curProcs = new ArrayList<ProcessRecord>();
17655                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17656                }
17657                if (!curProcs.contains(proc)) {
17658                    curProcs.add(proc);
17659                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17660                            proc.info.packageName, proc.info.uid);
17661                }
17662            } else {
17663                if (curProcs != null) {
17664                    if (curProcs.remove(proc)) {
17665                        mBatteryStatsService.noteEvent(
17666                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17667                                proc.info.packageName, proc.info.uid);
17668                        if (curProcs.size() <= 0) {
17669                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17670                        }
17671                    }
17672                }
17673            }
17674            if (oomAdj) {
17675                updateOomAdjLocked();
17676            }
17677        }
17678    }
17679
17680    private final ActivityRecord resumedAppLocked() {
17681        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17682        String pkg;
17683        int uid;
17684        if (act != null) {
17685            pkg = act.packageName;
17686            uid = act.info.applicationInfo.uid;
17687        } else {
17688            pkg = null;
17689            uid = -1;
17690        }
17691        // Has the UID or resumed package name changed?
17692        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17693                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17694            if (mCurResumedPackage != null) {
17695                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17696                        mCurResumedPackage, mCurResumedUid);
17697            }
17698            mCurResumedPackage = pkg;
17699            mCurResumedUid = uid;
17700            if (mCurResumedPackage != null) {
17701                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17702                        mCurResumedPackage, mCurResumedUid);
17703            }
17704        }
17705        return act;
17706    }
17707
17708    final boolean updateOomAdjLocked(ProcessRecord app) {
17709        final ActivityRecord TOP_ACT = resumedAppLocked();
17710        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17711        final boolean wasCached = app.cached;
17712
17713        mAdjSeq++;
17714
17715        // This is the desired cached adjusment we want to tell it to use.
17716        // If our app is currently cached, we know it, and that is it.  Otherwise,
17717        // we don't know it yet, and it needs to now be cached we will then
17718        // need to do a complete oom adj.
17719        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17720                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17721        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17722                SystemClock.uptimeMillis());
17723        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17724            // Changed to/from cached state, so apps after it in the LRU
17725            // list may also be changed.
17726            updateOomAdjLocked();
17727        }
17728        return success;
17729    }
17730
17731    final void updateOomAdjLocked() {
17732        final ActivityRecord TOP_ACT = resumedAppLocked();
17733        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17734        final long now = SystemClock.uptimeMillis();
17735        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17736        final int N = mLruProcesses.size();
17737
17738        if (false) {
17739            RuntimeException e = new RuntimeException();
17740            e.fillInStackTrace();
17741            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17742        }
17743
17744        mAdjSeq++;
17745        mNewNumServiceProcs = 0;
17746        mNewNumAServiceProcs = 0;
17747
17748        final int emptyProcessLimit;
17749        final int cachedProcessLimit;
17750        if (mProcessLimit <= 0) {
17751            emptyProcessLimit = cachedProcessLimit = 0;
17752        } else if (mProcessLimit == 1) {
17753            emptyProcessLimit = 1;
17754            cachedProcessLimit = 0;
17755        } else {
17756            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17757            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17758        }
17759
17760        // Let's determine how many processes we have running vs.
17761        // how many slots we have for background processes; we may want
17762        // to put multiple processes in a slot of there are enough of
17763        // them.
17764        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17765                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17766        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17767        if (numEmptyProcs > cachedProcessLimit) {
17768            // If there are more empty processes than our limit on cached
17769            // processes, then use the cached process limit for the factor.
17770            // This ensures that the really old empty processes get pushed
17771            // down to the bottom, so if we are running low on memory we will
17772            // have a better chance at keeping around more cached processes
17773            // instead of a gazillion empty processes.
17774            numEmptyProcs = cachedProcessLimit;
17775        }
17776        int emptyFactor = numEmptyProcs/numSlots;
17777        if (emptyFactor < 1) emptyFactor = 1;
17778        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17779        if (cachedFactor < 1) cachedFactor = 1;
17780        int stepCached = 0;
17781        int stepEmpty = 0;
17782        int numCached = 0;
17783        int numEmpty = 0;
17784        int numTrimming = 0;
17785
17786        mNumNonCachedProcs = 0;
17787        mNumCachedHiddenProcs = 0;
17788
17789        // First update the OOM adjustment for each of the
17790        // application processes based on their current state.
17791        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17792        int nextCachedAdj = curCachedAdj+1;
17793        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17794        int nextEmptyAdj = curEmptyAdj+2;
17795        for (int i=N-1; i>=0; i--) {
17796            ProcessRecord app = mLruProcesses.get(i);
17797            if (!app.killedByAm && app.thread != null) {
17798                app.procStateChanged = false;
17799                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17800
17801                // If we haven't yet assigned the final cached adj
17802                // to the process, do that now.
17803                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17804                    switch (app.curProcState) {
17805                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17806                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17807                            // This process is a cached process holding activities...
17808                            // assign it the next cached value for that type, and then
17809                            // step that cached level.
17810                            app.curRawAdj = curCachedAdj;
17811                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17812                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17813                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17814                                    + ")");
17815                            if (curCachedAdj != nextCachedAdj) {
17816                                stepCached++;
17817                                if (stepCached >= cachedFactor) {
17818                                    stepCached = 0;
17819                                    curCachedAdj = nextCachedAdj;
17820                                    nextCachedAdj += 2;
17821                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17822                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17823                                    }
17824                                }
17825                            }
17826                            break;
17827                        default:
17828                            // For everything else, assign next empty cached process
17829                            // level and bump that up.  Note that this means that
17830                            // long-running services that have dropped down to the
17831                            // cached level will be treated as empty (since their process
17832                            // state is still as a service), which is what we want.
17833                            app.curRawAdj = curEmptyAdj;
17834                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17835                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17836                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17837                                    + ")");
17838                            if (curEmptyAdj != nextEmptyAdj) {
17839                                stepEmpty++;
17840                                if (stepEmpty >= emptyFactor) {
17841                                    stepEmpty = 0;
17842                                    curEmptyAdj = nextEmptyAdj;
17843                                    nextEmptyAdj += 2;
17844                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17845                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17846                                    }
17847                                }
17848                            }
17849                            break;
17850                    }
17851                }
17852
17853                applyOomAdjLocked(app, TOP_APP, true, now);
17854
17855                // Count the number of process types.
17856                switch (app.curProcState) {
17857                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17858                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17859                        mNumCachedHiddenProcs++;
17860                        numCached++;
17861                        if (numCached > cachedProcessLimit) {
17862                            app.kill("cached #" + numCached, true);
17863                        }
17864                        break;
17865                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17866                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17867                                && app.lastActivityTime < oldTime) {
17868                            app.kill("empty for "
17869                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17870                                    / 1000) + "s", true);
17871                        } else {
17872                            numEmpty++;
17873                            if (numEmpty > emptyProcessLimit) {
17874                                app.kill("empty #" + numEmpty, true);
17875                            }
17876                        }
17877                        break;
17878                    default:
17879                        mNumNonCachedProcs++;
17880                        break;
17881                }
17882
17883                if (app.isolated && app.services.size() <= 0) {
17884                    // If this is an isolated process, and there are no
17885                    // services running in it, then the process is no longer
17886                    // needed.  We agressively kill these because we can by
17887                    // definition not re-use the same process again, and it is
17888                    // good to avoid having whatever code was running in them
17889                    // left sitting around after no longer needed.
17890                    app.kill("isolated not needed", true);
17891                }
17892
17893                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17894                        && !app.killedByAm) {
17895                    numTrimming++;
17896                }
17897            }
17898        }
17899
17900        mNumServiceProcs = mNewNumServiceProcs;
17901
17902        // Now determine the memory trimming level of background processes.
17903        // Unfortunately we need to start at the back of the list to do this
17904        // properly.  We only do this if the number of background apps we
17905        // are managing to keep around is less than half the maximum we desire;
17906        // if we are keeping a good number around, we'll let them use whatever
17907        // memory they want.
17908        final int numCachedAndEmpty = numCached + numEmpty;
17909        int memFactor;
17910        if (numCached <= ProcessList.TRIM_CACHED_APPS
17911                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17912            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17913                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17914            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17915                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17916            } else {
17917                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17918            }
17919        } else {
17920            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17921        }
17922        // We always allow the memory level to go up (better).  We only allow it to go
17923        // down if we are in a state where that is allowed, *and* the total number of processes
17924        // has gone down since last time.
17925        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17926                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17927                + " last=" + mLastNumProcesses);
17928        if (memFactor > mLastMemoryLevel) {
17929            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17930                memFactor = mLastMemoryLevel;
17931                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17932            }
17933        }
17934        mLastMemoryLevel = memFactor;
17935        mLastNumProcesses = mLruProcesses.size();
17936        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17937        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17938        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17939            if (mLowRamStartTime == 0) {
17940                mLowRamStartTime = now;
17941            }
17942            int step = 0;
17943            int fgTrimLevel;
17944            switch (memFactor) {
17945                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17946                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17947                    break;
17948                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17949                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17950                    break;
17951                default:
17952                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17953                    break;
17954            }
17955            int factor = numTrimming/3;
17956            int minFactor = 2;
17957            if (mHomeProcess != null) minFactor++;
17958            if (mPreviousProcess != null) minFactor++;
17959            if (factor < minFactor) factor = minFactor;
17960            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17961            for (int i=N-1; i>=0; i--) {
17962                ProcessRecord app = mLruProcesses.get(i);
17963                if (allChanged || app.procStateChanged) {
17964                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17965                    app.procStateChanged = false;
17966                }
17967                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17968                        && !app.killedByAm) {
17969                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17970                        try {
17971                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17972                                    "Trimming memory of " + app.processName
17973                                    + " to " + curLevel);
17974                            app.thread.scheduleTrimMemory(curLevel);
17975                        } catch (RemoteException e) {
17976                        }
17977                        if (false) {
17978                            // For now we won't do this; our memory trimming seems
17979                            // to be good enough at this point that destroying
17980                            // activities causes more harm than good.
17981                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17982                                    && app != mHomeProcess && app != mPreviousProcess) {
17983                                // Need to do this on its own message because the stack may not
17984                                // be in a consistent state at this point.
17985                                // For these apps we will also finish their activities
17986                                // to help them free memory.
17987                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17988                            }
17989                        }
17990                    }
17991                    app.trimMemoryLevel = curLevel;
17992                    step++;
17993                    if (step >= factor) {
17994                        step = 0;
17995                        switch (curLevel) {
17996                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17997                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17998                                break;
17999                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18000                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18001                                break;
18002                        }
18003                    }
18004                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18005                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18006                            && app.thread != null) {
18007                        try {
18008                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18009                                    "Trimming memory of heavy-weight " + app.processName
18010                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18011                            app.thread.scheduleTrimMemory(
18012                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18013                        } catch (RemoteException e) {
18014                        }
18015                    }
18016                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18017                } else {
18018                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18019                            || app.systemNoUi) && app.pendingUiClean) {
18020                        // If this application is now in the background and it
18021                        // had done UI, then give it the special trim level to
18022                        // have it free UI resources.
18023                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18024                        if (app.trimMemoryLevel < level && app.thread != null) {
18025                            try {
18026                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18027                                        "Trimming memory of bg-ui " + app.processName
18028                                        + " to " + level);
18029                                app.thread.scheduleTrimMemory(level);
18030                            } catch (RemoteException e) {
18031                            }
18032                        }
18033                        app.pendingUiClean = false;
18034                    }
18035                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18036                        try {
18037                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18038                                    "Trimming memory of fg " + app.processName
18039                                    + " to " + fgTrimLevel);
18040                            app.thread.scheduleTrimMemory(fgTrimLevel);
18041                        } catch (RemoteException e) {
18042                        }
18043                    }
18044                    app.trimMemoryLevel = fgTrimLevel;
18045                }
18046            }
18047        } else {
18048            if (mLowRamStartTime != 0) {
18049                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18050                mLowRamStartTime = 0;
18051            }
18052            for (int i=N-1; i>=0; i--) {
18053                ProcessRecord app = mLruProcesses.get(i);
18054                if (allChanged || app.procStateChanged) {
18055                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
18056                    app.procStateChanged = false;
18057                }
18058                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18059                        || app.systemNoUi) && app.pendingUiClean) {
18060                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18061                            && app.thread != null) {
18062                        try {
18063                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18064                                    "Trimming memory of ui hidden " + app.processName
18065                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18066                            app.thread.scheduleTrimMemory(
18067                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18068                        } catch (RemoteException e) {
18069                        }
18070                    }
18071                    app.pendingUiClean = false;
18072                }
18073                app.trimMemoryLevel = 0;
18074            }
18075        }
18076
18077        if (mAlwaysFinishActivities) {
18078            // Need to do this on its own message because the stack may not
18079            // be in a consistent state at this point.
18080            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18081        }
18082
18083        if (allChanged) {
18084            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18085        }
18086
18087        if (mProcessStats.shouldWriteNowLocked(now)) {
18088            mHandler.post(new Runnable() {
18089                @Override public void run() {
18090                    synchronized (ActivityManagerService.this) {
18091                        mProcessStats.writeStateAsyncLocked();
18092                    }
18093                }
18094            });
18095        }
18096
18097        if (DEBUG_OOM_ADJ) {
18098            if (false) {
18099                RuntimeException here = new RuntimeException("here");
18100                here.fillInStackTrace();
18101                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18102            } else {
18103                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18104            }
18105        }
18106    }
18107
18108    final void trimApplications() {
18109        synchronized (this) {
18110            int i;
18111
18112            // First remove any unused application processes whose package
18113            // has been removed.
18114            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18115                final ProcessRecord app = mRemovedProcesses.get(i);
18116                if (app.activities.size() == 0
18117                        && app.curReceiver == null && app.services.size() == 0) {
18118                    Slog.i(
18119                        TAG, "Exiting empty application process "
18120                        + app.processName + " ("
18121                        + (app.thread != null ? app.thread.asBinder() : null)
18122                        + ")\n");
18123                    if (app.pid > 0 && app.pid != MY_PID) {
18124                        app.kill("empty", false);
18125                    } else {
18126                        try {
18127                            app.thread.scheduleExit();
18128                        } catch (Exception e) {
18129                            // Ignore exceptions.
18130                        }
18131                    }
18132                    cleanUpApplicationRecordLocked(app, false, true, -1);
18133                    mRemovedProcesses.remove(i);
18134
18135                    if (app.persistent) {
18136                        addAppLocked(app.info, false, null /* ABI override */);
18137                    }
18138                }
18139            }
18140
18141            // Now update the oom adj for all processes.
18142            updateOomAdjLocked();
18143        }
18144    }
18145
18146    /** This method sends the specified signal to each of the persistent apps */
18147    public void signalPersistentProcesses(int sig) throws RemoteException {
18148        if (sig != Process.SIGNAL_USR1) {
18149            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18150        }
18151
18152        synchronized (this) {
18153            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18154                    != PackageManager.PERMISSION_GRANTED) {
18155                throw new SecurityException("Requires permission "
18156                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18157            }
18158
18159            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18160                ProcessRecord r = mLruProcesses.get(i);
18161                if (r.thread != null && r.persistent) {
18162                    Process.sendSignal(r.pid, sig);
18163                }
18164            }
18165        }
18166    }
18167
18168    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18169        if (proc == null || proc == mProfileProc) {
18170            proc = mProfileProc;
18171            profileType = mProfileType;
18172            clearProfilerLocked();
18173        }
18174        if (proc == null) {
18175            return;
18176        }
18177        try {
18178            proc.thread.profilerControl(false, null, profileType);
18179        } catch (RemoteException e) {
18180            throw new IllegalStateException("Process disappeared");
18181        }
18182    }
18183
18184    private void clearProfilerLocked() {
18185        if (mProfileFd != null) {
18186            try {
18187                mProfileFd.close();
18188            } catch (IOException e) {
18189            }
18190        }
18191        mProfileApp = null;
18192        mProfileProc = null;
18193        mProfileFile = null;
18194        mProfileType = 0;
18195        mAutoStopProfiler = false;
18196        mSamplingInterval = 0;
18197    }
18198
18199    public boolean profileControl(String process, int userId, boolean start,
18200            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18201
18202        try {
18203            synchronized (this) {
18204                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18205                // its own permission.
18206                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18207                        != PackageManager.PERMISSION_GRANTED) {
18208                    throw new SecurityException("Requires permission "
18209                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18210                }
18211
18212                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18213                    throw new IllegalArgumentException("null profile info or fd");
18214                }
18215
18216                ProcessRecord proc = null;
18217                if (process != null) {
18218                    proc = findProcessLocked(process, userId, "profileControl");
18219                }
18220
18221                if (start && (proc == null || proc.thread == null)) {
18222                    throw new IllegalArgumentException("Unknown process: " + process);
18223                }
18224
18225                if (start) {
18226                    stopProfilerLocked(null, 0);
18227                    setProfileApp(proc.info, proc.processName, profilerInfo);
18228                    mProfileProc = proc;
18229                    mProfileType = profileType;
18230                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18231                    try {
18232                        fd = fd.dup();
18233                    } catch (IOException e) {
18234                        fd = null;
18235                    }
18236                    profilerInfo.profileFd = fd;
18237                    proc.thread.profilerControl(start, profilerInfo, profileType);
18238                    fd = null;
18239                    mProfileFd = null;
18240                } else {
18241                    stopProfilerLocked(proc, profileType);
18242                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18243                        try {
18244                            profilerInfo.profileFd.close();
18245                        } catch (IOException e) {
18246                        }
18247                    }
18248                }
18249
18250                return true;
18251            }
18252        } catch (RemoteException e) {
18253            throw new IllegalStateException("Process disappeared");
18254        } finally {
18255            if (profilerInfo != null && profilerInfo.profileFd != null) {
18256                try {
18257                    profilerInfo.profileFd.close();
18258                } catch (IOException e) {
18259                }
18260            }
18261        }
18262    }
18263
18264    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18265        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18266                userId, true, ALLOW_FULL_ONLY, callName, null);
18267        ProcessRecord proc = null;
18268        try {
18269            int pid = Integer.parseInt(process);
18270            synchronized (mPidsSelfLocked) {
18271                proc = mPidsSelfLocked.get(pid);
18272            }
18273        } catch (NumberFormatException e) {
18274        }
18275
18276        if (proc == null) {
18277            ArrayMap<String, SparseArray<ProcessRecord>> all
18278                    = mProcessNames.getMap();
18279            SparseArray<ProcessRecord> procs = all.get(process);
18280            if (procs != null && procs.size() > 0) {
18281                proc = procs.valueAt(0);
18282                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18283                    for (int i=1; i<procs.size(); i++) {
18284                        ProcessRecord thisProc = procs.valueAt(i);
18285                        if (thisProc.userId == userId) {
18286                            proc = thisProc;
18287                            break;
18288                        }
18289                    }
18290                }
18291            }
18292        }
18293
18294        return proc;
18295    }
18296
18297    public boolean dumpHeap(String process, int userId, boolean managed,
18298            String path, ParcelFileDescriptor fd) throws RemoteException {
18299
18300        try {
18301            synchronized (this) {
18302                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18303                // its own permission (same as profileControl).
18304                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18305                        != PackageManager.PERMISSION_GRANTED) {
18306                    throw new SecurityException("Requires permission "
18307                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18308                }
18309
18310                if (fd == null) {
18311                    throw new IllegalArgumentException("null fd");
18312                }
18313
18314                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18315                if (proc == null || proc.thread == null) {
18316                    throw new IllegalArgumentException("Unknown process: " + process);
18317                }
18318
18319                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18320                if (!isDebuggable) {
18321                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18322                        throw new SecurityException("Process not debuggable: " + proc);
18323                    }
18324                }
18325
18326                proc.thread.dumpHeap(managed, path, fd);
18327                fd = null;
18328                return true;
18329            }
18330        } catch (RemoteException e) {
18331            throw new IllegalStateException("Process disappeared");
18332        } finally {
18333            if (fd != null) {
18334                try {
18335                    fd.close();
18336                } catch (IOException e) {
18337                }
18338            }
18339        }
18340    }
18341
18342    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18343    public void monitor() {
18344        synchronized (this) { }
18345    }
18346
18347    void onCoreSettingsChange(Bundle settings) {
18348        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18349            ProcessRecord processRecord = mLruProcesses.get(i);
18350            try {
18351                if (processRecord.thread != null) {
18352                    processRecord.thread.setCoreSettings(settings);
18353                }
18354            } catch (RemoteException re) {
18355                /* ignore */
18356            }
18357        }
18358    }
18359
18360    // Multi-user methods
18361
18362    /**
18363     * Start user, if its not already running, but don't bring it to foreground.
18364     */
18365    @Override
18366    public boolean startUserInBackground(final int userId) {
18367        return startUser(userId, /* foreground */ false);
18368    }
18369
18370    /**
18371     * Start user, if its not already running, and bring it to foreground.
18372     */
18373    boolean startUserInForeground(final int userId, Dialog dlg) {
18374        boolean result = startUser(userId, /* foreground */ true);
18375        dlg.dismiss();
18376        return result;
18377    }
18378
18379    /**
18380     * Refreshes the list of users related to the current user when either a
18381     * user switch happens or when a new related user is started in the
18382     * background.
18383     */
18384    private void updateCurrentProfileIdsLocked() {
18385        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18386                mCurrentUserId, false /* enabledOnly */);
18387        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18388        for (int i = 0; i < currentProfileIds.length; i++) {
18389            currentProfileIds[i] = profiles.get(i).id;
18390        }
18391        mCurrentProfileIds = currentProfileIds;
18392
18393        synchronized (mUserProfileGroupIdsSelfLocked) {
18394            mUserProfileGroupIdsSelfLocked.clear();
18395            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18396            for (int i = 0; i < users.size(); i++) {
18397                UserInfo user = users.get(i);
18398                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18399                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18400                }
18401            }
18402        }
18403    }
18404
18405    private Set getProfileIdsLocked(int userId) {
18406        Set userIds = new HashSet<Integer>();
18407        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18408                userId, false /* enabledOnly */);
18409        for (UserInfo user : profiles) {
18410            userIds.add(Integer.valueOf(user.id));
18411        }
18412        return userIds;
18413    }
18414
18415    @Override
18416    public boolean switchUser(final int userId) {
18417        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18418        String userName;
18419        synchronized (this) {
18420            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18421            if (userInfo == null) {
18422                Slog.w(TAG, "No user info for user #" + userId);
18423                return false;
18424            }
18425            if (userInfo.isManagedProfile()) {
18426                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18427                return false;
18428            }
18429            userName = userInfo.name;
18430            mTargetUserId = userId;
18431        }
18432        mHandler.removeMessages(START_USER_SWITCH_MSG);
18433        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18434        return true;
18435    }
18436
18437    private void showUserSwitchDialog(int userId, String userName) {
18438        // The dialog will show and then initiate the user switch by calling startUserInForeground
18439        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18440                true /* above system */);
18441        d.show();
18442    }
18443
18444    private boolean startUser(final int userId, final boolean foreground) {
18445        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18446                != PackageManager.PERMISSION_GRANTED) {
18447            String msg = "Permission Denial: switchUser() from pid="
18448                    + Binder.getCallingPid()
18449                    + ", uid=" + Binder.getCallingUid()
18450                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18451            Slog.w(TAG, msg);
18452            throw new SecurityException(msg);
18453        }
18454
18455        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18456
18457        final long ident = Binder.clearCallingIdentity();
18458        try {
18459            synchronized (this) {
18460                final int oldUserId = mCurrentUserId;
18461                if (oldUserId == userId) {
18462                    return true;
18463                }
18464
18465                mStackSupervisor.setLockTaskModeLocked(null, false);
18466
18467                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18468                if (userInfo == null) {
18469                    Slog.w(TAG, "No user info for user #" + userId);
18470                    return false;
18471                }
18472                if (foreground && userInfo.isManagedProfile()) {
18473                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18474                    return false;
18475                }
18476
18477                if (foreground) {
18478                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18479                            R.anim.screen_user_enter);
18480                }
18481
18482                boolean needStart = false;
18483
18484                // If the user we are switching to is not currently started, then
18485                // we need to start it now.
18486                if (mStartedUsers.get(userId) == null) {
18487                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18488                    updateStartedUserArrayLocked();
18489                    needStart = true;
18490                }
18491
18492                final Integer userIdInt = Integer.valueOf(userId);
18493                mUserLru.remove(userIdInt);
18494                mUserLru.add(userIdInt);
18495
18496                if (foreground) {
18497                    mCurrentUserId = userId;
18498                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18499                    updateCurrentProfileIdsLocked();
18500                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18501                    // Once the internal notion of the active user has switched, we lock the device
18502                    // with the option to show the user switcher on the keyguard.
18503                    mWindowManager.lockNow(null);
18504                } else {
18505                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18506                    updateCurrentProfileIdsLocked();
18507                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18508                    mUserLru.remove(currentUserIdInt);
18509                    mUserLru.add(currentUserIdInt);
18510                }
18511
18512                final UserStartedState uss = mStartedUsers.get(userId);
18513
18514                // Make sure user is in the started state.  If it is currently
18515                // stopping, we need to knock that off.
18516                if (uss.mState == UserStartedState.STATE_STOPPING) {
18517                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18518                    // so we can just fairly silently bring the user back from
18519                    // the almost-dead.
18520                    uss.mState = UserStartedState.STATE_RUNNING;
18521                    updateStartedUserArrayLocked();
18522                    needStart = true;
18523                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18524                    // This means ACTION_SHUTDOWN has been sent, so we will
18525                    // need to treat this as a new boot of the user.
18526                    uss.mState = UserStartedState.STATE_BOOTING;
18527                    updateStartedUserArrayLocked();
18528                    needStart = true;
18529                }
18530
18531                if (uss.mState == UserStartedState.STATE_BOOTING) {
18532                    // Booting up a new user, need to tell system services about it.
18533                    // Note that this is on the same handler as scheduling of broadcasts,
18534                    // which is important because it needs to go first.
18535                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18536                }
18537
18538                if (foreground) {
18539                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18540                            oldUserId));
18541                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18542                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18543                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18544                            oldUserId, userId, uss));
18545                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18546                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18547                }
18548
18549                if (needStart) {
18550                    // Send USER_STARTED broadcast
18551                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18552                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18553                            | Intent.FLAG_RECEIVER_FOREGROUND);
18554                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18555                    broadcastIntentLocked(null, null, intent,
18556                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18557                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18558                }
18559
18560                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18561                    if (userId != UserHandle.USER_OWNER) {
18562                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18563                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18564                        broadcastIntentLocked(null, null, intent, null,
18565                                new IIntentReceiver.Stub() {
18566                                    public void performReceive(Intent intent, int resultCode,
18567                                            String data, Bundle extras, boolean ordered,
18568                                            boolean sticky, int sendingUser) {
18569                                        onUserInitialized(uss, foreground, oldUserId, userId);
18570                                    }
18571                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18572                                true, false, MY_PID, Process.SYSTEM_UID,
18573                                userId);
18574                        uss.initializing = true;
18575                    } else {
18576                        getUserManagerLocked().makeInitialized(userInfo.id);
18577                    }
18578                }
18579
18580                if (foreground) {
18581                    if (!uss.initializing) {
18582                        moveUserToForeground(uss, oldUserId, userId);
18583                    }
18584                } else {
18585                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18586                }
18587
18588                if (needStart) {
18589                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18590                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18591                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18592                    broadcastIntentLocked(null, null, intent,
18593                            null, new IIntentReceiver.Stub() {
18594                                @Override
18595                                public void performReceive(Intent intent, int resultCode, String data,
18596                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18597                                        throws RemoteException {
18598                                }
18599                            }, 0, null, null,
18600                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18601                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18602                }
18603            }
18604        } finally {
18605            Binder.restoreCallingIdentity(ident);
18606        }
18607
18608        return true;
18609    }
18610
18611    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18612        long ident = Binder.clearCallingIdentity();
18613        try {
18614            Intent intent;
18615            if (oldUserId >= 0) {
18616                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18617                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18618                int count = profiles.size();
18619                for (int i = 0; i < count; i++) {
18620                    int profileUserId = profiles.get(i).id;
18621                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18622                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18623                            | Intent.FLAG_RECEIVER_FOREGROUND);
18624                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18625                    broadcastIntentLocked(null, null, intent,
18626                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18627                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18628                }
18629            }
18630            if (newUserId >= 0) {
18631                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18632                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18633                int count = profiles.size();
18634                for (int i = 0; i < count; i++) {
18635                    int profileUserId = profiles.get(i).id;
18636                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18637                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18638                            | Intent.FLAG_RECEIVER_FOREGROUND);
18639                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18640                    broadcastIntentLocked(null, null, intent,
18641                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18642                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18643                }
18644                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18645                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18646                        | Intent.FLAG_RECEIVER_FOREGROUND);
18647                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18648                broadcastIntentLocked(null, null, intent,
18649                        null, null, 0, null, null,
18650                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18651                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18652            }
18653        } finally {
18654            Binder.restoreCallingIdentity(ident);
18655        }
18656    }
18657
18658    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18659            final int newUserId) {
18660        final int N = mUserSwitchObservers.beginBroadcast();
18661        if (N > 0) {
18662            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18663                int mCount = 0;
18664                @Override
18665                public void sendResult(Bundle data) throws RemoteException {
18666                    synchronized (ActivityManagerService.this) {
18667                        if (mCurUserSwitchCallback == this) {
18668                            mCount++;
18669                            if (mCount == N) {
18670                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18671                            }
18672                        }
18673                    }
18674                }
18675            };
18676            synchronized (this) {
18677                uss.switching = true;
18678                mCurUserSwitchCallback = callback;
18679            }
18680            for (int i=0; i<N; i++) {
18681                try {
18682                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18683                            newUserId, callback);
18684                } catch (RemoteException e) {
18685                }
18686            }
18687        } else {
18688            synchronized (this) {
18689                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18690            }
18691        }
18692        mUserSwitchObservers.finishBroadcast();
18693    }
18694
18695    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18696        synchronized (this) {
18697            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18698            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18699        }
18700    }
18701
18702    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18703        mCurUserSwitchCallback = null;
18704        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18705        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18706                oldUserId, newUserId, uss));
18707    }
18708
18709    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18710        synchronized (this) {
18711            if (foreground) {
18712                moveUserToForeground(uss, oldUserId, newUserId);
18713            }
18714        }
18715
18716        completeSwitchAndInitalize(uss, newUserId, true, false);
18717    }
18718
18719    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18720        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18721        if (homeInFront) {
18722            startHomeActivityLocked(newUserId);
18723        } else {
18724            mStackSupervisor.resumeTopActivitiesLocked();
18725        }
18726        EventLogTags.writeAmSwitchUser(newUserId);
18727        getUserManagerLocked().userForeground(newUserId);
18728        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18729    }
18730
18731    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18732        completeSwitchAndInitalize(uss, newUserId, false, true);
18733    }
18734
18735    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18736            boolean clearInitializing, boolean clearSwitching) {
18737        boolean unfrozen = false;
18738        synchronized (this) {
18739            if (clearInitializing) {
18740                uss.initializing = false;
18741                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18742            }
18743            if (clearSwitching) {
18744                uss.switching = false;
18745            }
18746            if (!uss.switching && !uss.initializing) {
18747                mWindowManager.stopFreezingScreen();
18748                unfrozen = true;
18749            }
18750        }
18751        if (unfrozen) {
18752            final int N = mUserSwitchObservers.beginBroadcast();
18753            for (int i=0; i<N; i++) {
18754                try {
18755                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18756                } catch (RemoteException e) {
18757                }
18758            }
18759            mUserSwitchObservers.finishBroadcast();
18760        }
18761    }
18762
18763    void scheduleStartProfilesLocked() {
18764        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18765            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18766                    DateUtils.SECOND_IN_MILLIS);
18767        }
18768    }
18769
18770    void startProfilesLocked() {
18771        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18772        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18773                mCurrentUserId, false /* enabledOnly */);
18774        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18775        for (UserInfo user : profiles) {
18776            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18777                    && user.id != mCurrentUserId) {
18778                toStart.add(user);
18779            }
18780        }
18781        final int n = toStart.size();
18782        int i = 0;
18783        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18784            startUserInBackground(toStart.get(i).id);
18785        }
18786        if (i < n) {
18787            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18788        }
18789    }
18790
18791    void finishUserBoot(UserStartedState uss) {
18792        synchronized (this) {
18793            if (uss.mState == UserStartedState.STATE_BOOTING
18794                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18795                uss.mState = UserStartedState.STATE_RUNNING;
18796                final int userId = uss.mHandle.getIdentifier();
18797                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18798                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18799                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18800                broadcastIntentLocked(null, null, intent,
18801                        null, null, 0, null, null,
18802                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18803                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18804            }
18805        }
18806    }
18807
18808    void finishUserSwitch(UserStartedState uss) {
18809        synchronized (this) {
18810            finishUserBoot(uss);
18811
18812            startProfilesLocked();
18813
18814            int num = mUserLru.size();
18815            int i = 0;
18816            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18817                Integer oldUserId = mUserLru.get(i);
18818                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18819                if (oldUss == null) {
18820                    // Shouldn't happen, but be sane if it does.
18821                    mUserLru.remove(i);
18822                    num--;
18823                    continue;
18824                }
18825                if (oldUss.mState == UserStartedState.STATE_STOPPING
18826                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18827                    // This user is already stopping, doesn't count.
18828                    num--;
18829                    i++;
18830                    continue;
18831                }
18832                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18833                    // Owner and current can't be stopped, but count as running.
18834                    i++;
18835                    continue;
18836                }
18837                // This is a user to be stopped.
18838                stopUserLocked(oldUserId, null);
18839                num--;
18840                i++;
18841            }
18842        }
18843    }
18844
18845    @Override
18846    public int stopUser(final int userId, final IStopUserCallback callback) {
18847        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18848                != PackageManager.PERMISSION_GRANTED) {
18849            String msg = "Permission Denial: switchUser() from pid="
18850                    + Binder.getCallingPid()
18851                    + ", uid=" + Binder.getCallingUid()
18852                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18853            Slog.w(TAG, msg);
18854            throw new SecurityException(msg);
18855        }
18856        if (userId <= 0) {
18857            throw new IllegalArgumentException("Can't stop primary user " + userId);
18858        }
18859        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18860        synchronized (this) {
18861            return stopUserLocked(userId, callback);
18862        }
18863    }
18864
18865    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18866        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18867        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18868            return ActivityManager.USER_OP_IS_CURRENT;
18869        }
18870
18871        final UserStartedState uss = mStartedUsers.get(userId);
18872        if (uss == null) {
18873            // User is not started, nothing to do...  but we do need to
18874            // callback if requested.
18875            if (callback != null) {
18876                mHandler.post(new Runnable() {
18877                    @Override
18878                    public void run() {
18879                        try {
18880                            callback.userStopped(userId);
18881                        } catch (RemoteException e) {
18882                        }
18883                    }
18884                });
18885            }
18886            return ActivityManager.USER_OP_SUCCESS;
18887        }
18888
18889        if (callback != null) {
18890            uss.mStopCallbacks.add(callback);
18891        }
18892
18893        if (uss.mState != UserStartedState.STATE_STOPPING
18894                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18895            uss.mState = UserStartedState.STATE_STOPPING;
18896            updateStartedUserArrayLocked();
18897
18898            long ident = Binder.clearCallingIdentity();
18899            try {
18900                // We are going to broadcast ACTION_USER_STOPPING and then
18901                // once that is done send a final ACTION_SHUTDOWN and then
18902                // stop the user.
18903                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18904                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18905                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18906                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18907                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18908                // This is the result receiver for the final shutdown broadcast.
18909                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18910                    @Override
18911                    public void performReceive(Intent intent, int resultCode, String data,
18912                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18913                        finishUserStop(uss);
18914                    }
18915                };
18916                // This is the result receiver for the initial stopping broadcast.
18917                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18918                    @Override
18919                    public void performReceive(Intent intent, int resultCode, String data,
18920                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18921                        // On to the next.
18922                        synchronized (ActivityManagerService.this) {
18923                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18924                                // Whoops, we are being started back up.  Abort, abort!
18925                                return;
18926                            }
18927                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18928                        }
18929                        mBatteryStatsService.noteEvent(
18930                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18931                                Integer.toString(userId), userId);
18932                        mSystemServiceManager.stopUser(userId);
18933                        broadcastIntentLocked(null, null, shutdownIntent,
18934                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18935                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18936                    }
18937                };
18938                // Kick things off.
18939                broadcastIntentLocked(null, null, stoppingIntent,
18940                        null, stoppingReceiver, 0, null, null,
18941                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18942                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18943            } finally {
18944                Binder.restoreCallingIdentity(ident);
18945            }
18946        }
18947
18948        return ActivityManager.USER_OP_SUCCESS;
18949    }
18950
18951    void finishUserStop(UserStartedState uss) {
18952        final int userId = uss.mHandle.getIdentifier();
18953        boolean stopped;
18954        ArrayList<IStopUserCallback> callbacks;
18955        synchronized (this) {
18956            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18957            if (mStartedUsers.get(userId) != uss) {
18958                stopped = false;
18959            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18960                stopped = false;
18961            } else {
18962                stopped = true;
18963                // User can no longer run.
18964                mStartedUsers.remove(userId);
18965                mUserLru.remove(Integer.valueOf(userId));
18966                updateStartedUserArrayLocked();
18967
18968                // Clean up all state and processes associated with the user.
18969                // Kill all the processes for the user.
18970                forceStopUserLocked(userId, "finish user");
18971            }
18972
18973            // Explicitly remove the old information in mRecentTasks.
18974            removeRecentTasksForUserLocked(userId);
18975        }
18976
18977        for (int i=0; i<callbacks.size(); i++) {
18978            try {
18979                if (stopped) callbacks.get(i).userStopped(userId);
18980                else callbacks.get(i).userStopAborted(userId);
18981            } catch (RemoteException e) {
18982            }
18983        }
18984
18985        if (stopped) {
18986            mSystemServiceManager.cleanupUser(userId);
18987            synchronized (this) {
18988                mStackSupervisor.removeUserLocked(userId);
18989            }
18990        }
18991    }
18992
18993    @Override
18994    public UserInfo getCurrentUser() {
18995        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18996                != PackageManager.PERMISSION_GRANTED) && (
18997                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18998                != PackageManager.PERMISSION_GRANTED)) {
18999            String msg = "Permission Denial: getCurrentUser() from pid="
19000                    + Binder.getCallingPid()
19001                    + ", uid=" + Binder.getCallingUid()
19002                    + " requires " + INTERACT_ACROSS_USERS;
19003            Slog.w(TAG, msg);
19004            throw new SecurityException(msg);
19005        }
19006        synchronized (this) {
19007            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19008            return getUserManagerLocked().getUserInfo(userId);
19009        }
19010    }
19011
19012    int getCurrentUserIdLocked() {
19013        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19014    }
19015
19016    @Override
19017    public boolean isUserRunning(int userId, boolean orStopped) {
19018        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19019                != PackageManager.PERMISSION_GRANTED) {
19020            String msg = "Permission Denial: isUserRunning() from pid="
19021                    + Binder.getCallingPid()
19022                    + ", uid=" + Binder.getCallingUid()
19023                    + " requires " + INTERACT_ACROSS_USERS;
19024            Slog.w(TAG, msg);
19025            throw new SecurityException(msg);
19026        }
19027        synchronized (this) {
19028            return isUserRunningLocked(userId, orStopped);
19029        }
19030    }
19031
19032    boolean isUserRunningLocked(int userId, boolean orStopped) {
19033        UserStartedState state = mStartedUsers.get(userId);
19034        if (state == null) {
19035            return false;
19036        }
19037        if (orStopped) {
19038            return true;
19039        }
19040        return state.mState != UserStartedState.STATE_STOPPING
19041                && state.mState != UserStartedState.STATE_SHUTDOWN;
19042    }
19043
19044    @Override
19045    public int[] getRunningUserIds() {
19046        if (checkCallingPermission(INTERACT_ACROSS_USERS)
19047                != PackageManager.PERMISSION_GRANTED) {
19048            String msg = "Permission Denial: isUserRunning() from pid="
19049                    + Binder.getCallingPid()
19050                    + ", uid=" + Binder.getCallingUid()
19051                    + " requires " + INTERACT_ACROSS_USERS;
19052            Slog.w(TAG, msg);
19053            throw new SecurityException(msg);
19054        }
19055        synchronized (this) {
19056            return mStartedUserArray;
19057        }
19058    }
19059
19060    private void updateStartedUserArrayLocked() {
19061        int num = 0;
19062        for (int i=0; i<mStartedUsers.size();  i++) {
19063            UserStartedState uss = mStartedUsers.valueAt(i);
19064            // This list does not include stopping users.
19065            if (uss.mState != UserStartedState.STATE_STOPPING
19066                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19067                num++;
19068            }
19069        }
19070        mStartedUserArray = new int[num];
19071        num = 0;
19072        for (int i=0; i<mStartedUsers.size();  i++) {
19073            UserStartedState uss = mStartedUsers.valueAt(i);
19074            if (uss.mState != UserStartedState.STATE_STOPPING
19075                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19076                mStartedUserArray[num] = mStartedUsers.keyAt(i);
19077                num++;
19078            }
19079        }
19080    }
19081
19082    @Override
19083    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19084        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19085                != PackageManager.PERMISSION_GRANTED) {
19086            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19087                    + Binder.getCallingPid()
19088                    + ", uid=" + Binder.getCallingUid()
19089                    + " requires " + INTERACT_ACROSS_USERS_FULL;
19090            Slog.w(TAG, msg);
19091            throw new SecurityException(msg);
19092        }
19093
19094        mUserSwitchObservers.register(observer);
19095    }
19096
19097    @Override
19098    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19099        mUserSwitchObservers.unregister(observer);
19100    }
19101
19102    private boolean userExists(int userId) {
19103        if (userId == 0) {
19104            return true;
19105        }
19106        UserManagerService ums = getUserManagerLocked();
19107        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19108    }
19109
19110    int[] getUsersLocked() {
19111        UserManagerService ums = getUserManagerLocked();
19112        return ums != null ? ums.getUserIds() : new int[] { 0 };
19113    }
19114
19115    UserManagerService getUserManagerLocked() {
19116        if (mUserManager == null) {
19117            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19118            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19119        }
19120        return mUserManager;
19121    }
19122
19123    private int applyUserId(int uid, int userId) {
19124        return UserHandle.getUid(userId, uid);
19125    }
19126
19127    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19128        if (info == null) return null;
19129        ApplicationInfo newInfo = new ApplicationInfo(info);
19130        newInfo.uid = applyUserId(info.uid, userId);
19131        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19132                + info.packageName;
19133        return newInfo;
19134    }
19135
19136    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19137        if (aInfo == null
19138                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19139            return aInfo;
19140        }
19141
19142        ActivityInfo info = new ActivityInfo(aInfo);
19143        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19144        return info;
19145    }
19146
19147    private final class LocalService extends ActivityManagerInternal {
19148        @Override
19149        public void goingToSleep() {
19150            ActivityManagerService.this.goingToSleep();
19151        }
19152
19153        @Override
19154        public void wakingUp() {
19155            ActivityManagerService.this.wakingUp();
19156        }
19157
19158        @Override
19159        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19160                String processName, String abiOverride, int uid, Runnable crashHandler) {
19161            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19162                    processName, abiOverride, uid, crashHandler);
19163        }
19164    }
19165
19166    /**
19167     * An implementation of IAppTask, that allows an app to manage its own tasks via
19168     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19169     * only the process that calls getAppTasks() can call the AppTask methods.
19170     */
19171    class AppTaskImpl extends IAppTask.Stub {
19172        private int mTaskId;
19173        private int mCallingUid;
19174
19175        public AppTaskImpl(int taskId, int callingUid) {
19176            mTaskId = taskId;
19177            mCallingUid = callingUid;
19178        }
19179
19180        private void checkCaller() {
19181            if (mCallingUid != Binder.getCallingUid()) {
19182                throw new SecurityException("Caller " + mCallingUid
19183                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19184            }
19185        }
19186
19187        @Override
19188        public void finishAndRemoveTask() {
19189            checkCaller();
19190
19191            synchronized (ActivityManagerService.this) {
19192                long origId = Binder.clearCallingIdentity();
19193                try {
19194                    if (!removeTaskByIdLocked(mTaskId, false)) {
19195                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19196                    }
19197                } finally {
19198                    Binder.restoreCallingIdentity(origId);
19199                }
19200            }
19201        }
19202
19203        @Override
19204        public ActivityManager.RecentTaskInfo getTaskInfo() {
19205            checkCaller();
19206
19207            synchronized (ActivityManagerService.this) {
19208                long origId = Binder.clearCallingIdentity();
19209                try {
19210                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19211                    if (tr == null) {
19212                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19213                    }
19214                    return createRecentTaskInfoFromTaskRecord(tr);
19215                } finally {
19216                    Binder.restoreCallingIdentity(origId);
19217                }
19218            }
19219        }
19220
19221        @Override
19222        public void moveToFront() {
19223            checkCaller();
19224
19225            final TaskRecord tr;
19226            synchronized (ActivityManagerService.this) {
19227                tr = recentTaskForIdLocked(mTaskId);
19228                if (tr == null) {
19229                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19230                }
19231                if (tr.getRootActivity() != null) {
19232                    moveTaskToFrontLocked(tr.taskId, 0, null);
19233                    return;
19234                }
19235            }
19236
19237            startActivityFromRecentsInner(tr.taskId, null);
19238        }
19239
19240        @Override
19241        public int startActivity(IBinder whoThread, String callingPackage,
19242                Intent intent, String resolvedType, Bundle options) {
19243            checkCaller();
19244
19245            int callingUser = UserHandle.getCallingUserId();
19246            TaskRecord tr;
19247            IApplicationThread appThread;
19248            synchronized (ActivityManagerService.this) {
19249                tr = recentTaskForIdLocked(mTaskId);
19250                if (tr == null) {
19251                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19252                }
19253                appThread = ApplicationThreadNative.asInterface(whoThread);
19254                if (appThread == null) {
19255                    throw new IllegalArgumentException("Bad app thread " + appThread);
19256                }
19257            }
19258            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19259                    resolvedType, null, null, null, null, 0, 0, null, null,
19260                    null, options, callingUser, null, tr);
19261        }
19262
19263        @Override
19264        public void setExcludeFromRecents(boolean exclude) {
19265            checkCaller();
19266
19267            synchronized (ActivityManagerService.this) {
19268                long origId = Binder.clearCallingIdentity();
19269                try {
19270                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19271                    if (tr == null) {
19272                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19273                    }
19274                    Intent intent = tr.getBaseIntent();
19275                    if (exclude) {
19276                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19277                    } else {
19278                        intent.setFlags(intent.getFlags()
19279                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19280                    }
19281                } finally {
19282                    Binder.restoreCallingIdentity(origId);
19283                }
19284            }
19285        }
19286    }
19287}
19288